题解 | #非整数倍数据位宽转换24to128#

非整数倍数据位宽转换24to128

http://www.nowcoder.com/practice/6312169e30a645bba5d832c7313c64cc

简析

输入:valid_in, data_in[23:0]
输出:valid_out,data_out[127:0]
输入数据是24bit,输出数据是128bit。因为128×3=24×16128\times3=24\times16,所以每输入16个有效数据,就可以产生三个完整的输出。因此设置一个仅在输入数据有效时工作的计数器cnt,计数范围是0-15。

    reg [3:0]   cnt;
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            cnt <= 0;
        else
            cnt <= ~valid_in? cnt:
                   cnt==15  ? 0  :
                   cnt+1;
    end

然后设置一个数据暂存器data_lock,每当输入有效时,将数据从低位移入。

reg [127:0] data_lock;
always@(posedge clk or negedge rst_n) begin
    if(~rst_n)
      	data_lock <= 0;
    else
      	data_lock <= valid_in? {data_lock[103:0], data_in}: data_lock;
end

alt

由上图易得,每当计数器cnt计数到5、10、15时,data_out要进行更新,并拉高valid_out一个周期。

    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            valid_out <= 0;
        else
            valid_out <= (cnt==5 || cnt==10 || cnt==15)&&valid_in;
    end
     
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            data_out <= 0;
        else if(cnt==5)
            data_out <= valid_in? {data_lock[119:0], data_in[23:16]}: data_out;
        else if(cnt==10)
            data_out <= valid_in? {data_lock[111:0], data_in[23: 8]}: data_out;
        else if(cnt==15)
            data_out <= valid_in? {data_lock[103:0], data_in[23: 0]}: data_out;
        else
            data_out <= data_out;
    end

代码

`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 [3:0]   cnt;
    reg [127:0] data_lock;
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            cnt <= 0;
        else
            cnt <= ~valid_in? cnt:cnt+1;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            valid_out <= 0;
        else
            valid_out <= (cnt==5 || cnt==10 || cnt==15)&&valid_in;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            data_lock <= 0;
        else
            data_lock <= valid_in? {data_lock[103:0], data_in}: data_lock;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            data_out <= 0;
        else if(cnt==5)
            data_out <= valid_in? {data_lock[119:0], data_in[23:16]}: data_out;
        else if(cnt==10)
            data_out <= valid_in? {data_lock[111:0], data_in[23: 8]}: data_out;
        else if(cnt==15)
            data_out <= valid_in? {data_lock[103:0], data_in[23: 0]}: data_out;
        else
            data_out <= data_out;
    end
endmodule
Verilog篇题解 文章被收录于专栏

本人对牛客网verilog篇题目一些理解

全部评论
写的很好,但是我觉得对于cnt的计数存在问题:当完成一轮的24bit*16的转换后,应该手动将cnt置0,否则下一轮计算若由cnt+1的进位,将会导致计数第一个数据到来时cnt为0,导致计数错误。
2 回复 分享
发布于 2022-09-01 09:30 湖北
输入位宽是24哥
点赞 回复 分享
发布于 2022-06-09 11:59
很精彩
点赞 回复 分享
发布于 2022-08-02 02:33
这题确实没想到
点赞 回复 分享
发布于 2022-11-21 05:31 德国
请问这一题和后面的8to12有什么区别?
点赞 回复 分享
发布于 2022-12-01 15:41 陕西
always@(posedge clk or negedge rst_n) begin if(~rst_n) valid_out <= 0; else valid_out <= (cnt==5 || cnt==10 || cnt==15)&&valid_in; end 为啥【您提交的代码无法完成编译 main.v:26: syntax error main.v:28: Syntax in assignment statement l-value. main.v:29: syntax error main.v:30: Syntax in assignment statement l-value. 】我不理解
点赞 回复 分享
发布于 2023-02-12 11:12 江苏
cnt <= (valid_in==1'b1 && cnt != 4'd15) ? cnt + 1 : (cnt==4'd15 ? 0 : cnt);这样写对不?满15的时候手动置0还是1
点赞 回复 分享
发布于 2023-03-03 21:47 江西
为什么后面8to12我这样做结果不对
点赞 回复 分享
发布于 2023-03-07 20:09 江苏
data——lock更新明显不对!
点赞 回复 分享
发布于 2023-05-17 13:31 江苏
个人愚见还是手动将cnt置零比较好,虽然阁下的代码也能通过
点赞 回复 分享
发布于 2023-05-31 10:36 江苏
如果计数是从0-15,那么复位后cnt=0,第一个数据到来后就变为了1(但理应为0),用1-16是不是更准确
点赞 回复 分享
发布于 2023-08-29 22:30 广东

相关推荐

09-04 21:05
已编辑
西南科技大学 Java
点赞 评论 收藏
分享
72 6 评论
分享
牛客网
牛客企业服务