This repository has been archived on 2023-04-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
vivado-202304/projects/datalink_814/dl814_z7/rtl/c2c_bridge.v
T
josh cd256a8cd6 Update gitignore, add dl814_z7 project
gitignore structure is updated to work with single and multi project situation under a single project directory
2023-03-29 10:42:01 +08:00

326 lines
8.3 KiB
Verilog

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 08/06/2022 04:29:04 PM
// Design Name:
// Module Name: c2c_bridge
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module c2c_bridge
#(
parameter [31:0] FRAME_HEAD = 31'h7E7E7E7E,
parameter [31:0] FRAME_MAX_LENGTH = 32'h00002000
)
(
input clk , // input clk, 100Mhz
input rst , // input rst, active high
//interface data
input c2c_clkin ,
output c2c_clkout,
input c2c_din ,
output c2c_dout ,
// bram interface
output tx_bram_clk , // output bram clk
output [31:0] tx_bram_addr , // output bram address[31:0]
input [31:0] tx_bram_dout , // input bram data[31:0]
output reg tx_bram_en , // output bram enable, active-high
output reg [3:0] tx_bram_we , // output bram write enable, active-high
output rx_bram_clk , // output bram clk
output reg [31:0] rx_bram_addr , // output bram address[31:0]
output reg [31:0] rx_bram_din , // output bram data[31:0]
output reg rx_bram_en , // output bram enable, active-high
output reg [3:0] rx_bram_we , // output bram write enable, active-high
// pl interrupt
output reg pl_rd_done , // output pl_rd_done, active-high
output reg pl_wr_done , // output pl_wr_done, active-high
// flag signal from ps to pl
input ps_rd_done , // input ps_rd_done, active-high
input ps_wr_done // input ps_wr_done, active-high
);
reg [31:0] c2c_in_32;
reg [39:0] tx_bitcnt;
reg [39:0] rx_bitcnt;
reg [31:0] tx_frame_length;//byte
reg [31:0] rx_frame_length;//byte
always @ ( posedge c2c_clkin or posedge rst) begin
if ( rst ) begin
c2c_in_32 <= 32'h00000000;
end
else begin
c2c_in_32 <= {c2c_in_32[30:0],c2c_din};
end
end
reg [31:0] c2c_out_32;
always @ ( posedge clk or posedge rst) begin
if ( rst ) begin
c2c_out_32 <= 32'h00000000;
end
else if(tx_bitcnt[4:0] == 5'd1) begin
c2c_out_32 <= tx_bram_dout;
end
else begin
c2c_out_32 <= {c2c_out_32[30:0],1'b0};
end
end
assign c2c_dout = c2c_out_32[31];
// dly
wire pl_read_start;
reg ps_rd_done_d0;
reg ps_rd_done_d1;
reg ps_rd_done_d2;
reg ps_wr_done_d0;
reg ps_wr_done_d1;
reg ps_wr_done_d2;
always @ ( posedge clk ) begin
if ( rst ) begin
ps_rd_done_d0 <= 1'b0;
ps_rd_done_d1 <= 1'b0;
ps_rd_done_d2 <= 1'b0;
ps_wr_done_d0 <= 1'b0;
ps_wr_done_d1 <= 1'b0;
ps_wr_done_d2 <= 1'b0;
end else begin
ps_rd_done_d0 <= ps_rd_done;
ps_rd_done_d1 <= ps_rd_done_d0;
ps_rd_done_d2 <= ps_rd_done_d1;
ps_wr_done_d0 <= ps_wr_done;
ps_wr_done_d1 <= ps_wr_done_d0;
ps_wr_done_d2 <= ps_wr_done_d1;
end
end
assign pl_read_start = ps_wr_done_d1 ^ ps_wr_done_d2;
////////////////// TX PORT /////////////////////
// state machine
reg [3:0] tx_state_next;
reg [3:0] tx_state;
localparam S_TX_WAIT = 4'd0;
localparam S_TX_PLREAD = 4'd1;
always @ (*) begin
case (tx_state)
S_TX_WAIT : begin
if ( pl_read_start ) begin //can read
tx_state_next <= S_TX_PLREAD;
end
else begin
tx_state_next <= S_TX_WAIT;
end
end
S_TX_PLREAD : begin // read bram
if(tx_bram_addr[31:0] >= tx_frame_length[31:0]) begin//frame end
tx_state_next <= S_TX_WAIT;
end
else if(tx_bram_addr > FRAME_MAX_LENGTH)begin //overtime
tx_state_next <= S_TX_WAIT;
end
else begin
tx_state_next <= S_TX_PLREAD;
end
end
default : begin
tx_state_next <= S_TX_WAIT;
end
endcase
end
always @(posedge clk) begin
tx_state <= tx_state_next;
end
//tx_bitcnt
always @(posedge clk) begin
if(rst) begin
tx_bitcnt[39:0] <= 40'd0;
end
else if(tx_state == S_TX_PLREAD) begin
tx_bitcnt[39:0] <= tx_bitcnt[39:0]+40'd1;
end
else begin
tx_bitcnt[39:0] <= 40'd0;
end
end
//tx_frame_length
always @(posedge clk) begin
if(rst) begin
tx_frame_length[31:0] <= 32'hFFFFFFFF;
end
else if(tx_bitcnt == 40'h0000000021) begin
tx_frame_length[31:0] <= tx_bram_dout;
end
else if(tx_state == S_TX_PLREAD) begin
tx_frame_length[31:0] <= tx_frame_length[31:0];
end
else begin
tx_frame_length[31:0] <= 32'hFFFFFFFF;
end
end
// tx_bram_en
// always enable
always @(posedge clk) begin
tx_bram_en <= 1'b1;
end
// tx_bram_we
// always disable
always @(posedge clk) begin
tx_bram_we[3:0] <= 4'h0;
end
//tx_bram_addr
assign tx_bram_addr = {tx_bitcnt[34:5],2'b0};
assign c2c_clkout = clk;
assign tx_bram_clk = clk;
////////////////// RX PORT /////////////////////
reg [3:0] rx_state_next;
reg [3:0] rx_state;
localparam S_RX_WAIT = 4'd0;
localparam S_RX_PLWRITE = 4'd1;
always @ (*) begin
case (rx_state)
S_TX_WAIT : begin
if ( c2c_in_32 == FRAME_HEAD ) begin //can write
rx_state_next <= S_RX_PLWRITE;
end
else begin
rx_state_next <= S_RX_WAIT;
end
end
S_RX_PLWRITE : begin // write bram
if(rx_bram_addr[31:0] >= rx_frame_length[31:0]) begin//frame end
rx_state_next <= S_RX_WAIT;
end
else if(rx_bram_addr > FRAME_MAX_LENGTH)begin //overtime
rx_state_next <= S_RX_WAIT;
end
else begin
rx_state_next <= S_RX_PLWRITE;
end
end
default : begin
rx_state_next <= S_RX_WAIT;
end
endcase
end
always @(posedge c2c_clkin) begin
rx_state <= rx_state_next;
end
//tx_bitcnt
always @(posedge c2c_clkin or posedge rst) begin
if(rst) begin
rx_bitcnt[39:0] <= 40'd0;
end
else if(rx_state == S_RX_PLWRITE) begin
rx_bitcnt[39:0] <= rx_bitcnt[39:0] + 40'd1;
end
else begin
rx_bitcnt <= 40'd0;
end
end
//rx_frame_length
always @(posedge c2c_clkin or posedge rst) begin
if(rst) begin
rx_frame_length[31:0] <= 32'hFFFFFFFF;
end
else if(rx_bitcnt == 40'h000000001F) begin
rx_frame_length[31:0] <= c2c_in_32;
end
else if(rx_state == S_RX_PLWRITE) begin
rx_frame_length[31:0] <= rx_frame_length[31:0];
end
else begin
rx_frame_length[31:0] <= 32'hFFFFFFFF;
end
end
// rx_bram_en
// always enable
always @(posedge c2c_clkin) begin
rx_bram_en <= 1'b1;
end
// rx_bram_we
// always disable
always @(posedge c2c_clkin or posedge rst) begin
if(rst) begin
rx_bram_we[3:0] <= 4'h0;
end
else if(rx_state_next == S_RX_PLWRITE) begin
rx_bram_we[3:0] <= 4'hF;
end
else begin
rx_bram_we[3:0] <= 4'h0;
end
end
//rx_bram_addr
always @(posedge c2c_clkin or posedge rst) begin
if(rst) begin
rx_bram_addr[31:0] <= 32'd0;
end
else if(rx_state == S_RX_PLWRITE) begin
rx_bram_addr = {rx_bitcnt[34:5],2'b0} + 32'd4;
end
else begin
rx_bram_addr[31:0] <= 32'b0;
end
end
reg [7:0] pl_wr_done_cnt;
always @(posedge c2c_clkin or posedge rst) begin
if(rst) begin
pl_wr_done_cnt <= 8'd0;
pl_wr_done <= 1'b0;
end
else if(rx_state == S_RX_PLWRITE
&& rx_state_next == S_RX_WAIT
&& rx_bram_addr <= FRAME_MAX_LENGTH) begin
pl_wr_done_cnt <= 8'd16;
pl_wr_done <= 1'b1;
end
else if(pl_wr_done_cnt > 0) begin
pl_wr_done_cnt <= pl_wr_done_cnt - 8'd1;
pl_wr_done <= 1'b1;
end
else begin
pl_wr_done_cnt <= 8'd0;
pl_wr_done <= 1'b0;
end
end
always @(posedge c2c_clkin or posedge rst) begin
if(rst) begin
rx_bram_din[31:0] <= 32'd0;
end
else begin
rx_bram_din <= c2c_in_32;
end
end
assign rx_bram_clk = c2c_clkin;
endmodule