`timescale 1ns / 1ns module add_prefix #( //! if the WIDTH or DATA_LEN parameter is changed, make sure the shift IP inside is also changed parameter WIDTH = 2, parameter DATA_LEN = 256, parameter PREFIX_LEN = 8 ) ( input clk, input start, output reg ready, input [WIDTH-1:0] data_in, output reg data_in_ready, output reg [WIDTH-1:0] data_out, output reg data_out_valid ); localparam CNT_WIDTH = $clog2(DATA_LEN); // ******** Wire & Reg ******** wire [ WIDTH-1:0] shift_out; reg [CNT_WIDTH : 0] cnt_in; reg [ CNT_WIDTH:0] cnt_out; reg [ 2:0] cs = 0; reg [ 2:0] ns = 0; localparam [2:0] S_IDLE = 0; localparam [2:0] S_IN = 1; localparam [2:0] S_OUT = 2; // ******** Assingment ******** // ******** Logic Block ******** always @(posedge clk) begin cs <= ns; end always @(*) begin case (cs) S_IDLE: begin if (start) begin ns = S_IN; end else begin ns = S_IDLE; end end S_IN: begin if (cnt_in == DATA_LEN - PREFIX_LEN - 1) begin ns = S_OUT; end else begin ns = S_IN; end end S_OUT: begin if (cnt_out == DATA_LEN + PREFIX_LEN - 1) begin ns = S_IDLE; end else begin ns = S_OUT; end end default: begin ns = S_IDLE; end endcase end // module ready to receive new packet always @(posedge clk) begin if (cs == S_IDLE && ~start) begin ready <= 1'b1; end else begin ready <= 1'b0; end end // counts the data in always @(posedge clk) begin if (cs == S_IN || cnt_in < DATA_LEN - 1 && cnt_in > 0) begin cnt_in <= cnt_in + 1; end else begin cnt_in <= 0; end end always @(posedge clk) begin if (start) begin data_in_ready <= 1'b1; end else if (cnt_in == DATA_LEN - 1 || cs == S_IDLE) begin data_in_ready <= 1'b0; end end always @(posedge clk) begin if (cs == S_OUT) begin cnt_out <= cnt_out + 1; end else begin cnt_out <= 0; end end always @(posedge clk) begin if (cs == S_OUT) begin if (cnt_out < PREFIX_LEN) begin data_out <= data_in; end else begin data_out <= shift_out; end end else begin data_out <= 0; end end always @(posedge clk) begin if (cs == S_OUT) begin data_out_valid <= 1'b1; end else begin data_out_valid <= 1'b0; end end // ******** Inst ******** shift256_8 u_shift256_8 ( .CLK(clk), // input wire CLK .D (data_in), // input wire [31 : 0] D .Q (shift_out) // output wire [31 : 0] Q ); // ******** Debug ******** endmodule