// ============================================================================ // Top Module: ulink_rx // Integrates training, descrambling, and frame reception, outputs 512-bit block writes to SRAM // ============================================================================ module ulink_rx #( parameter FIFO_DEPTH = 64, // Input FIFO depth parameter [31:0] SCRAMBLER_SEED = 32'hFFFFFFFF // Fixed seed for descrambler (all lanes share) )( input logic clk ,input logic rst_n // Active-low reset // 4-lane serial input ,input logic [3 :0] serial_in // Training parameters ,input logic [19 :0] patn_count ,input logic [2 :0] tap_step ,input logic [2 :0] tap_adj_mask // Delay adjustment mask ,input logic [0 :0] tap_force // Delay force to tap_step ,input logic force_train ,input logic descram_en ,input logic always_on ,input logic prefilling ,output logic prefill_start // Link status outputs ,output logic link_down ,output logic train_ready ,output logic [2 :0] delay_tap ,output logic tap_adj_req // SRAM write interface (each block is 512 bits) ,output logic [12 :0] wr_addr ,output logic [511:0] wr_data ,output logic wr_en ,output logic [63 :0] byte_mask // CRC error indication (can be used for external monitoring or to restart training) ,output logic crc_error ,output logic frame_done ,output logic [31 :0] train_status ,output logic [31 :0] frame_status ); // Internal connection signals //logic train_ready; // Training ready (not used, but can be exported) logic data_valid; // Data valid pulse from training module logic [127:0] data_int; // 128-bit data from training module logic [127:0] descrambled_data; // Descrambled data logic descrambled_valid; // Descrambled data valid logic [0 :0] train_en; // Training enable logic [3 :0] descram_valid; // ======================================================================== // prefill module instantiation // ======================================================================== prefill #( .DELAY ( 20'd10000 ) ) U_prefill ( .clk ( clk ) ,.rst_n ( rst_n ) ,.always_on ( always_on ) ,.prefilling ( prefilling ) ,.prefill_start ( prefill_start ) ,.prefill_done ( train_en ) ); // ======================================================================== // Training module instantiation // ======================================================================== ulink_rx_train u_train ( .clk ( clk ) ,.rst_n ( rst_n ) ,.serial_in ( serial_in ) ,.patn_count ( patn_count ) ,.frame_error ( crc_error ) // Frame error feedback to restart training ,.frame_done ( frame_done ) ,.tap_step ( tap_step ) ,.tap_adj_mask ( tap_adj_mask ) ,.tap_force ( tap_force ) ,.force_train ( force_train ) ,.train_en ( train_en ) ,.link_down ( link_down ) ,.delay_tap ( delay_tap ) ,.tap_adj_req ( tap_adj_req ) ,.train_ready ( train_ready ) ,.descram_valid ( descram_valid ) ,.data_valid ( data_valid ) ,.data_out ( data_int ) ,.train_status ( train_status ) ); // ======================================================================== // Descrambler module instantiation (128-bit, all lanes share the same seed) // ======================================================================== ulink_descrambler_128 #( .SEED ( SCRAMBLER_SEED ) ) u_descrambler ( .clk ( clk ) ,.rst_n ( rst_n ) ,.data_in ( data_int ) ,.valid_in ( descram_valid ) ,.enable ( descram_en ) // Always enable descrambling ,.data_out ( descrambled_data ) ,.valid_out ( descrambled_valid ) ); // ======================================================================== // Frame receiver module instantiation // ======================================================================== ulink_frame_receiver #( .FIFO_DEPTH ( FIFO_DEPTH ) ) u_frame ( .clk ( clk ) ,.rst_n ( rst_n ) ,.data_in ( descrambled_data ) ,.valid_in ( descrambled_valid ) ,.wr_addr ( wr_addr ) ,.wr_data ( wr_data ) ,.wr_en ( wr_en ) ,.byte_mask ( byte_mask ) ,.crc_error ( crc_error ) ,.frame_done ( frame_done ) ,.frame_status ( frame_status ) ); endmodule // ============================================================================ // Sub-module definitions (can be placed in separate files as needed) // ============================================================================ // ---------------------------------------------------------------------------- // 32-bit Descrambler (used inside the 128-bit descrambler) // ---------------------------------------------------------------------------- module ulink_descrambler_32 #( parameter [31:0] SEED = 32'hFFFFFFFF ) ( input logic clk ,input logic rst_n ,input logic [31:0] data_in ,input logic valid_in ,input logic enable ,output logic [31:0] data_out ,output logic valid_out ); logic [31:0] lfsr, next_lfsr; wire feedback = lfsr[31] ^ lfsr[30] ^ lfsr[29] ^ lfsr[28]; assign next_lfsr = {lfsr[30:0], feedback}; always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) lfsr <= SEED; else if (valid_in && enable) lfsr <= next_lfsr; end logic [31:0] descrambled; assign descrambled = valid_in && enable ? (data_in ^ lfsr) : data_in; always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) begin data_out <= 32'h0; valid_out <= 1'b0; end else begin data_out <= descrambled; valid_out <= valid_in; end end endmodule // ---------------------------------------------------------------------------- // 128-bit Descrambler (composed of four 32-bit descramblers) // ---------------------------------------------------------------------------- module ulink_descrambler_128 #( parameter [31:0] SEED = 32'hFFFFFFFF ) ( input logic clk ,input logic rst_n ,input logic [127:0] data_in ,input logic [3 :0] valid_in ,input logic enable ,output logic [127:0] data_out ,output logic valid_out ); logic [31:0] lane0_out, lane1_out, lane2_out, lane3_out; logic valid_out0, valid_out1, valid_out2, valid_out3; ulink_descrambler_32 #(.SEED(SEED)) u0 ( .clk (clk), .rst_n (rst_n), .data_in (data_in[31:0]), .valid_in (valid_in[0]), .enable (enable), .data_out (lane0_out), .valid_out(valid_out0) ); ulink_descrambler_32 #(.SEED(SEED)) u1 ( .clk (clk), .rst_n (rst_n), .data_in (data_in[63:32]), .valid_in (valid_in[1]), .enable (enable), .data_out (lane1_out), .valid_out(valid_out1) ); ulink_descrambler_32 #(.SEED(SEED)) u2 ( .clk (clk), .rst_n (rst_n), .data_in (data_in[95:64]), .valid_in (valid_in[2]), .enable (enable), .data_out (lane2_out), .valid_out(valid_out2) ); ulink_descrambler_32 #(.SEED(SEED)) u3 ( .clk (clk), .rst_n (rst_n), .data_in (data_in[127:96]), .valid_in (valid_in[3]), .enable (enable), .data_out (lane3_out), .valid_out(valid_out3) ); assign data_out = {lane3_out, lane2_out, lane1_out, lane0_out}; assign valid_out = valid_out1; // All lanes are synchronized endmodule // ---------------------------------------------------------------------------- // CRC32 Module (used in frame receiver) // ---------------------------------------------------------------------------- module crc32 #( parameter POLY = 32'h04C11DB7 ,parameter INIT = 32'hFFFFFFFF )( input logic clk ,input logic rst_n ,input logic clear ,input logic [31:0] data ,input logic valid ,output logic [31:0] crc ); logic [31:0] crc_reg, crc_next; integer i; logic data_bit; always_ff @(posedge clk or negedge rst_n) begin if (!rst_n) crc_reg <= INIT; else if (clear) crc_reg <= INIT; else if (valid) crc_reg <= crc_next; end always_comb begin crc_next = crc_reg; for (i = 0; i < 32; i++) begin data_bit = crc_next[31] ^ data[31-i]; crc_next = {crc_next[30:0], 1'b0}; if (data_bit) crc_next = crc_next ^ POLY; end end assign crc = crc_reg; endmodule // ---------------------------------------------------------------------------- // Frame Receiver Module (uses syn_fwft_fifo) // ---------------------------------------------------------------------------- module ulink_frame_receiver #( parameter FIFO_DEPTH = 64 )( input logic clk ,input logic rst_n ,input logic [127:0] data_in ,input logic valid_in ,output logic [12:0] wr_addr ,output logic [511:0] wr_data ,output logic wr_en ,output logic [63:0] byte_mask ,output logic [31:0] frame_status ,output logic crc_error ,output logic frame_done ); // Frame header constant localparam FRAME_HEADER = 32'hBCBCBCBC; // FIFO instantiation logic fifo_rd_en; logic [127:0] fifo_dout; logic fifo_empty; //syn_fwft_fifo syn_fwft_fifo #( .width ( 128 ) ,.depth ( FIFO_DEPTH ) ) u_fifo ( .clk ( clk ) ,.rst ( ~rst_n ) ,.clr ( 1'b0 ) ,.wr_en ( valid_in ) ,.din ( data_in ) ,.full ( ) ,.almost_full ( ) ,.prog_full ( ) ,.rd_en (fifo_rd_en ) ,.dout (fifo_dout ) ,.empty (fifo_empty ) ,.almost_empty ( ) ,.prog_empty ( ) ,.cnt ( ) ); // Split 128-bit data into four 32-bit words typedef enum logic [2:0] { S_IDLE, S_WORD0, S_WORD1, S_WORD2, S_WORD3 } word_state_t; word_state_t word_state_c, word_state_n; // ------------------------------------------------------ // -- word state machine // ------------------------------------------------------ //jump conditions wire idle2word0 = (word_state_c == S_IDLE ) && !fifo_empty; wire word02word1 = (word_state_c == S_WORD0 ) ; wire word12word2 = (word_state_c == S_WORD1 ) ; wire word22word3 = (word_state_c == S_WORD2 ) ; wire word32idle = (word_state_c == S_WORD3 ) ; //state_n assign word_state_n = ((word_state_c == S_IDLE ) && idle2word0 ) ? S_WORD0 : ((word_state_c == S_WORD0 ) && word02word1 ) ? S_WORD1 : ((word_state_c == S_WORD1 ) && word12word2 ) ? S_WORD2 : ((word_state_c == S_WORD2 ) && word22word3 ) ? S_WORD3 : ((word_state_c == S_WORD3 ) && word32idle ) ? S_IDLE : word_state_c ; //word_state_c sirv_gnrl_edffr #(.T(word_state_t)) word_state_c_dffr (word_state_n,word_state_c,clk, rst_n); //fifo_rd_en assign fifo_rd_en = idle2word0; wire [127:0] current_fifo_data; sirv_gnrl_dfflr #(128) current_fifo_data_dfflr (fifo_rd_en, fifo_dout, current_fifo_data, clk, rst_n); wire [31:0] current_word_w = (word_state_c == S_WORD0) ? current_fifo_data[31:0] : (word_state_c == S_WORD1) ? current_fifo_data[63:32] : (word_state_c == S_WORD2) ? current_fifo_data[95:64] : (word_state_c == S_WORD3) ? current_fifo_data[127:96] : 32'h0; wire word_valid_w = (word_state_c != S_IDLE); wire [31:0] current_word; sirv_gnrl_dfflr #(32) current_word_dfflr (word_valid_w, current_word_w, current_word, clk, rst_n); wire word_valid; sirv_gnrl_dffr #(1) word_valid_dffr (word_valid_w, word_valid, clk, rst_n); // ------------------------------------------------------ // -- Frame parsing FSM // ------------------------------------------------------ typedef enum logic [2:0] { ST_IDLE, ST_HEAD, ST_DATA, ST_CRC } state_t; state_t state_c, state_n; //data_len wire [15:0] data_len; sirv_gnrl_dfflr #(16) data_len_dfflr ((state_c == ST_HEAD ), current_word[15:0], data_len, clk, rst_n); //data_cnt contrl wire [15:0] data_cnt; wire add_data_cnt = (state_c == ST_DATA ) && word_valid; wire end_data_cnt = add_data_cnt && (state_c == ST_DATA ) && (data_cnt == data_len -1); wire [15:0] data_cnt_n = end_data_cnt ? 5'h0 : add_data_cnt ? data_cnt + 1'b1 : data_cnt ; sirv_gnrl_dffr #(16) data_cnt_dffr (data_cnt_n, data_cnt, clk, rst_n); //jump conditions wire idle2head = (state_c == ST_IDLE ) && (word_valid && current_word == FRAME_HEADER); wire head2data = (state_c == ST_HEAD ) && word_valid; wire data2crc = (state_c == ST_DATA ) && end_data_cnt; wire crc2idle = (state_c == ST_CRC ) && word_valid; //state_n assign state_n = ((state_c == ST_IDLE ) && idle2head ) ? ST_HEAD : ((state_c == ST_HEAD ) && head2data ) ? ST_DATA : ((state_c == ST_DATA ) && data2crc ) ? ST_CRC : ((state_c == ST_CRC ) && crc2idle ) ? ST_IDLE : state_c ; //state_c sirv_gnrl_edffr #(.T(state_t)) state_c_dffr (state_n,state_c,clk, rst_n); //cur_block_offset wire [3:0] cur_block_offset; wire add_cur_block_offset = (state_c == ST_DATA ) && word_valid; wire end_cur_block_offset = (state_c == ST_DATA ) && add_cur_block_offset && (cur_block_offset == 16-1);; wire [3:0] cur_block_offset_n = end_cur_block_offset ? 5'h0 : (state_c == ST_HEAD ) ? current_word[19:16] : add_cur_block_offset ? cur_block_offset + 1'b1 : cur_block_offset ; sirv_gnrl_dffr #(4) cur_block_offset_dffr (cur_block_offset_n, cur_block_offset, clk, rst_n); //block_done wire block_done; sirv_gnrl_dffr #(1) block_done_dffr ((state_c == ST_DATA) && ((end_data_cnt && !end_cur_block_offset) || end_cur_block_offset), block_done, clk, rst_n); //base_addr wire [15:0] base_addr; sirv_gnrl_dfflr #(16) base_addr_dfflr ((state_c == ST_HEAD ), current_word[31:16], base_addr, clk, rst_n); //cur_block_addr wire [12:0] cur_block_addr; wire [12:0] cur_block_addr_w = end_cur_block_offset ? cur_block_addr + 1'b1 : (state_c == ST_HEAD) ? current_word[31:16] >> 4 : crc2idle ? 13'd0 : cur_block_addr; sirv_gnrl_dffr #(13) cur_block_addr_dffr (cur_block_addr_w, cur_block_addr, clk, rst_n); //cur_block_data wire [31:0] cur_block_data [15:0]; genvar i; generate for (i = 0; i < 16; i++) begin : gen_block_data wire load_sel = (state_c == ST_DATA) && (cur_block_offset == i); sirv_gnrl_dfflr #(32) cur_block_data_dfflr (load_sel, current_word, cur_block_data[i], clk, rst_n); end endgenerate //cur_block_mask wire [63:0] cur_block_mask; wire clear_mask = (state_c == ST_HEAD) || block_done; genvar j; generate for (j = 0; j < 16; j++) begin : gen_mask wire load_sel_mask = (state_c == ST_DATA) && (cur_block_offset == j); wire load_en = load_sel_mask || clear_mask; wire [3:0] dnxt = load_sel_mask ? 4'b1111 : clear_mask ? 4'b0000 : 4'b1111; sirv_gnrl_dfflr #(4) cur_block_mask_dfflr (load_en, dnxt, cur_block_mask[j*4 +: 4], clk, rst_n); end endgenerate //SRAM Write Ouput Contrl //wr_addr wire [12:0] cur_block_addr_r; sirv_gnrl_dffr #(13) cur_block_addr_r_dffr (cur_block_addr, cur_block_addr_r, clk, rst_n); sirv_gnrl_dfflr #(13) wr_addr_dfflr (block_done, cur_block_addr_r, wr_addr, clk, rst_n); //wr_data wire [511:0] cur_block_data_packed; genvar k; generate for (k = 0; k < 16; k++) begin : pack_cur_block_data assign cur_block_data_packed[32*k +: 32] = cur_block_data[k]; end endgenerate sirv_gnrl_dfflr #(512) wr_data_dfflr (block_done, cur_block_data_packed, wr_data, clk, rst_n); //byte_mask sirv_gnrl_dfflr #(64) byte_mask_dfflr (block_done, cur_block_mask, byte_mask, clk, rst_n); //wr_en sirv_gnrl_dffr #(1) wr_en_dffr (block_done, wr_en, clk, rst_n); //frame_done sirv_gnrl_dffr #(1) frame_done_dffr (crc2idle, frame_done, clk, rst_n); // ------------------------------------------------------ // -- CRC32 instance // ------------------------------------------------------ wire crc_clear, crc_valid; wire [31:0] crc_out; crc32 u_crc32 ( .clk ( clk ) ,.rst_n ( rst_n ) ,.clear ( crc_clear ) ,.data ( current_word ) ,.valid ( crc_valid ) ,.crc ( crc_out ) ); //CRC Contrl //crc_clear sirv_gnrl_dffr #(1) crc_clear_dffr (crc2idle, crc_clear, clk, rst_n); //crc_valid //sirv_gnrl_dffr #(1) crc_valid_dffr ((state_c == ST_HEAD) || (state_c == ST_DATA) && word_valid, crc_valid, clk, rst_n); assign crc_valid = (state_c == ST_HEAD) || (state_c == ST_DATA) && word_valid; //crc_error sirv_gnrl_dffr #(1) crc_error_dffr (crc2idle && (current_word != crc_out), crc_error, clk, rst_n); wire [31:0] frame_status_w; assign frame_status_w[2 : 0] = state_c; assign frame_status_w[15: 3] = base_addr[15:3]; assign frame_status_w[31:16] = data_len; sirv_gnrl_dffr #(32) frame_status_dffr (frame_status_w, frame_status, clk, rst_n); endmodule // ---------------------------------------------------------------------------- // Training module (provided in user's file, placeholder here) // Note: To avoid duplication, the definition of ulink_rx_train is omitted. // In actual use, include the original file content here or via `include. // ---------------------------------------------------------------------------- // Assume ulink_rx_train module exists, identical to the user-provided code. module ulink_rx_train ( input logic clk ,input logic rst_n ,input logic [3 :0] serial_in // 4-lane serial input ,input logic [19 :0] patn_count // Training count preset value ,input logic frame_error // Frame error indication (from frame module) ,input logic frame_done // Frame done indication (from frame module) ,input logic [2 :0] tap_step // Delay adjustment step value ,input logic [2 :0] tap_adj_mask // Delay adjustment mask ,input logic [0 :0] tap_force // Delay force to tap_step ,input logic force_train // Force Training ,input logic [0 :0] train_en // Training enable ,output logic link_down // Link down indication ,output logic [2 :0] delay_tap // Delay adjustment value ,output logic tap_adj_req ,output logic train_ready // Training complete, link ready ,output logic [127:0] data_out // Latched parallel data ,output logic data_valid ,output logic [3 :0] descram_valid ,output logic [31 :0] train_status ); // 4 32-bit shift registers, corresponding to 4 input lanes wire [31:0] lane0_reg, lane1_reg, lane2_reg, lane3_reg; sirv_gnrl_dffr #(32) lane0_reg_dffr ({lane0_reg[30:0], serial_in[0]}, lane0_reg, clk, rst_n); sirv_gnrl_dffr #(32) lane1_reg_dffr ({lane1_reg[30:0], serial_in[1]}, lane1_reg, clk, rst_n); sirv_gnrl_dffr #(32) lane2_reg_dffr ({lane2_reg[30:0], serial_in[2]}, lane2_reg, clk, rst_n); sirv_gnrl_dffr #(32) lane3_reg_dffr ({lane3_reg[30:0], serial_in[3]}, lane3_reg, clk, rst_n); // State definition typedef enum logic [1:0] { SM_DOWN, // Link down SM_MATCH, // Match training pattern SM_EXIT, // Wait for exit pattern SM_READY // Link ready } state_t; state_t state_c, state_n; localparam TRAINING_PATN = 32'h68666E6C; // "hfnl" localparam TRAINING_EXIT = 32'h65786974; // "exit" // Bit counter control wire [4:0] bit_counter; wire add_bit_conuter = ((state_c == SM_MATCH) || (state_c == SM_EXIT)); wire end_bit_conuter = add_bit_conuter && (bit_counter == 32-1); wire [4:0] counter_m1 = end_bit_conuter ? 5'h0 : add_bit_conuter ? bit_counter + 1'b1 : bit_counter ; sirv_gnrl_dffr #(5) bit_counter_dffr (counter_m1, bit_counter, clk, rst_n); // Combinational signals: all four lanes match simultaneously wire match_en = (lane0_reg == TRAINING_PATN) && (lane1_reg == TRAINING_PATN) && (lane2_reg == TRAINING_PATN) && (lane3_reg == TRAINING_PATN); wire match_exit = (lane0_reg == TRAINING_EXIT) && (lane1_reg == TRAINING_EXIT) && (lane2_reg == TRAINING_EXIT) && (lane3_reg == TRAINING_EXIT); wire match_failed = !(match_en | match_exit) & end_bit_conuter; // Match counter wire [19:0] match_counter_c; wire add_match_counter = (state_c == SM_MATCH) && end_bit_conuter; wire end_match_counter = add_match_counter && (match_counter_c == patn_count-2); wire [19:0] match_counter_n = end_match_counter ? 20'h0 : add_match_counter ? match_counter_c + 1'b1 : match_counter_c ; sirv_gnrl_dffr #(20) match_counter_c_dffr (match_counter_n, match_counter_c, clk, rst_n); // ------------------------------------------------------ // -- state machine // ------------------------------------------------------ //jump conditions wire down2match = (state_c == SM_DOWN ) && match_en && train_en; wire match2down = (state_c == SM_MATCH ) && match_failed; wire match2exit = (state_c == SM_MATCH ) && end_match_counter; wire exit2down = (state_c == SM_EXIT ) && match_failed; wire exit2ready = (state_c == SM_EXIT ) && match_exit; wire ready2down = (state_c == SM_READY ) && frame_error; //state_n assign state_n = ((state_c == SM_DOWN ) && down2match ) ? SM_MATCH : ((state_c == SM_MATCH ) && (match2down || force_train )) ? SM_DOWN : ((state_c == SM_MATCH ) && match2exit ) ? SM_EXIT : ((state_c == SM_EXIT ) && (exit2down || force_train )) ? SM_DOWN : ((state_c == SM_EXIT ) && exit2ready ) ? SM_READY : ((state_c == SM_READY ) && (ready2down || force_train )) ? SM_DOWN : state_c ; //state_c sirv_gnrl_edffr #(.T(state_t)) state_c_dffr (state_n,state_c,clk, rst_n); // Delay adjustment (step controlled by tap_step) wire tap_adj_req_w = (tap_adj_mask[0] && match2down) || (tap_adj_mask[1] && exit2down ) || (tap_adj_mask[2] && ready2down) ; wire tap_adj_enable = tap_adj_req_w || tap_force; wire [2:0] delay_tap_w = tap_force ? tap_step : delay_tap + tap_step ; sirv_gnrl_dfflr #(3) delay_tap_dfflr (tap_adj_enable, delay_tap_w, delay_tap, clk, rst_n); sirv_gnrl_dffr #(1) tap_adj_req_dffr (tap_adj_req_w, tap_adj_req, clk, rst_n); // Link status outputs sirv_gnrl_dffr #(1) link_down_dffr ((state_c == SM_DOWN), link_down, clk, rst_n); sirv_gnrl_dffr #(1) train_ready_dffr ((state_c == SM_READY), train_ready, clk, rst_n); // ====================== // Data output // ====================== wire [127:0] data_buf; sirv_gnrl_dffr #(128) data_buf_dffr ({lane3_reg, lane2_reg, lane1_reg, lane0_reg}, data_buf, clk, rst_n); // Frame header constant localparam FRAME_HEADER = 32'hBCBCBCBC; // ============================================================================================================== // Data input control: In SM_READY state, latch data every 32 cycles and generate a valid pulse // ============================================================================================================== //match_head wire match_head_start; wire match_head = (data_buf[31:0] == FRAME_HEADER); wire match_head_start_w = match_head && train_ready ? 1'b1 : link_down ? 1'b0 : frame_done ? 1'b0 : match_head_start; sirv_gnrl_dffr #(1) match_head_start_dffr (match_head_start_w, match_head_start, clk, rst_n); // data counter control wire [4:0] data_counter; wire add_data_conuter = match_head_start; wire end_data_conuter = (add_data_conuter && (data_counter == 32-1) || frame_done); wire [4:0] data_counter_n = end_data_conuter ? 5'h0 : add_data_conuter ? data_counter + 1'b1 : data_counter ; sirv_gnrl_dffr #(5) data_counter_dffr (data_counter_n, data_counter, clk, rst_n); //valid_int wire data_valid_w = (state_c == SM_READY) && (match_head || (end_data_conuter && (data_counter == 32-1))); sirv_gnrl_dffr #(1) valid_int_dffr (data_valid_w, data_valid, clk, rst_n); //descram_valid wire [3:0] descram_valid_w; assign descram_valid_w[3:1] = {3{data_valid_w}}; assign descram_valid_w[0] = (state_c == SM_READY) && (end_data_conuter && (data_counter == 32-1)); sirv_gnrl_dffr #(4) descram_valid_dffr (descram_valid_w, descram_valid, clk, rst_n); //data_in reg wire data_in_reg; sirv_gnrl_dffr #(128) data_in_reg_dffr (data_buf, data_out, clk, rst_n); //train_status wire [31:0] train_status_w; assign train_status_w[1 : 0] = state_c; assign train_status_w[2 ] = match_en; assign train_status_w[3 ] = match_exit; assign train_status_w[4 ] = match_failed; assign train_status_w[5 ] = match_head; assign train_status_w[6 ] = match_head_start; assign train_status_w[11: 7] = bit_counter; assign train_status_w[31:12] = match_counter_c; sirv_gnrl_dffr #(32) train_status_dffr (train_status_w, train_status, clk, rst_n); endmodule // ---------------------------------------------------------------------------- // prefill Module (used in frame receiver) // ---------------------------------------------------------------------------- module prefill #( parameter DELAY = 20'd10000 )( input logic clk ,input logic rst_n ,input logic always_on ,input logic prefilling ,output logic prefill_start ,output logic prefill_done ); // delay counter control wire [19:0] delay_counter; wire add_delay_counter = ~(delay_counter == DELAY); wire end_delay_counter = add_delay_counter && (delay_counter == DELAY-1); wire [19:0] delay_counter_n = end_delay_counter ? 20'h0 : add_delay_counter ? delay_counter + 1'b1 : delay_counter ; sirv_gnrl_dffr #(20) delay_counter_dffr (delay_counter_n, delay_counter, clk, rst_n); //prefill_start sirv_gnrl_dffr #(1) prefill_start_dffr (end_delay_counter, prefill_start, clk, rst_n); //prefilling_falling wire [1:0] prefilling_r; sirv_gnrl_dffr #(2) prefilling_r_dffr ({prefilling_r[0],prefilling}, prefilling_r, clk, rst_n); wire prefilling_falling = !prefilling_r[0] && prefilling_r[1]; //prefill_done sirv_gnrl_dfflr #(1) prefill_done_dfflr (prefilling_falling || always_on, 1'b1, prefill_done, clk, rst_n); endmodule