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

查看14道真题和解析