lin-win-share/DA4008_V1.2/rtl/lvds/ulink_rx.sv

766 lines
30 KiB
Systemverilog
Raw Normal View History

2026-03-13 14:32:42 +08:00
// ============================================================================
// 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