目录
- valid/ready握手协议
- valid/ready状态机
- verilog实现代码
- 波形文件
valid/ready握手协议
在两个模块之间传输数据时候,可以使用valid/ready握手协议,保证数据传输的有效性。
发送方准备发送数据时,它发送valid信号给接收方,接收方准备好可以接收数据时候,他发送ready信号给发送方,在valid和ready信号都置高的时钟上升沿,开始传送数据。
valid/ready状态机
发送方接收方都会处于下图所示四个状态之一,它们的状态转化图如下
verilog实现代码
发送模块,文件名称:transmitter.sv
[code]`timescale 1ns/1ns module transmitter #(parameter DATA_WIDTH=8) ( input wire clk, input wire rst_n, output logic vld, output logic [DATA_WIDTH-1:0] data, input wire rdy ); //下一个valid信号 logic next_vld; //下一个数据及hold的数据 logic [DATA_WIDTH-1:0] next_data; reg [DATA_WIDTH-1:0] hold_data; //内部valid信号 logic i_vld; //内部data信号 logic [DATA_WIDTH-1:0] i_data; //发送数据队列,记录发送的数据,便于debug显示 logic [DATA_WIDTH-1:0] sent_data[$]; typedef enum {IDLE, WAIT_RDY, WAIT_VLD, TRANSFER} ff_state; ff_state current_state = IDLE; ff_state next_state = IDLE; //根据现在状态,更新下一个状态 always_comb begin case (current_state) IDLE: begin if (i_vld == 1 && rdy == 0) begin next_state = WAIT_RDY; end else if (i_vld == 0 && rdy == 1) begin next_state = WAIT_VLD; end else if (i_vld == 1 && rdy == 1) begin next_state = TRANSFER; end else begin next_state = current_state; end end WAIT_RDY: begin if (i_vld == 1 && rdy == 1) begin next_state = TRANSFER; end else begin next_state = current_state; end end WAIT_VLD: begin if (i_vld == 1 && rdy == 1) begin next_state = TRANSFER; end else begin next_state = current_state; end end TRANSFER: begin if (i_vld == 1 && rdy == 0) begin next_state = WAIT_RDY; end else if (i_vld == 0 && rdy == 1) begin next_state = WAIT_VLD; end else if (i_vld == 0 && rdy == 0) begin next_state = IDLE; end else begin next_state = current_state; end end endcase end always_ff @(posedge clk or negedge rst_n) begin // Next state here is the previous state from the previous cycle $display("[DEBUG %d] next_vld: %d, next_state: %d, current_state: %d", $time, next_vld, next_state, current_state); if (!rst_n) begin current_state |