简析
输入信号: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