From 8d9016d41f8fd79047822bc23c76ea79ccbb8bec Mon Sep 17 00:00:00 2001 From: Thomas Leyk Date: Thu, 27 Sep 2018 13:45:44 +0200 Subject: [PATCH 1/2] Adapted osd_event_packetization for module specific TYPE_SUB --- .../common/osd_event_packetization.sv | 22 ++++++++++++++----- .../osd_event_packetization_fixedwidth.sv | 4 ++++ ...test_osd_event_packetization_fixedwidth.py | 1 + 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/blocks/eventpacket/common/osd_event_packetization.sv b/blocks/eventpacket/common/osd_event_packetization.sv index 02a4b36..414bea4 100644 --- a/blocks/eventpacket/common/osd_event_packetization.sv +++ b/blocks/eventpacket/common/osd_event_packetization.sv @@ -55,7 +55,10 @@ module osd_event_packetization #( input [15:0] dest, // Generate an overflow packet input overflow, - + + // Module specific sub-type (TYPE_SUB) + input [2:0] mod_type_sub, + // a new event is available input event_available, // the packet has been sent @@ -105,8 +108,9 @@ module osd_event_packetization #( assign data_req_idx = word_cnt; assign data_req_valid = (state == PAYLOAD || state == OVERFLOW); - localparam TYPE_SUB_LAST = 4'h0; - localparam TYPE_SUB_CONTINUE = 4'h1; + localparam TYPE_SUB_LAST = 1'b0; + localparam TYPE_SUB_CONTINUE = 1'b1; + localparam TYPE_SUB_OVERFLOW = 4'h5; always_ff @(posedge clk) begin @@ -157,7 +161,15 @@ module osd_event_packetization #( debug_out.data[15:14] = 2'b10; // TYPE == EVENT // TYPE_SUB - if (overflow) begin + debug_out.data[13:11] = mod_type_sub[2:0]; + + if (pkg_cnt == num_pkgs - 1) begin + debug_out.data[10] = TYPE_SUB_LAST; + end else begin + debug_out.data[10] = TYPE_SUB_CONTINUE; + end + + /*if (overflow) begin debug_out.data[13:10] = TYPE_SUB_OVERFLOW; end else begin if (pkg_cnt == num_pkgs - 1) begin @@ -165,7 +177,7 @@ module osd_event_packetization #( end else begin debug_out.data[13:10] = TYPE_SUB_CONTINUE; end - end + end*/ debug_out.data[9:0] = 10'h0; // reserved debug_out.valid = 1; diff --git a/blocks/eventpacket/common/osd_event_packetization_fixedwidth.sv b/blocks/eventpacket/common/osd_event_packetization_fixedwidth.sv index 75f0f11..b983875 100644 --- a/blocks/eventpacket/common/osd_event_packetization_fixedwidth.sv +++ b/blocks/eventpacket/common/osd_event_packetization_fixedwidth.sv @@ -56,6 +56,9 @@ module osd_event_packetization_fixedwidth #( input [15:0] dest, // Generate an overflow packet input overflow, + + // Module specific sub-type (TYPE_SUB) + input [2:0] mod_type_sub, // a new event is available input event_available, @@ -100,6 +103,7 @@ module osd_event_packetization_fixedwidth #( .id(id), .dest(dest), .overflow(overflow), + .mod_type_sub(mod_type_sub), .event_available(event_available), .event_consumed(event_consumed), diff --git a/blocks/eventpacket/test/test_osd_event_packetization_fixedwidth.py b/blocks/eventpacket/test/test_osd_event_packetization_fixedwidth.py index 89d8b2f..9b2e714 100644 --- a/blocks/eventpacket/test/test_osd_event_packetization_fixedwidth.py +++ b/blocks/eventpacket/test/test_osd_event_packetization_fixedwidth.py @@ -57,6 +57,7 @@ def test_fixedwidth(dut): data_int = int.from_bytes(data_bytes, byteorder='little', signed=False) dut.data.value = BinaryValue(data_int) + dut.mod_type_sub <= 0 dut.overflow <= 0 dut.event_available <= 1 From 4eaafae9eba067a1f03d1045a3a5850171c4eb47 Mon Sep 17 00:00:00 2001 From: Thomas Leyk Date: Fri, 12 Oct 2018 11:34:14 +0200 Subject: [PATCH 2/2] DEM-UART: Initial implementation for FIFOs --- .../dem_uart/common/fifo_singleclock_fwft.sv | 116 ++++++ .../common/fifo_singleclock_standard.sv | 111 ++++++ modules/dem_uart/common/osd_dem_uart.sv | 350 +++++++++++++++++- 3 files changed, 576 insertions(+), 1 deletion(-) create mode 100644 modules/dem_uart/common/fifo_singleclock_fwft.sv create mode 100644 modules/dem_uart/common/fifo_singleclock_standard.sv diff --git a/modules/dem_uart/common/fifo_singleclock_fwft.sv b/modules/dem_uart/common/fifo_singleclock_fwft.sv new file mode 100644 index 0000000..03b64ae --- /dev/null +++ b/modules/dem_uart/common/fifo_singleclock_fwft.sv @@ -0,0 +1,116 @@ +/* Copyright (c) 2017 by the author(s) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * ============================================================================= + * + * Synchronous First-Word Fall-Through (FWFT) FIFO + * + * This FIFO implementation wraps the FIFO with standard read characteristics + * to have first-word fall-through read characteristics. + * + * Author(s): + * Philipp Wagner + */ + +module fifo_singleclock_fwft #( + parameter WIDTH = 8, + parameter DEPTH = 32, + parameter PROG_FULL = (DEPTH / 2) +)( + input clk, + input rst, + + input [(WIDTH-1):0] din, + input wr_en, + output full, + output prog_full, + + output reg [(WIDTH-1):0] dout, + input rd_en, + output empty, + + output [$clog2(DEPTH)-1:0] count +); + + reg fifo_valid, middle_valid, dout_valid; + reg [(WIDTH-1):0] middle_dout; + + wire [(WIDTH-1):0] fifo_dout; + wire fifo_empty, fifo_rd_en; + wire will_update_middle, will_update_dout; + + // synchronous FIFO with standard (non-FWFT) read characteristics + fifo_singleclock_standard + #(.WIDTH(WIDTH), + .DEPTH(DEPTH), + .PROG_FULL(PROG_FULL)) + u_fifo ( + .rst(rst), + .clk(clk), + .rd_en(fifo_rd_en), + .dout(fifo_dout), + .empty(fifo_empty), + .wr_en(wr_en), + .din(din), + .full(full), + .prog_full(prog_full), + .count(count) + ); + + // create FWFT FIFO out of non-FWFT FIFO + // public domain code from Eli Billauer + // see http://www.billauer.co.il/reg_fifo.html + assign will_update_middle = fifo_valid && (middle_valid == will_update_dout); + assign will_update_dout = (middle_valid || fifo_valid) && (rd_en || !dout_valid); + assign fifo_rd_en = (!fifo_empty) && !(middle_valid && dout_valid && fifo_valid); + assign empty = !dout_valid; + + always_ff @(posedge clk) begin + if (rst) begin + fifo_valid <= 0; + middle_valid <= 0; + dout_valid <= 0; + dout <= 0; + middle_dout <= 0; + end else begin + if (will_update_middle) + middle_dout <= fifo_dout; + + if (will_update_dout) + dout <= middle_valid ? middle_dout : fifo_dout; + + if (fifo_rd_en) + fifo_valid <= 1; + else if (will_update_middle || will_update_dout) + fifo_valid <= 0; + + if (will_update_middle) + middle_valid <= 1; + else if (will_update_dout) + middle_valid <= 0; + + if (will_update_dout) + dout_valid <= 1; + else if (rd_en) + dout_valid <= 0; + end + end + +endmodule diff --git a/modules/dem_uart/common/fifo_singleclock_standard.sv b/modules/dem_uart/common/fifo_singleclock_standard.sv new file mode 100644 index 0000000..7160c87 --- /dev/null +++ b/modules/dem_uart/common/fifo_singleclock_standard.sv @@ -0,0 +1,111 @@ +/* Copyright (c) 2017 by the author(s) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * ============================================================================= + * + * Synchronous Standard FIFO (one clock) + * + * The memory block in this FIFO is following the "RAM HDL Coding Guidelines" + * of Xilinx (UG901) to enable placing the FIFO memory into block ram during + * synthesis. + * + * Author(s): + * Philipp Wagner + */ + +module fifo_singleclock_standard #( + parameter WIDTH = 8, + parameter DEPTH = 32, + parameter PROG_FULL = DEPTH / 2 +)( + input clk, + input rst, + + input [(WIDTH-1):0] din, + input wr_en, + output full, + output prog_full, + + output reg [(WIDTH-1):0] dout, + input rd_en, + output empty, + + output [$clog2(DEPTH) - 1:0] count +); + localparam AW = $clog2(DEPTH); + + // ensure that parameters are set to allowed values + initial begin + if ((1 << $clog2(DEPTH)) != DEPTH) begin + $fatal("fifo_singleclock_standard: the DEPTH must be a power of two."); + end + end + + reg [AW-1:0] wr_addr; + reg [AW-1:0] rd_addr; + wire fifo_read; + wire fifo_write; + reg [AW-1:0] rd_count; + + // generate control signals + assign empty = (rd_count[AW-1:0] == 0); + assign prog_full = (rd_count[AW-1:0] >= PROG_FULL); + assign full = (rd_count[AW-1:0] == (DEPTH-1)); + assign fifo_read = rd_en & ~empty; + assign fifo_write = wr_en & ~full; + assign count = rd_count; + + // address logic + always_ff @(posedge clk) begin + if (rst) begin + wr_addr[AW-1:0] <= 'd0; + rd_addr[AW-1:0] <= 'b0; + rd_count[AW-1:0] <= 'b0; + end else begin + if (fifo_write & fifo_read) begin + wr_addr[AW-1:0] <= wr_addr[AW-1:0] + 'd1; + rd_addr[AW-1:0] <= rd_addr[AW-1:0] + 'd1; + end else if (fifo_write) begin + wr_addr[AW-1:0] <= wr_addr[AW-1:0] + 'd1; + rd_count[AW-1:0]<= rd_count[AW-1:0] + 'd1; + end else if (fifo_read) begin + rd_addr[AW-1:0] <= rd_addr[AW-1:0] + 'd1; + rd_count[AW-1:0]<= rd_count[AW-1:0] - 'd1; + end + end + end + + // generic dual-port, single clock memory + reg [WIDTH-1:0] ram [DEPTH-1:0]; + + // write + always_ff @(posedge clk) begin + if (fifo_write) begin + ram[wr_addr] <= din; + end + end + + // read + always_ff @(posedge clk) begin + if (fifo_read) begin + dout <= ram[rd_addr]; + end + end +endmodule diff --git a/modules/dem_uart/common/osd_dem_uart.sv b/modules/dem_uart/common/osd_dem_uart.sv index 5ebc15e..2b92767 100644 --- a/modules/dem_uart/common/osd_dem_uart.sv +++ b/modules/dem_uart/common/osd_dem_uart.sv @@ -14,6 +14,34 @@ // Authors: // Stefan Wallentowitz +/* NOTE: This is a WiP! + * + * A couple of important points about the current state of the FIFO + * implementation. + * + * 1. The ordering of any data musn't ever change. No data may be lost. + * + * 2. We have to be able to receive 2 chars (16-bit) in a single cycle to + * avoid unnecessary stalling of the DI. + * + * 3. The bus side is only capable of sending/receiving one char (8-bit) at a time. + * + * -> We therefore need a buffering mechanism to convert between 8-bit & 16-bit width + * + * 4. If the osd_event_packetization module is used to create outgoing + * DI packets, we have to know exactly how many chars (8-bit) we want + * to send when event_available is asserted. + * + * 5. If some sort of out_char_bypass is used to buffer outgoing chars (8-bit) + * before they enter they FIFO or get sent over the DI, access to it must be synchronized. + * + * As of my current knowledge, it seems the best way to address all these issues would be to + * make use of 2 8-bit Buffer for each direction (4 in total). Whenever only a single char is received, + * the MSB-LSB ordering of the 2 8-bit buffers is swapped, so that any follow up data won't leave an + * 8-bit gap in the buffer (like a 16-bit buffer would do). The new type of FIFO could be packaged into + * a new module nicely, see the comment below for more. + **/ + import dii_package::dii_flit; module osd_dem_uart @@ -70,8 +98,328 @@ module osd_dem_uart .reg_err (1'b0), .reg_rdata (16'h0)); + // --------------------------------------------------------------- + logic [2:0] mod_type_sub; + logic event_available; + logic event_consumed; + reg [3:0] data_num_words; + logic data_reg_idx; + logic data_reg_valid; + logic [15:0] data; + + osd_event_packetization + #(.MAX_PKT_LEN(1), .MAX_DATA_NUM_WORDS(16)) + u_event_packetization(.clk(clk), .rst(rst), + .debug_out(c_uart_out), + .debug_out_ready(c_uart_out_ready), + .id(id), + .dest(event_dest), + .overflow(1'b0), + .mod_type_sub(mod_type_sub), + .event_available(event_available), + .event_consumed(event_consumed), + .data_num_words(data_num_words), + .data_reg_idx(data_reg_idx), + .data_reg_valid(data_reg_valid), + .data(data)); + +/* The entire tx/rx FIFO-logic could/should be a new module 'osd_dem_uart_fifo' + * that wraps 2 (or 4) fwft-FIFO and allows for 8 or 16 bit reads/writes. + * Internally the module should take care of swapping MSB & LSB whenever + * only 8 bit are written/read. The interface to the outside would be almost + * identical to a standard FIFO, except for a read_single_char & write_single_char + * input flag. + **/ + +// ------------------------ TX LOGIC --------------------------------- + logic tx_fifo0_din; + logic tx_fifo0_wr_en; + logic tx_fifo0_full; + logic tx_fifo0_dout; + logic tx_fifo0_rd_en; + logic tx_fifo0_empty; + logic tx_fifo0_count; + logic tx_fifo1_din; + logic tx_fifo1_wr_en; + logic tx_fifo1_full; + logic tx_fifo1_dout; + logic tx_fifo1_rd_en; + logic tx_fifo1_empty; + logic tx_fifo1_count; + + fifo_singleclock_fwft + #(.WIDTH(16), .DEPTH(16)) + u_tx_fifo0(.clk(clk), .rst(rst), + .din(tx_fifo0_din), + .wr_en(tx_fifo0_wr_en), + .full(tx_fifo0_full), + .prog_full(), + .dout(tx_fifo0_dout), + .rd_en(tx_fifo0_rd_en), + .empty(tx_fifo0_empty), + .count(tx_fifo0_count)); + + fifo_singleclock_fwft + #(.WIDTH(16), .DEPTH(16)) + u_tx_fifo1(.clk(clk), .rst(rst), + .din(tx_fifo1_din), + .wr_en(tx_fifo1_wr_en), + .full(tx_fifo1_full), + .prog_full(), + .dout(tx_fifo1_dout), + .rd_en(tx_fifo1_rd_en), + .empty(tx_fifo1_empty), + .count(tx_fifo1_count)); + + // 0 = fifo0, 1 = fifo1 + logic tx_fifo_select, nxt_tx_fifo_select; + logic tx_fifo_select1, nxt_tx_fifo_select1; + + enum {STATE_IDLE, STATE_DELAY, STATE_XFER} + tx_state, nxt_tx_state; + + always @(posedge clk) begin + if (rst) begin + tx_fifo_select <= 1'b0; + tx_fifo_select <= 1'b0; + tx_state <= STATE_IDLE; + end else begin + tx_fifo_select <= nxt_tx_fifo_select; + tx_fifo_select1 <= nxt_tx_fifo_select1; + tx_state <= nxt_tx_state; + end + end + + reg tx_delay_couter; + reg last; + + always_comb begin + tx_fifo0_din = 8'h0; + tx_fifo0_wr_en = 1'b0; + tx_fifo1_din = 8'h0; + tx_fifo1_wr_en = 1'b0; + out_ready = 1'b0; + + if (tx_fifo_select) begin + tx_fifo0_din = out_char; + tx_fifo0_wr_en = out_valid; + out_ready = !tx_fifo0_full; + if (out_valid & out_ready) begin + nxt_tx_fifo_select = 1'b0; + end + end else begin + tx_fifo1_din = out_char; + tx_fifo1_wr_en = out_valid; + out_ready = !tx_fifo1_full; + if (out_valid & out_ready) begin + nxt_tx_fifo_select = 1'b1; + end + end + + case (tx_state) + STATE_IDLE: + if (!tx_fifo01_empty) begin + nxt_tx_state = STATE_DELAY; + end + end + STATE_DELAY: + // TODO: Magic numbers + if (tx_delay_couter > 20 | tx_fifo01_count > 8) begin + event_available = 1'b1; + nxt_tx_state = STATE_XFER; + data_num_words = (tx_fifo0_count + tx_fifo1_count) / 2; + mod_type_sub = {(tx_fifo0_count == tx_fifo1_count), 2'b00}; + end else begin + tx_delay_couter = tx_delay_couter + 1; + end + end + STATE_XFER: + if (data_reg_valid) begin + // TODO: Properly send data_num_words chars using the osd_event_packetization module. + // XXX: Current data_word_idx + nxt + // XXX: We need a tx_fifo_select1 + end + + if (event_consumed) begin + nxt_tx_state = STATE_IDLE; + end + end + endcase + end +// ------------------------- TX LOGIC END ------------------------- + + +// ------------------------- RX LOGIC ----------------------------- + logic rx_fifo0_din; + logic rx_fifo0_wr_en; + logic rx_fifo0_full; + logic rx_fifo0_dout; + logic rx_fifo0_rd_en; + logic rx_fifo0_empty; + logic rx_fifo0_count; + logic rx_fifo1_din; + logic rx_fifo1_wr_en; + logic rx_fifo1_full; + logic rx_fifo1_dout; + logic rx_fifo1_rd_en; + logic rx_fifo1_empty; + logic rx_fifo1_count; + + fifo_singleclock_fwft + #(.WIDTH(16), .DEPTH(16)) + u_rx_fifo0(.clk(clk), .rst(rst), + .din(rx_fifo0_din), + .wr_en(rx_fifo0_wr_en), + .full(rx_fifo0_full), + .prog_full(), + .dout(rx_fifo0_dout), + .rd_en(rx_fifo0_rd_en), + .empty(rx_fifo0_empty), + .count(rx_fifo0_count)); + + fifo_singleclock_fwft + #(.WIDTH(16), .DEPTH(16)) + u_rx_fifo1(.clk(clk), .rst(rst), + .din(rx_fifo1_din), + .wr_en(rx_fifo1_wr_en), + .full(rx_fifo1_full), + .prog_full(), + .dout(rx_fifo1_dout), + .rd_en(rx_fifo1_rd_en), + .empty(rx_fifo1_empty), + .count(rx_fifo1_count)); + + logic rx_fifo_select, nxt_rx_fifo_select; + logic rx_fifo_select1, nxt_rx_fifo_select1; + + enum { STATE_IDLE, STATE_HDR_SRC, STATE_HDR_FLAGS, + STATE_XFER } rx_state, nxt_rx_state; + + always @(posedge clk) begin + if (rst) begin + rx_fifo_select <= 1'b0; + rx_fifo_select1 <= 1'b0; + rx_state <= STATE_IDLE; + end else begin + rx_fifo_select <= nxt_rx_fifo_select; + rx_fifo_select1 <= nxt_rx_fifo_select1; + rx_state <= nxt_rx_state; + end + end + + reg is_single_char; + + always_comb begin + in_char = 8'h0; + in_valid = 1'b0; + + if (rx_fifo_select) begin + in_char = rx_fifo0_dout; + in_valid = !rx_fifo0_empty; + rx_fifo0_rd_en = in_ready; + if (in_valid & in_ready) begin + nxt_rx_fifo_select = 1'b0; + end + end else begin + in_char = rx_fifo1_dout; + in_valid = !rx_fifo1_empty; + rx_fifo1_rd_en = in_ready; + if (in_valid & in_ready) begin + nxt_rx_fifo_select = 1'b01; + end + end + + c_uart_in_ready = 0; + nxt_rx_fifo_select = 1'b0; + rx_fifo0_wr_en = 1'b0; + rx_fifo0_din = 8'h0; + rx_fifo1_wr_en = 1'b0; + rx_fifo1_din = 8'h0; + + case (rx_state) + STATE_IDLE: begin + c_uart_in_ready = 1; + if (c_uart_in.valid) begin + nxt_rx_state = STATE_HDR_SRC; + end + end + STATE_HDR_SRC: begin + c_uart_in_ready = 1; + if (c_uart_in.valid) begin + nxt_rx_state = STATE_HDR_FLAGS; + end + end + STATE_HDR_FLAGS: begin + c_uart_in_ready = 1; + is_single_char = c_uart_in.data[12]; // XXX: Choose correct bit + if (c_uart_in.valid) begin + nxt_rx_state = STATE_XFER; + end + end + STATE_XFER: begin + // XXX: Simplify this block + if (c_uart_in.last) begin + if (is_single_char) begin + if (rx_fifo_select1) begin + c_uart_in_ready = !rx_fifo1_full; + + rx_fifo1_wr_en = c_uart_in.valid; + rx_fifo1_din = c_uart_in.data[7:0]; + nxt_rx_fifo_select1 = 1'b0; + end else begin + c_uart_in_ready = !rx_fifo0_full; + + rx_fifo0_wr_en = c_uart_in.valid; + rx_fifo0_din = c_uart_in.data[7:0]; + nxt_rx_fifo_select1 = 1'b1; + end + end else begin + if (rx_fifo_select1) begin + c_uart_in_ready = !rx_fifo0_full & !rx_fifo1_full; + + rx_fifo0_wr_en = c_uart_in.valid; + rx_fifo0_din = c_uart_in.data[15:8]; + rx_fifo1_wr_en = c_uart_in.valid; + rx_fifo1_din = c_uart_in.data[7:0]; + end else begin + c_uart_in_ready = !rx_fifo0_full & !rx_fifo1_full; + + rx_fifo0_wr_en = c_uart_in.valid; + rx_fifo0_din = c_uart_in.data[7:0]; + rx_fifo1_wr_en = c_uart_in.valid; + rx_fifo1_din = c_uart_in.data[15:8]; + end + end + end else begin + if (rx_fifo_select1) begin + c_uart_in_ready = !rx_fifo0_full & !rx_fifo1_full; + + rx_fifo0_wr_en = c_uart_in.valid; + rx_fifo0_din = c_uart_in.data[15:8]; + rx_fifo1_wr_en = c_uart_in.valid; + rx_fifo1_din = c_uart_in.data[7:0]; + end else begin + c_uart_in_ready = !rx_fifo0_full & !rx_fifo1_full; + + rx_fifo0_wr_en = c_uart_in.valid; + rx_fifo0_din = c_uart_in.data[7:0]; + rx_fifo1_wr_en = c_uart_in.valid; + rx_fifo1_din = c_uart_in.data[15:8]; + end + end + + if (c_uart_in.valid && c_uart_in.last) begin + nxt_rx_state = STATE_IDLE; + end + end + endcase + end +// ------------------------ RX LOGIC END --------------------------- + +// ---------------------- OLD CODE --------------------------------- +// The previous implementation without any FIFOs or the osd_event_packetization module. enum { STATE_IDLE, STATE_HDR_DEST, STATE_HDR_SRC, STATE_HDR_FLAGS, - STATE_XFER } state_tx, state_rx; + STATE_XFER } state_rx; always @(posedge clk) begin if (rst) begin