题意整理
本题要求实现将6个单bit输入数据拼接之后输出。
时序图含有的信息较多,观察时序图需要注意:
l data_b是在已接收到6个数据后下一个时钟产生输出;
l 本模块与上游采用valid_ready握手机制,当valid_a拉低,表示与上游握手未成功,则此时data_a的数据无效,不存入本模块当中;
l 本模块与下游采用valid_only握手机制,这是一种单向指示性握手机制,已接收到6个数据后,valid_b拉高一个时钟周期,指示输出数据有效性
题解主体
要实现6个单bit输入数据的拼接,要用1个寄存器将先到达的数据缓存。当上游握手成功,将输入数据进寄存器,先收到的数据放在低位;当缓存好6个输入数据,valid_b拉高,输出data_b。
需要计数器来计数接收到的数据数量,计数器在0-5之间循环。计数器初始值是0,每接收一个数据,计数器加1,当计数器再次循环到0时,表示已经接收到6个数据,可以输出拼接结果。
Verilog代码如下:
reg [5:0] data_reg; reg [2:0] data_cnt; always @(posedge clk or negedge rst_n ) begin if(!rst_n) ready_a <= 'd0; else ready_a <= 1'd1; end always @(posedge clk or negedge rst_n ) begin if(!rst_n) data_cnt <= 'd0; else if(valid_a && ready_a) data_cnt <= (data_cnt == 3'd5) ? 'd0 : (data_cnt + 1'd1); end always @(posedge clk or negedge rst_n ) begin if(!rst_n) data_reg <= 'd0; else if(valid_a && ready_a) data_reg <= {data_a, data_reg[5:1]}; end always @(posedge clk or negedge rst_n ) begin if(!rst_n)begin valid_b <= 'd0; data_b <= 'd0; end else if(data_cnt == 3'd5)begin valid_b <= 1'd1; data_b <= {data_a, data_reg[5:1]}; end else valid_b <= 'd0; 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_reg; reg [2:0] data_cnt; always @(posedge clk or negedge rst_n ) begin if(!rst_n) ready_a <= 'd0; else ready_a <= 1'd1; end always @(posedge clk or negedge rst_n ) begin if(!rst_n) data_cnt <= 'd0; else if(valid_a && ready_a) data_cnt <= (data_cnt == 3'd5) ? 'd0 : (data_cnt + 1'd1); end always @(posedge clk or negedge rst_n ) begin if(!rst_n) data_reg <= 'd0; else if(valid_a && ready_a) data_reg <= {data_a, data_reg[5:1]}; end always @(posedge clk or negedge rst_n ) begin if(!rst_n)begin valid_b <= 'd0; data_b <= 'd0; end else if(data_cnt == 3'd5)begin valid_b <= 1'd1; data_b <= {data_a, data_reg[5:1]}; end else valid_b <= 'd0; end endmodule