Thank you for the tips! :) I reworked it a little and removed the always * block, and moved it into a single process, as you suggested. And now it works as expected :D
module rs232_send
(
input wire SYSCLK, // 50MHz
input wire RST_B, // reset switch, active low
output reg UART_TX
);
reg COUNTER;
wire SER_CLK;
reg TX_STATE;
reg LETTER;
wire ENABLE;
initial
begin
COUNTER <= 0;
TX_STATE <= 0;
LETTER <= 7'h21; // start with '!' character
UART_TX <= 1;
end
assign SER_CLK = (COUNTER == 16'd5208); // 50MHz / 5208 = 9600
assign ENABLE = (LETTER != 7'h7e);
always *AT* (posedge SYSCLK)
begin
if(!RST_B)
begin
COUNTER <= 0;
TX_STATE <= 4'hA;
LETTER <= 7'h21;
UART_TX <= 1;
end
else
begin
if(!ENABLE)
UART_TX <= 1;
else if(SER_CLK)
begin
COUNTER <= 0;
case(TX_STATE)
4'd0: UART_TX <= 0; // start bit
4'd1: UART_TX <= LETTER; // first nibble
4'd2: UART_TX <= LETTER;
4'd3: UART_TX <= LETTER;
4'd4: UART_TX <= LETTER;
4'd5: UART_TX <= LETTER; // second nibble start
4'd6: UART_TX <= LETTER;
4'd7: UART_TX <= LETTER;
4'd8: UART_TX <= 0;
4'd9: UART_TX <= 1; // stop bit
default: UART_TX <= 1; // idle
endcase
if(TX_STATE == 4'd9)
begin
TX_STATE <= 4'h0;
if(LETTER == 7'h7e)
LETTER <= 7'h21;
else
LETTER <= LETTER + 7'h1;
end
else
begin
TX_STATE <= TX_STATE + 4'h1;
end
end
else
COUNTER <= COUNTER + 16'h1;
end
end
endmodule
If there's anything else that's bad about this code, I would be very grateful to hear it.
Thanks again,