FIFO到 BRAM IP的 互联 即 AXIstream转接至 BRAM上 的 verilog 代码
control.v
module control #(
parameter TDATA_WIDTH = 32 ,
parameter BRAM_A_ADDR_WIDTH = 15 ,
parameter BRAM_din_WIDTH = 32 ,
parameter BRAM_B_ADDR_WIDTH = 15
)(
input [TDATA_WIDTH - 1 : 0] tdata ,
input tvaild ,
input sys_clk ,
input sys_rst_n ,
output reg tready ,
output reg [BRAM_A_ADDR_WIDTH - 1 : 0] addressa ,
output reg [BRAM_din_WIDTH - 1 : 0] dina ,
output reg ena , // this is first to let a vaild
output reg wea , // this is used to let a to write
output reg [BRAM_B_ADDR_WIDTH - 1 : 0] addressb ,
output reg enb
);
// my idea is we let it write then when write is over we let it read
// because word tell me read and write can together but address can not same
//==========================================================================\\
// define parameter and internal signals \\
//==========================================================================\\
reg [2:0] mode ; // 0 1 2 3 4 IDILE
//=============================================================================\\
// next is main code \\
//=============================================================================\\
//====================\\
//=====================================\\
always@(posedge sys_clk or negedge sys_rst_n)
begin
if( sys_rst_n == 0 )
begin
tready <= 1 ;
addressa <= 0 ;
dina <= 0 ;
ena <= 0 ;
wea <= 0 ;
addressb <= 0 ;
enb <= 0 ;
mode <= 0 ;
end
else
begin
case(mode)
3'b000 :
begin
dina <= dina ;
addressa <= addressa ;
ena <= 0 ;
wea <= 0 ;
addressb <= addressb ;
enb <= 0 ;
mode <= ( tvaild && tready ) ? 1 : 0 ;
end
3'b001 : // give number and address
begin
tready <= 0 ;
dina <= tdata ;
addressa <= addressa + 4 ;
ena <= 0 ;
wea <= 0 ;
addressb <= addressb ;
enb <= 0 ;
mode <= mode + 1 ;
end
3'b010 : // write in RAM
begin
tready <= 0 ;
dina <= dina ;
addressa <= addressa ;
ena <= 1 ;
wea <= 1 ;
addressb <= addressb ;
enb <= 0 ;
mode <= mode + 1 ;
end
3'b011 :
begin // read
tready <= 0 ;
dina <= dina ;
addressa <= addressa ;
ena <= 0 ;
wea <= 0 ;
addressb <= addressb+4 ;
enb <= 0 ;
mode <= mode + 1 ;
end
3'b100 :
begin // read
tready <= 0 ;
dina <= dina ;
addressa <= addressa ;
ena <= 0 ;
wea <= 0 ;
addressb <= addressb ;
enb <= 1 ;
mode <= mode + 1 ;
end
3'b101 :
begin
dina <= dina ;
addressa <= addressa ;
ena <= 0 ;
wea <= 0 ;
addressb <= addressb ;
enb <= 0 ;
tready <= 1 ;
mode <= 0 ;
end
default :
begin
dina <= dina ;
addressa <= addressa ;
ena <= 0 ;
wea <= 0 ;
addressb <= addressb ;
enb <= 0 ;
tready <= 1 ;
mode <= 0 ;
end
endcase
end
end
endmodule
control_tb .v
module control_tb #(
parameter TDATA_WIDTH = 32 ,
parameter BRAM_A_ADDR_WIDTH = 15 ,
parameter BRAM_din_WIDTH = 32 ,
parameter BRAM_B_ADDR_WIDTH = 15
);
reg [TDATA_WIDTH - 1 : 0] tdata ;
reg tvaild ;
reg sys_clk ;
reg sys_rst_n ;
wire tready ;
wire [BRAM_A_ADDR_WIDTH - 1 : 0] addressa ;
wire [BRAM_din_WIDTH - 1 : 0] dina ;
wire ena ; // this is first to let a vaild
wire wea ; //this is used to let a to write
wire [BRAM_B_ADDR_WIDTH - 1 : 0] addressb ;
wire enb ;
control # (
.TDATA_WIDTH(TDATA_WIDTH),
.BRAM_A_ADDR_WIDTH(BRAM_A_ADDR_WIDTH),
.BRAM_din_WIDTH(BRAM_din_WIDTH),
.BRAM_B_ADDR_WIDTH(BRAM_B_ADDR_WIDTH)
)
control_inst (
.tdata(tdata),
.tvaild(tvaild),
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.tready(tready),
.addressa(addressa),
.dina(dina),
.ena(ena),
.wea(wea),
.addressb(addressb),
.enb(enb)
);
always #10 sys_clk = ~sys_clk ;
initial begin
sys_clk = 0 ;
sys_rst_n = 1 ;
tvaild = 0 ;
#10
sys_rst_n = 0 ;
#10
sys_rst_n = 1 ;
#100
tvaild = 1 ;
tdata = 32'd8 ;
#200
tdata = 32'd10 ;
#200
tdata = 32'd1012 ;
#2000 $finish ;
end
endmodule