题解 | #非整数倍数据位宽转换24to128#
非整数倍数据位宽转换24to128
https://www.nowcoder.com/practice/6312169e30a645bba5d832c7313c64cc
`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 ,
output reg [127:0] data_reg
// output reg [3:0] cnt
);
//==============================================
// 这道题,注意:
// 1) 非整数倍的位宽转换,要防止非整数倍的那一个数据丢数据位置。
// 因此,应当采用更大位宽的数组将需要获取的数据全部都缓存,然后再根据需要输出。
// 2) 寻找非整数倍的位宽要求,对于输入数据位宽,在拼接操作出现循环状态时候,所需要的拼接次数。
// 根据输入的特点,多个24bit的数据转换为128bit的数据,
// 假设有一个位宽很大的数据buffer存放输入的24bit数据,则每轮存储情况如下:
// ① 24×5+8,新输入6个24bit,余最后一个数据的后16bit,输出 buf[143:16]
// ② 算上上次余下的16bit,16+24×4+16,新输入5个24bit,余下最后一数据的后8bit,输出 buf[135:8]
// ③ 同理,8+5×24,新输入5个24bit,余下0bit,输出[127:0]
// ④ 上一轮数据无剩余bit,也就是buf清空,状态和 ① 一样。
// ......................
// 综上所述,也就是说,经过三轮的输出,24bit的拼接状态会出现循环。
// 统计以上三轮的输入,一共是输入了 6+5+5=16 个24bit数据,由此可以以16次输入为一轮,计数0-15,这个刚好可以用4bit的寄存器,循环覆盖计数
//==============================================
reg [3:0] cnt;
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
cnt <= 4'd0;
else
cnt <= valid_in? cnt+1'd1 : cnt;
end
// width: 16×24=384
// buffer
reg [383:0] data_buf;
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
data_buf <= 384'h0;
else
data_buf <= valid_in? {data_buf[359:0], data_in} : data_buf;
end
// valid_out
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
valid_out <= 1'b0;
else begin
if(cnt==4'd5 || cnt==4'd10 || cnt==4'd15)
valid_out <= 1'b1;
else
valid_out <= 1'b0;
end
end
// data_out
always @(*)
begin
if(~rst_n)
data_out = 'h0;
else begin
if(cnt==4'd6)
data_out = data_buf[143:16];
else if(cnt==4'd11)
data_out = data_buf[135:8];
else if(cnt==4'd0)
data_out = data_buf[127:0];
else
data_out = data_out;
end
end
endmodule
testbench
`timescale 1ns/1ns
module tb;
reg clk;
reg rst_n;
reg [23:0] data_in;
reg valid_in;
wire valid_out;
wire [127:0] data_out;
wire [3:0] cnt;
// wire [127:0] data_reg;
wire [383:0] q;
always#5 clk = ~clk;
initial begin
clk = 1'b1;
rst_n = 1'b0;
data_in = 'b0;
valid_in = 1'b0;
#10;
rst_n = 1'b1;
#20;
valid_in = 1'b1;
data_in = 24'ha0a1a2;
#10;
data_in = 24'hb2b1b0;
#10;
data_in = 24'hc2c1c0;
#10;
data_in = 24'hd2d1d0;
#10;
data_in = 24'he2e1e0;
#10;
data_in = 24'hf2f1f0;
#10;
valid_in = 1'b1;
#40;
valid_in = 1'b1;
#10;
data_in = 24'ha2a1a0;
#10;
data_in = 24'hb2b1b0;
#10;
data_in = 24'hc2c1c0;
#10;
data_in = 24'hd2d1d0;
#10;
data_in = 24'he2e1e0;
#40;
$finish();
end
width_24to128 ins (
.clk (clk),
.rst_n (rst_n),
.valid_in (valid_in),
.data_in (data_in),
.valid_out (valid_out),
.data_out (data_out),
// .data_reg (data_reg),
.cnt (cnt),
.q (q)
);
endmodule
查看12道真题和解析
深信服公司福利 732人发布
