alt

时序图含有的信息较多,观察时序图需要注意:

alt

  • data_b是在已接收到6个数据后下一个时钟产生输出;

  • 本模块与上游采用valid_ready握手机制,当valid_a拉低,表示与上游握手未成功,则此时data_a的数据无效,不存入本模块当中;

  • 本模块与下游采用valid_only握手机制,这是一种单向指示性握手机制,已接收到6个数据后,valid_b拉高一个时钟周期,指示输出数据有效性。

要实现6个单bit输入数据的拼接,要用1个寄存器将先到达的数据缓存。当上游握手成功,将输入数据进寄存器,先收到的数据放在低位;当缓存好6个输入数据,valid_b拉高,输出data_b。

需要计数器来计数接收到的数据数量,计数器在0-5之间循环。计数器初始值是0,每接收一个数据,计数器加1,当计数器再次循环到0时,表示已经接收到6个数据,可以输出拼接结果。

`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;
    always@(posedge clk or negedge rst_n) begin: reg_input
        if(~rst_n)
            data_reg <= 6'b0;
        else if(valid_a && ready_a)
                data_reg <= {data_a, data_reg[5:1]};
    end
    
    reg [2:0] cnt;
    always@(posedge clk or negedge rst_n) begin: count_input
        if(~rst_n) 
            cnt <= 3'b0;
        else if(valid_a && ready_a)
            cnt <= (cnt == 3'd5)? 3'd0: (cnt + 1);
    end
    
    always @(posedge clk or negedge rst_n ) begin: gen_ready_a
    if(!rst_n) 
        ready_a <= 0;
    else 
        ready_a <= 1;
    end
    
    always@(posedge clk or negedge rst_n) begin: gen_signal_b
        if(~rst_n) begin
            data_b <= 0;
            valid_b <= 0;
        end
        else if(cnt == 3'd5) begin
            valid_b <= 1;
            data_b <= {data_a, data_reg[5:1]};
        end
        else
            valid_b <= 0;
    end
    
endmodule