题解 | #整数倍数据位宽转换8to16-解法4有问题#


自己写的时序出错,但是面试手撕的时候也没给时序图啊,可能问题也不大。
题解区copy的代码:
注意点:
1、a0的那个时钟周期valid是没有赶上上升沿的。
2、

`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 [7:0]       data_lock;  //data buffer

reg                      flag    ;

//input data buff in data_lock

always @(posedge clk or negedge rst_n ) begin

       if(!rst_n)

              data_lock <= 'd0;

       else if(valid_in && !flag)

              data_lock <= data_in;

end

//generate flag

always @(posedge clk or negedge rst_n ) begin

       if(!rst_n)

              flag <= 'd0;

       else if(valid_in)

              flag <= ~flag;

end

//generate valid_out

always @(posedge clk or negedge rst_n ) begin

       if(!rst_n)

              valid_out <= 'd0;

       else if(valid_in && flag)

              valid_out <= 1'd1;

       else

              valid_out <= 'd0;

end

//data stitching

always @(posedge clk or negedge rst_n ) begin

       if(!rst_n)

              data_out <= 'd0;

       else if(valid_in && flag)

              data_out <= {data_lock, data_in};

end
endmodule


不明白为什么解法2是错的
`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 [1:0] cnt;
    reg [15:0] data_in_reg;
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            cnt <= 0;
        end
        else if(valid_in) begin
            cnt <= (cnt == 2 ) ? 0 : cnt + 1;
        end
    end
    
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            data_in_reg <= 0;
        end
        else if(valid_in) begin
            data_in_reg <= {data_in_reg[7:0], data_in};
        end
    end
    
    always @ (*) begin
        if(~rst_n) begin
            valid_out <= 0;
        end
        else if(cnt == 2) begin
            valid_out <= 1;
        end
        else begin
            valid_out <= 0;
        end
    end
    always @ (*) begin
        if(~rst_n) begin
            data_out <= 0;
        end
        else if(valid_out) begin
            data_out <= data_in_reg;
        end
        else begin
            data_out <= data_out;
        end
    end
    
    
endmodule

解法2修改正确:
1、valid_out 是时序模块,cnt到1就可以了。
2、判断valid_out 时还需要cnt == 1 && valid_in,因为只有cnt == 1只能证明缓存了一个数,还需要再一个valid_in才行
`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 [1:0] cnt;
    reg [15:0] data_in_reg;
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            cnt <= 0;
        end
        else if(valid_in) begin
            cnt <= (cnt == 1 ) ? 0 : cnt + 1;
        end
    end
    
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            data_in_reg <= 0;
        end
        else if(valid_in) begin
            data_in_reg <= {data_in_reg[7:0], data_in};
        end
    end
    
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            valid_out <= 0;
        end
        else if(cnt == 1 && valid_in) begin
            valid_out <= 1;
        end
        else begin
            valid_out <= 0;
        end
    end
    always @ (*) begin
        if(~rst_n) begin
            data_out <= 0;
        end
        else if(valid_out) begin
            data_out <= data_in_reg;
        end
        else begin
            data_out <= data_out;
        end
    end
    
    
endmodule

解法3、为什么以下又通过不了,data_out的输出判断换为
cnt == 1 && valid_in
`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 [1:0] cnt;
    reg [15:0] data_in_reg;
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            cnt <= 0;
        end
        else if(valid_in) begin
            cnt <= (cnt == 1 ) ? 0 : cnt + 1;
        end
    end
    
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            data_in_reg <= 0;
        end
        else if(valid_in) begin
            data_in_reg <= {data_in_reg[7:0], data_in};
        end
    end
    
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            valid_out <= 0;
        end
        else if(cnt == 1 && valid_in) begin
            valid_out <= 1;
        end
        else begin
            valid_out <= 0;
        end
    end
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            data_out <= 0;
        end
        else if(cnt == 1 && valid_in) begin
            data_out <= data_in_reg;
        end
        else begin
            data_out <= data_out;
        end
    end
    
    
endmodule

解法3修改:
修改点:data_out 改为时序,则会发现当上升沿到来时最新的{data_in_reg[7:0], data_in}还没到,需要手动加上。
`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 [1:0] cnt;
    reg [15:0] data_in_reg;
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            cnt <= 0;
        end
        else if(valid_in) begin
            cnt <= (cnt == 1 ) ? 0 : cnt + 1;
        end
    end
    
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            data_in_reg <= 0;
        end
        else if(valid_in) begin
            data_in_reg <= {data_in_reg[7:0], data_in};
        end
    end
    
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            valid_out <= 0;
        end
        else if(cnt == 1 && valid_in) begin
            valid_out <= 1;
        end
        else begin
            valid_out <= 0;
        end
    end
    always @ (posedge clk, negedge rst_n) begin
        if(~rst_n) begin
            data_out <= 0;
        end
        else if(cnt == 1 && valid_in) begin
            data_out <= {data_in_reg[7:0], data_in};
        end
        else begin
            data_out <= data_out;
        end
    end
    
    
endmodule




全部评论

相关推荐

mq2:我倒是觉得这种敞亮一点好。能接受就去不能就不去呗。 完了跟现在“正常”公司一样,hr说的天花乱坠,进去一看根本就是996核动力牛马,想走又没应届生身份了。岂不是更糟。
点赞 评论 收藏
分享
浪子陪都:简历最优秀的地方放到了后面,国奖,校级奖学金这些是最亮眼的。说明你跟同级别的学生不一样。 建议台灯这个,PCB布局布线这个词汇不专业,业内是PCB Layout,第二,单片机的板子一般不用考虑SI,PI 都是低速信号,只要遵循3W原则就好了。 单片机的项目太low了,技能这块,你要看一下BOSS直聘的招聘要求,按照别人的要求写,一些关键词可以增加你简历被检索到的概率。 主修课程不用写,这个没有人去关注的。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务