题解 | #整数倍数据位宽转换8to16#

整数倍数据位宽转换8to16

https://www.nowcoder.com/practice/f1fb03cb0baf46ada2969806114bce5e

思路

本道题思路很简单。

在valid_in为1的情况下,得到第一个数据放在data_out的高8位,得到第二个数据放在data_out的低8位。

但是仔细观察波形图发现,valid_in为0后并没有把data_out之前装载的数据清空,而是下一次valid_in为1时继续使用。

data_out装载完成后,让valid_out为1,并输出data_out。

重复以上步骤!由此可以找一个标志的符号flag,若flag为0,则data_in的数据装载到data_out的高位;若flag为1,则data_in的数据装载到data_out的低位。每次装载完数据就让flag=flag+1,这样flag就能在0和1之间来回变换。

代码

`timescale 1ns/1ns

module width_8to16(
	input 				   clk 		,   
	input 				   rst_n		,
	input				      valid_in	,
	input	   [7:0]		   data_in	,
 
 	output	reg			valid_out,
	output   reg [15:0]	data_out
);
	reg flag=1'b0;//flag为0把data_in放在data_out_tmp高8位,为1放低位
	reg [15:0]data_out_tmp;
	always @(posedge clk or posedge rst_n) begin
		if (!rst_n)begin
			data_out_tmp<=0;
			data_out<=0;
			flag<=0;
			valid_out<=0;
		end
		else begin
			if (valid_in)begin
				if (flag==0)begin
					data_out_tmp[15:8]<=data_in;
					flag=flag+1;
                    valid_out<=0;
				end
				else begin
					data_out_tmp[7:0]=data_in;//注意这里是=不是<=
					flag=flag+1;
					valid_out<=1;
                    data_out<=data_out_tmp;
				end
			end
			else begin
				valid_out=0;
				// data_out<=0;  这句不要 要了就通不过测试用例
			end
		end
	end
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)begin
			data_out<=0;
			valid_out<=0;
		end
    end
endmodule

注意点

接下来说一说代码中有几个需要注意的地方:

1.代码第29行,为什么用=而不用<=

  • 观察题目的波形图,可以发现当装载完数据,valid_out为1恰好是在如下图的“1”处。所以装载完数据要马上能让valid_in为1。所以用阻塞赋值,让data_in的数据完整装到data_out_tmp里面才可以赋值给data_out.

2.第37行代码,为什么那句代码不要?

  • 因为要了的话就通不过测试。在valid_in为0期间,data_out还要保持valid_in为1时的值。所以这句代码不能要。

3.第41行到第46行是不是多余?

  • 其实我也觉得多余,因为在第15~19行已经给它赋值过了。但是如果不要第41~46行,就会报错。咱也不知道为啥呢【

4.这想提一个题外话,笔者发现牛客的仿真和在vivado上的仿真不一样唉。同样的代码逻辑,在牛客上仿真时valid_out为1时要落后于valid_in一拍,但是在vivado上仿真两个可以同时为1,咱也不知道为啥呢【

全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务