赞
踩
“一种解决总线同步问题的方法是使用一个保持寄存器和握手信号”,这也就是“先异步暂存,后同步写入”的方法
//发送端代码 //接收域应答信号ack采用两级寄存器同步,便于时序收敛 module woshou_tx( input rst_n, input t_clk, input ack, output [7:0] dout, output reg req ); reg ack_reg1,ack_reg2; reg [7:0] data_buf; reg [2:0]tr_state; reg [7:0] TR_MEM_Addr; reg [7:0] TR_MEM [255:0]; parameter TR_IDLE=3'b000, SND_DATA_REQ=3'b001, CHK_ACK_ACTIVE=3'b010, CHK_COMM_END=3'b100; always@(negedge rst_n or posedge t_clk) begin if(!rst_n)begin ack_reg1 <= 1'b0; ack_reg2 <= 1'b0; end else begin ack_reg1 <= ack; ack_reg2 <= ack_reg1; end end // always@(posedge t_clk or negedge rst_n) begin if(!rst_n) begin data_buf <= 1'b0; tr_state <= TR_IDLE; TR_MEM_Addr <= 1'b0; end else case(tr_state) TR_IDLE: //初始化状态 begin req <= 1'b0; TR_MEM_Addr <= 1'b0; tr_state <= SND_DATA_REQ; end SND_DATA_REQ: //送数据到总线上和发送请求信号 begin data_buf <= TR_MEM[TR_MEM_Addr]; req <= 1'b1; //发送请求信号,请求信号为高,表示请求接收 TR_MEM_Addr <= TR_MEM_Addr + 1; tr_state <= CHK_ACK_ACTIVE; end CHK_ACK_ACTIVE: //检测应答信号为高,释放请求信号 begin if(ack_reg2 == 1'b1) //便于时序收敛 begin req <= 1'b0; //释放请求信号 tr_state <= CHK_COMM_END; end else tr_state <= CHK_ACK_ACTIVE; end CHK_COMM_END: //检测握手通信结束,如果应答信号被释放,一次握手结束 begin if(ack_reg2 == 1'b0) tr_state <= SND_DATA_REQ; else tr_state <= CHK_COMM_END; end default:tr_state <= TR_IDLE; endcase end assign dout = data_buf; endmodule
module woshou_rx( input rst_n, input r_clk, input req, input [7:0] din, output reg ack ); reg req_reg1,req_reg2; reg [2:0] re_state; reg [7:0] RE_MEM_Addr; reg [7:0] RE_MEM[255:0]; parameter RE_IDLE=3'b000, CHK_REQ_ACTIVE=3'b001, CHK_REQ_RELEASE=3'b010; always@(posedge r_clk or negedge rst_n) begin if(!rst_n) begin req_reg1 <= 1'b0; req_reg2 <= 1'b0; end else begin req_reg1 <= req; req_reg2 <= req_reg1; end end // always@(posedge r_clk or negedge rst_n) begin if(!rst_n) begin re_state <= RE_IDLE; ack <= 1'b0; RE_MEM_Addr <= 1'b0; end else case(re_state) RE_IDLE: //初始化状态 begin RE_MEM_Addr <= 0; re_state <= CHK_REQ_ACTIVE; end CHK_REQ_ACTIVE: //检测发送端的数据发送请求信号 begin if(req_reg2 == 1) //如果有请求信号,接收数据 begin re_state <= CHK_REQ_RELEASE; RE_MEM_Addr <= RE_MEM_Addr + 1; RE_MEM[RE_MEM_Addr] <= din; //接收数据存放到MEM ack <= 1'b1; //检测到请求信号,发送接收端应答信号 end else re_state <= CHK_REQ_ACTIVE; end CHK_REQ_RELEASE: //检测请求信号释放,释放应答信号 begin if(req_reg2 == 0) begin ack <= 1'b0; //释放应答信号,一次握手通信结束 re_state <= CHK_REQ_ACTIVE; end else re_state <= RE_IDLE; end default: re_state <= RE_IDLE; endcase end endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。