题解 | #数据串转并电路#

数据串转并电路

http://www.nowcoder.com/practice/6134dc3c8d0741d08eb522542913583d

简析

输入信号:valid_a, data_a
输出信号:ready_a,valid_b,data_b

valid_a信号拉高时,输入有效,并且每接收到6个有效数据才更新一次输出。所以首先设置一个数据移位寄存器data_r。从题目给的波形图可以看出,移位寄存器应是右移的。

reg [5:0] data_r;
always@(posedge clk or negedge rst_n) begin
    if(~rst_n)
       data_r <= 6'b0;
    else
       data_r <= valid_a&&ready_a? {data_a, data_r[5:1]}: data_r;
end

然后设置一个仅在输入数据有效时工作的计数器cnt,用来指示有效数据的个数。

reg [2:0] cnt;
always@(posedge clk or negedge rst_n) begin
    if(~rst_n)
        cnt <= 0;
    else
        cnt <= ~ready_a||~valid_a? cnt:
               cnt     ==       5? 0  :
               cnt+1;
end

当有效数据达到6个时,输出数据有效信号valid_b拉高一个时钟周期。

always@(posedge clk or negedge rst_n) begin
    if(~rst_n)
      valid_b <= 0;
    else
      valid_b <= cnt==5;
end

当有效数据达到6个时,同时更新输出data_r

always@(posedge clk or negedge rst_n) begin
    if(~rst_n)
      	data_r <= 6'b0;
    else
    	data_r <= valid_a&&ready_a? {data_a, data_r[5:1]}: data_r;
end

根据题目要求ready_a始终拉高。

always@(posedge clk or negedge rst_n) begin
    if(~rst_n)
        ready_a <= 0;
    else
        ready_a <= 1;
end

代码

`timescale 1ns/1ns

module s_to_p(
	input 				clk 		,   
	input 				rst_n		,
	input				valid_a		,
	input	 			data_a		,
 
 	output	reg 		ready_a		,
 	output	reg			valid_b		,
	output  reg [5:0] 	data_b
);
    reg [5:0] data_r;
    reg [2:0] cnt;

    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            cnt <= 0;
        else
            cnt <= ~ready_a||~valid_a? cnt:
                   cnt      ==      5? 0  :
                   cnt+1;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            data_r <= 6'b0;
        else
            data_r <= ready_a&&valid_a? {data_a, data_r[5:1]}: data_r;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            data_b <= 6'b0;
        else
            data_b <= cnt==5&&valid_a? {data_a, data_r[5:1]}: data_b;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            valid_b <= 0;
        else
            valid_b <= cnt==5;
    end
    
    always@(posedge clk or negedge rst_n) begin
        if(~rst_n)
            ready_a <= 0;
        else
            ready_a <= 1;
    end
endmodule
Verilog篇题解 文章被收录于专栏

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

全部评论
你这个代码有漏洞。当计数器刚好记到5的时候,valid_a变为0,这个时候在后面几个cycle的并行输出位置的输出会一直变化。虽然没有具体输出出来,但是每一位上的数据都在移位。不完善。建议在输出的时候判断语句要加上valid_a有效。这样才能保证输入有效的数据,同时这个数据会在确定的输出位上。
2 回复 分享
发布于 2022-04-23 10:54
这个代码没有考虑到valid_a不连续的情况,有BUG。
点赞 回复 分享
发布于 2022-04-25 17:00
您好,请问第36行,为什么不考虑【ready_a==1】的情况呢?
点赞 回复 分享
发布于 2023-03-10 17:34 江苏

相关推荐

09-25 10:34
东北大学 Java
多面手的小八想要自然醒:所以读这么多年到头来成为时代车轮底下的一粒尘
点赞 评论 收藏
分享
Yushuu:你的确很厉害,但是有一个小问题:谁问你了?我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了😆
点赞 评论 收藏
分享
11 2 评论
分享
牛客网
牛客企业服务