题解 | #整数倍数据位宽转换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




全部评论

相关推荐

10-17 12:16
同济大学 Java
7182oat:快快放弃了然后发给我,然后让我也泡他七天最后再拒掉,狠狠羞辱他一把😋
点赞 评论 收藏
分享
10-28 14:42
门头沟学院 Java
watermelon1124:因为嵌入式炸了
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务