Archived
gitignore structure is updated to work with single and multi project situation under a single project directory
326 lines
8.3 KiB
Verilog
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
|