赞
踩
`timescale 1ns/1ns // 数据发送模块 module data_driver( input clk_a, input rst_n, input data_ack, output reg [3:0] data, output reg data_req ); reg data_ack_1; reg data_ack_2; reg [2:0] count; // 打两拍消除亚稳态 always @(posedge clk_a or negedge rst_n) begin if (~rst_n) begin data_ack_1 <= 1'b0; data_ack_2 <= 1'b0; end else begin data_ack_1 <= data_ack; data_ack_2 <= data_ack_1; end end // 输出数据data always @(posedge clk_a or negedge rst_n) begin if (~rst_n) begin data <= 4'b0; end else if (data_ack_1 && !data_ack_2) begin if (data == 4'd7) begin data <= 4'd0; end else begin data <= data + 1; end end else begin data <= data; end end // count计数模块 always @(posedge clk_a or negedge rst_n) begin if (~rst_n) begin count <= 3'b0; end else if (data_ack_1 && !data_ack_2) begin count <= 3'b0; end else if (data_req) begin count <= count; end else begin count <= count + 1; end end // data_req信号 always @(posedge clk_a or negedge rst_n) begin if (~rst_n) begin data_req <= 1'b0; end else if (count == 3'b100) begin data_req <= 1'b1; end else if (data_ack_1 && !data_ack_2) begin data_req <= 1'b0; end else begin data_req <= data_req; end end endmodule
`timescale 1ns/1ns // 数据接收模块 module data_receiver( input clk_b, input rst_n, input [3:0] data, input data_req, output reg data_ack ); reg data_req_1; reg data_req_2; reg [3:0] data_in; // 打两拍消除亚稳态 always @(posedge clk_b or negedge rst_n) begin if (~rst_n) begin data_req_1 <= 1'b0; data_req_2 <= 1'b0; end else begin data_req_1 <= data_req; data_req_2 <= data_req_1; end end // data_ack信号 always @(posedge clk_b or negedge rst_n) begin if (~rst_n) begin data_ack <= 1'b0; end else if (data_req_1) begin data_ack <= 1'b1; end else begin data_ack <= 1'b0; end end // 接收data数据到data_in always @(posedge clk_b or negedge rst_n) begin if (~rst_n) begin data_in <= 4'b0; end else if (data_req_1 && !data_req_2) begin data_in <= data; end else begin data_in <= data_in; end end endmodule
`timescale 1ns / 1ps `include "data_driver.v" `include "data_receiver.v" module tb_handshake; // data_driver Parameters parameter PERIOD1 = 10; parameter PERIOD2 = 20; // data_driver Inputs reg clk_a = 0 ; reg rst_n = 0 ; // data_receiver Inputs reg clk_b = 0 ; wire [3:0] data; initial begin forever #(PERIOD1/2) clk_a=~clk_a; end initial begin forever #(PERIOD2/2) clk_b = ~clk_b; end initial begin #(PERIOD1*2) rst_n = 1; end data_driver u_data_driver ( .clk_a ( clk_a ), .rst_n ( rst_n ), .data_ack ( data_ack ), .data ( data [3:0] ), .data_req ( data_req ) ); data_receiver u_data_receiver ( .clk_b ( clk_b ), .rst_n ( rst_n ), .data ( data [3:0] ), .data_req ( data_req ), .data_ack ( data_ack ) ); initial begin $dumpfile("handshake.vcd"); $dumpvars; #1000 $finish; end endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。