always @(posedge clk)
case(state)
RDY: begin
bitIndex <= 1'b0;
timer <= 14'b0;
txBit <= 1'b1;
if(send == 1'b1) begin
txData <= {1'b1, data, 1'b0};
state <= LOAD_BIT;
end
end
LOAD_BIT: begin
if(timer == baud_timer) begin
timer <= 14'b0;
state <= SEND_BIT;
txBit <= txData[bitIndex];
bitIndex <= bitIndex + 1'b1;
end else timer <= timer + 1'b1;
end
SEND_BIT: begin
if(bitIndex == bit_index_max) state <= RDY;
else state <= LOAD_BIT;
end
default: state <= RDY;
endcase
localparam PRESS = 2'b00, EXTEND = 2'b01, RLS = 2'b10, CHECK = 2'b11;
reg [1:0] state = PRESS;
reg [23:0] received;
wire [7:0] data;
reg [7:0] ledreg = 0;
wire ready;
reg ready_prev;
USB_keyboard kb1(.ps2data(PS2Data), .ps2clk(PS2Clk), .data(data),
.ready(ready));
UART_tx_ctrl #(19200) uart(.clk(clk), .send(uartSend), .data(uartData),
.uart_tx(RsTx), .ready(uartRdy));
always @ (posedge clk) begin
ready_prev <= ready;
case(state)
PRESS:
if (ready_prev == 0 && ready == 1) begin
received[23:16] <= data;
state <= EXTEND;
end
EXTEND:
if (ready_prev == 0 && ready == 1) begin
received[15:8] <= data;
state <= RLS;
end
RLS:
if (received[15:8] != 8'hF0) state <= EXTEND;
else if (ready_prev == 0 && ready == 1) begin
received[7:0] <= data;
state <= CHECK;
end
CHECK:
begin
uartState <= 1'b0;
case(received[7:0])
8'h16: ledreg[0] <= ~ledreg[0];
8'h1E: ledreg[1] <= ~ledreg[1];
8'h26: ledreg[2] <= ~ledreg[2];
8'h25: ledreg[3] <= ~ledreg[3];
8'h2E: ledreg[4] <= ~ledreg[4];
8'h36: ledreg[5] <= ~ledreg[5];
8'h3D: ledreg[6] <= ~ledreg[6];
8'h3E: ledreg[7] <= ~ledreg[7];
endcase
state <= PRESS;
end
endcase
end
assign led = {received[7:0], ledreg};
assign uartSend = {state == CHECK};
endmodule
This ended up working fine as soon as I switched my keyboard. The demo
can be seen below.
Part 2)
I then added my module for tx to the serial monitor and switched the
ledreg values of the check statement to simply set the UART data to the
corresponding ASCII code for the number. Other than some slight
modifications this way pretty much copy and paste from one of the
previous homeworks.
always @(posedge clk)
case(state)
RDY: begin
bitIndex <= 1'b0;
timer <= 14'b0;
txBit <= 1'b1;
if(send == 1'b1) begin
txData <= {1'b1, data, 1'b0};
state <= LOAD_BIT;
end
end
LOAD_BIT: begin
if(timer == baud_timer) begin
timer <= 14'b0;
state <= SEND_BIT;
txBit <= txData[bitIndex];
bitIndex <= bitIndex + 1'b1;
end else timer <= timer + 1'b1;
end
SEND_BIT: begin
if(bitIndex == bit_index_max) state <= RDY;
else state <= LOAD_BIT;
end
default: state <= RDY;
endcase
localparam PRESS = 2'b00, EXTEND = 2'b01, RLS = 2'b10, CHECK = 2'b11;
reg [1:0] state = PRESS;
reg [23:0] received;
wire [7:0] data;
reg [7:0] ledreg = 0;
wire ready;
reg ready_prev;
USB_keyboard kb1(.ps2data(PS2Data), .ps2clk(PS2Clk), .data(data),
.ready(ready));
UART_tx_ctrl #(19200) uart(.clk(clk), .send(uartSend), .data(uartData),
.uart_tx(RsTx), .ready(uartRdy));
always @ (posedge clk) begin
ready_prev <= ready;
case(state)
PRESS:
if (ready_prev == 0 && ready == 1) begin
received[23:16] <= data;
state <= EXTEND;
end
EXTEND:
if (ready_prev == 0 && ready == 1) begin
received[15:8] <= data;
state <= RLS;
end
RLS:
if (received[15:8] != 8'hF0) state <= EXTEND;
else if (ready_prev == 0 && ready == 1) begin
received[7:0] <= data;
state <= CHECK;
end
CHECK:
begin
uartState <= 1'b0;
case(received[7:0])
8'h16: uartData <= 49;
8'h1E: uartData <= 50;
8'h26: uartData <= 51;
8'h25: uartData <= 52;
8'h2E: uartData <= 53;
8'h36: uartData <= 54;
8'h3D: uartData <= 55;
8'h3E: uartData <= 56;
endcase
state <= PRESS;
end
endcase
end
assign led = {received[7:0], ledreg};
assign uartSend = {state == CHECK};
endmodule
Discussion: Easy
peasy. I have a programmable RGB mechanical keyboard which caused the
busy light on the board to flash very fast and the LEDs to not light
up. When I switched to a cheaper membrane keyboard everything worked
fine. Very odd but kind of makes sense if the keyboard is trying to
send unwanted data.