I am trying to build a simple UART reception parser command line based on example from Tang Nano 9K repo here, here is my modified version. It basically uses a memory to hold some values, which is working. Once I receive 5 characters I would like to send them back to host, basically looping through the memory items and sending once tx_data_rdy is set.
module uart_test(
input clk,
input rst_n,
input uart_rx,
output uart_tx,
output reg [5:0] led
);
parameter CLK_FRE = 27; //MHz
parameter UART_FRE = 115200; //bps
localparam IDLE = 0;
localparam SEND = 1;
localparam WAIT = 2;
localparam PROCESS_RX = 3;
parameter MSG_SIZE = 256;
reg[7:0] tx_data;
reg[7:0] tx_str;
reg tx_data_valid;
wire tx_data_ready;
reg[7:0] tx_cnt;
wire[7:0] rx_data;
wire rx_data_valid;
wire rx_data_ready;
reg[31:0] wait_cnt;
reg[3:0] state;
reg [7:0] message [MSG_SIZE - 1:0];
reg [7:0] rx_index;
integer i;
localparam DATA_NUM2 = 3; // just for testing
assign rx_data_ready = 1'b1;//always can receive data,
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
led <= ~6'b100000;
wait_cnt <= 32'd0;
tx_data <= 8'd0;
state <= IDLE;
tx_cnt <= 8'd0;
tx_data_valid <= 1'b0;
rx_index <= 8'd0;
for (i = 0; i < 256; i = i+1) begin
message[i] <= 0;
end
end
else
case(state)
IDLE:
begin
if(rx_data_valid == 1'b1)
begin
message[rx_index] <= rx_data; // send uart received data
if(rx_index >= 8'd4)
begin
rx_index <= 8'd0;
tx_cnt <= 8'd0;
state <= PROCESS_RX;
end
else begin
led <= ~rx_data[5:0];
rx_index <= rx_index + 8'd1;
end
end
end
PROCESS_RX:
begin
tx_data <= tx_str;
tx_data_valid <= 1'b1;
state <= WAIT;
end
WAIT:
begin
if(tx_data_valid == 1'b1 && tx_data_ready == 1'b1) begin
tx_data_valid <= 1'b0;
tx_cnt <= tx_cnt + 8'd1; //Send data counter
if(tx_cnt <= (DATA_NUM2 - 1)) begin
state <= PROCESS_RX;
led <= ~6'b000110;
end
else begin
led <= ~6'b000100;
state <= IDLE;
end
end
end
default:
state <= IDLE;
endcase
end
always@(tx_cnt)
tx_str <= message[tx_cnt];
uart_rx#
(
.CLK_FRE(CLK_FRE),
.BAUD_RATE(UART_FRE)
) uart_rx_inst
(
.clk (clk ),
.rst_n (rst_n ),
.rx_data (rx_data ),
.rx_data_valid (rx_data_valid ),
.rx_data_ready (rx_data_ready ),
.rx_pin (uart_rx )
);
uart_tx#
(
.CLK_FRE(CLK_FRE),
.BAUD_RATE(UART_FRE)
) uart_tx_inst
(
.clk (clk ),
.rst_n (rst_n ),
.tx_data (tx_data ),
.tx_data_valid (tx_data_valid ),
.tx_data_ready (tx_data_ready ),
.tx_pin (uart_tx )
);
endmodule
The Verilog is not able to synthetize as it runs out of SLICEs.
If I just comment the line that increments the index variable used for indexing the memory, i.e. tx_cnt <= tx_cnt + 8'd1;
, then it builds ok.
I have tried different things without success, any Verilog expert probably can quickly see the problem but I am not getting it.
What am I doing wrong?