传送
主要由选通信号strobe,case就可以了,当寄存器中数据大于等于8个字节,就输出一次
module narrow_trans(
input clk,
input rst_n,
input [31 : 0] i_data,
input [3 : 0] i_data_strobe,
output reg [63 : 0] o_data,
output reg o_vld
);
//==============defination
reg [3 : 0] cnt;
//==============combinal logic
//==============sequential logic
always@(posedge clk or negedge rst_n)begin
if(!rst_n) o_data <= 'd0;
else begin
case(i_data_strobe)
4'b0000 : o_data <= o_data;
4'b0001 : o_data <= {o_data, i_data[7 : 0]};
4'b0010 : o_data <= {o_data, i_data[15 : 8]};
4'b0011 : o_data <= {o_data, i_data[15 : 0]};
4'b0100 : o_data <= {o_data, i_data[23 : 16]};
4'b0101 : o_data <= {o_data, i_data[23 : 16], i_data[7 : 0]};
4'b0110 : o_data <= {o_data, i_data[23 : 8]};
4'b0111 : o_data <= {o_data, i_data[23 : 0]};
4'b1000 : o_data <= {o_data, i_data[31 : 24]};
4'b1001 : o_data <= {o_data, i_data[31 : 24], i_data[7 : 0]};
4'b1010 : o_data <= {o_data, i_data[31 : 24], i_data[15 : 8]};
4'b1011 : o_data <= {o_data, i_data[31 : 24], i_data[15 : 0]};
4'b1100 : o_data <= {o_data, i_data[31 : 16]};
4'b1101 : o_data <= {o_data, i_data[31 : 16], i_data[7 : 0]};
4'b1110 : o_data <= {o_data, i_data[31 : 8]};
4'b1111 : o_data <= {o_data, i_data[31 : 0]};
endcase
end
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n) cnt <= 'd0;
else begin
if(cnt >= 8) begin
case(i_data_strobe)
4'b0000 : cnt <= cnt - 'd8;
4'b0001 : cnt <= cnt - 'd8 + 'd1;
4'b0010 : cnt <= cnt - 'd8 + 'd1;
4'b0011 : cnt <= cnt - 'd8 + 'd2;
4'b0100 : cnt <= cnt - 'd8 + 'd1;
4'b0101 : cnt <= cnt - 'd8 + 'd2;
4'b0110 : cnt <= cnt - 'd8 + 'd2;
4'b0111 : cnt <= cnt - 'd8 + 'd3;
4'b1000 : cnt <= cnt - 'd8 + 'd1;
4'b1001 : cnt <= cnt - 'd8 + 'd2;
4'b1010 : cnt <= cnt - 'd8 + 'd2;
4'b1011 : cnt <= cnt - 'd8 + 'd3;
4'b1100 : cnt <= cnt - 'd8 + 'd2;
4'b1101 : cnt <= cnt - 'd8 + 'd3;
4'b1110 : cnt <= cnt - 'd8 + 'd3;
4'b1111 : cnt <= cnt - 'd8 + 'd4;
endcase
end
else begin
case(i_data_strobe)
4'b0000 : cnt <= cnt;
4'b0001 : cnt <= cnt + 'd1;
4'b0010 : cnt <= cnt + 'd1;
4'b0011 : cnt <= cnt + 'd2;
4'b0100 : cnt <= cnt + 'd1;
4'b0101 : cnt <= cnt + 'd2;
4'b0110 : cnt <= cnt + 'd2;
4'b0111 : cnt <= cnt + 'd3;
4'b1000 : cnt <= cnt + 'd1;
4'b1001 : cnt <= cnt + 'd2;
4'b1010 : cnt <= cnt + 'd2;
4'b1011 : cnt <= cnt + 'd3;
4'b1100 : cnt <= cnt + 'd2;
4'b1101 : cnt <= cnt + 'd3;
4'b1110 : cnt <= cnt + 'd3;
4'b1111 : cnt <= cnt + 'd4;
endcase
end
end
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n) o_vld <= 1'b0;
else begin
if(cnt >= 'd8) o_vld <= 1'b1;
else o_vld <= 1'b0;
end
end
endmodule
module tb_narrow_trans();
//===================parameter
parameter PERIOD = 20;
//===================defination
reg clk, rst_n;
reg [31 : 0] i_data;
reg [3 : 0] i_data_strobe;
wire [63 : 0] o_data;
wire o_vld;
//===================logic
initial begin
clk = 0;
rst_n = 0;
#200 rst_n = 1;
#500 $finish;
end
always #(PERIOD / 2) clk = ~clk;
initial begin
@(rst_n);
data_in(32'habcd_1234, 4'b1010);
data_in(32'hef67_3482, 4'b1111);
data_in(32'h6789_3322, 4'b0110);
data_in(32'hef67_3482, 4'b1100);
data_in(32'habcd_1234, 4'b1010);
data_in(32'hef67_3482, 4'b1111);
data_in(32'h6789_3322, 4'b0110);
data_in(32'hef67_3482, 4'b1100);
end
task data_in(input [31 : 0] data, input [3 : 0] strobe);
@(posedge clk);
#1;
i_data = data;
i_data_strobe = strobe;
endtask
narrow_trans u_narrow_trans(
.clk(clk),
.rst_n(rst_n),
.i_data(i_data),
.i_data_strobe(i_data_strobe),
.o_data(o_data),
.o_vld(o_vld)
);
`ifdef FSDB
initial begin
$fsdbDumpfile("narrow_trans.fsdb");
$fsdbDumpvars;
$fsdbDumpMDA();
end
`endif
endmodule