非整数倍的低bit数据转成高bit数据
对于非整数倍数据转换,我们需要保证完整的数据不能被丢失,下面举一个例子
24bit转换成128bit
首先要保证把24bit完整的保存到几个128bit中,24bit和128bit的公倍数为384

由图中可以看出,16个24bit数据与三个128bit长度相同。
为了解决这个过程中的data_out的输出问题,我们考虑采用一个【127:0】寄存器来帮助它实现
这个工过程中一定要记住!r_tmp寄存器的延时要比输入延后一个周期,也就是说在cnt == 5的时候,寄存器中的数据存储的前5个周期输入的数据以及8位的空白数据。
此处的详细过程可在仿真的时候在r_tmp寄存器的移位变化过程显示出来。
`timescale 1ns/1ns
module width_24to128(
input clk ,
input rst_n ,
input valid_in ,
input [23:0] data_in ,
output reg valid_out ,
output reg [127:0] data_out
);
reg [4:0] r_cnt;
reg [127:0] r_tmp;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
r_cnt <= 'd0;
else if(r_cnt == 4'd15)
r_cnt <= 'd0;
else if(valid_in)
r_cnt <= r_cnt + 'd1;
end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
valid_out <= 'd0;
else if(r_cnt == 5 || r_cnt == 10 || r_cnt == 15)
valid_out <= 'd1;
else
valid_out <= 'd0;
end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
r_tmp <= 'd0;
else if(valid_in)
r_tmp <= {r_tmp[127:0],data_in};
else
r_tmp <= r_tmp;
end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
data_out <= 'd0;
else begin
case (r_cnt)
5'd5: data_out <= {r_tmp[119:0], data_in};
5'd10 : data_out <= {r_tmp[111:0],data_in[23:8]};
5'd15 : data_out <= {r_tmp[103:0],data_in[23:0]};
default: data_out <= 'd0;
endcase
end
end
endmodule
TB文件
`timescale 1ns/1ns
module tb_width_24to128();
// 时钟和复位信号
reg clk;
reg rst_n;
// 输入激励信号
reg valid_in;
reg [23:0] data_in;
// 输出信号
wire valid_out;
wire [127:0] data_out;
// 时钟生成(100MHz)
always #5 clk = ~clk;
// 实例化被测模块
width_24to128 dut (
.clk(clk),
.rst_n(rst_n),
.valid_in(valid_in),
.data_in(data_in),
.valid_out(valid_out),
.data_out(data_out)
);
// 复位控制和激励生成
initial begin
// 初始信号置零
clk = 0;
rst_n = 0;
valid_in = 0;
data_in = 24'h0;
// 释放复位信号
#20 rst_n = 1;
// 生成连续16组输入数据(覆盖3次完整输出)
repeat(16) begin
@(posedge clk);
valid_in = 1;
data_in = $random; // 随机24bit数据
#1; // 保持建立时间
end
// 停止输入
@(posedge clk);
valid_in = 0;
// 延长仿真时间观察波形
#200 $finish;
end
endmodule
波形

浙公网安备 33010602011771号