本文主要是介绍【【FIFO to multiplier to RAM的 verilog 代码 和 testbnench 】】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
FIFO to multiplier to RAM的 verilog 代码 和 testbnench
只完成了单个数据的传输 大数据需要修改 tb 或者基本连线
FIFO.v
//synchronous fifo
module FIFO_syn #(parameter WIDTH = 16, // the fifo wideparameter DEPTH = 1024, // deepthparameter ADDR_WIDTH = clogb2(DEPTH) // bit wide// parameter PROG_EMPTY = 100, // this what we set to empty// parameter PROG_FULL = 800 // this what we set to full)(input sys_clk ,input sys_rst_n ,input wr_en ,input rd_en ,input [WIDTH-1: 0] din ,output reg full ,output reg empty , /// 1 is real empty 0 is no emptyoutput reg [WIDTH-1:0] dout );//========================================================================================//// define parameter and internal signals ////======================================================================================//reg [WIDTH-1 : 0] ram[DEPTH-1 : 0] ; // this we set a 15:0 total 1024 number ramreg [ADDR_WIDTH-1 : 0] wr_addr ; // this is write pointerreg [ADDR_WIDTH-1 : 0] rd_addr ; // this is read pointerreg [ADDR_WIDTH-1 : 0] fifo_cnt ;//=========================================================================================//// next is main code ////=========================================================================================//// we set a function let me to count the numberfunction integer clogb2; // remember integer has symbol reg has no symbolinput[31:0]value;beginvalue=value-1;for(clogb2=0;value>0;clogb2=clogb2+1)value=value>>1;endendfunction// this you can see from the PPT 5-74//=================================================== next is used to readalways@(posedge sys_clk or negedge sys_rst_n)beginif(sys_rst_n == 0)rd_addr <= {ADDR_WIDTH{1'b0}};else if(rd_en && !empty)beginrd_addr <= rd_addr+1'd1;dout <= ram[rd_addr];endelsebeginrd_addr <= rd_addr;dout <= dout;endend//=================================================== next is used to writealways@(posedge sys_clk or negedge sys_rst_n)beginif(sys_rst_n == 0)beginwr_addr <= {ADDR_WIDTH{1'b0}} ; // this let pointer to zeroendelse if( wr_en && !full )begin // no full and wr_en and whether to write prog_full therewr_addr <= wr_addr + 1'b1 ;ram[wr_addr] <= din ;endelsewr_addr <= wr_addr ;end//============================================================== next is used to set fifo_cntalways@(posedge sys_clk or negedge sys_rst_n )beginif(sys_rst_n == 0)beginfifo_cnt <= {ADDR_WIDTH{1'b0}};endelse if(wr_en && !full && !rd_en)beginfifo_cnt <= fifo_cnt + 1'b1 ;endelse if(rd_en && !empty && !wr_en)beginfifo_cnt <= fifo_cnt - 1'b1 ;endelsefifo_cnt <= fifo_cnt ;end//========================================================== next is empty// we set counter so when the count is zero emptyalways@(posedge sys_clk or negedge sys_rst_n)beginif(sys_rst_n == 0)beginempty <= 1'b1 ; // begin we set empty to highend// there is two possibilties first no write fifo_cnt is all zero//second is no write it will be change to zero is just a will empty signalelseempty <= (!wr_en && (fifo_cnt[ADDR_WIDTH-1:1] == 'b0))&&((fifo_cnt[0] == 1'b0) || rd_en);end//============================================================ next is fullalways@(posedge sys_clk or negedge sys_rst_n)beginif(sys_rst_n == 0 )full <= 1'b1;//reset:1elsefull <= (!rd_en && (fifo_cnt[ADDR_WIDTH-1:1]=={(ADDR_WIDTH-1){1'b1}})) && ((fifo_cnt[0] == 1'b1) || wr_en);endendmodule
multiplier.v
module uumultiplier #(parameter NUMBER1 = 8 ,parameter NUMBER2 = 8 )(input [NUMBER1-1 : 0] input1 ,input [NUMBER2-1 : 0] input2 ,input clk ,input rst_n ,input begin_en ,output reg finish_en ,output reg [NUMBER1+NUMBER2 : 0] out);//======================================================================================\// define parameter and internal signal \//======================================================================================\reg [1:0] LCD = 2'b10 ;reg [1:0] LCD1 ;//==========================================================================================\// next is main code \\//===========================================================================================\\
always@(posedge clk or negedge rst_n) begin if(rst_n == 0)beginout <= 0 ;endelse LCD1 <= LCD ;endalways@(posedge clk or negedge rst_n)beginif(rst_n == 0)beginout <= 0 ;endelse if(begin_en && finish_en )beginout <= input1 * input2 ;LCD <= {LCD[0],LCD[1]} ; endelseout <= out ;endalways@(posedge clk or negedge rst_n)beginif(rst_n == 0)beginfinish_en <= 1'b1 ;endelse if(LCD == LCD1)beginfinish_en <= 1'b1 ;endelsefinish_en <= 1'b0 ;endendmodule
RAM.v
//DUal ended RAM
module RAM #(parameter WIDTH = 8 ,parameter DEPTH = 16 ,parameter ADD_WIDTH = clogb2(DEPTH)
)(input wr_clk ,input rd_clk ,input wr_en ,input rd_en ,input [WIDTH-1 : 0 ] din ,input [ADD_WIDTH-1 : 0] wr_address ,output reg [WIDTH-1 : 0 ] dout ,input [ADD_WIDTH-1 : 0] rd_address
);//==================================================================================\\
// define parameter and internal signal \\
//==================================================================================\\
reg [WIDTH - 1 : 0 ] ram [DEPTH - 1 : 0] ; //==================================================================================\\
// next is main code \\
//==================================================================================\\
function integer clogb2 ;
input [31:0] value ;
begin value = value - 1 ;for(clogb2 = 0 ; value > 0 ; clogb2 = clogb2 + 1)value = value >> 1 ;
end
endfunction // write
always@(posedge wr_clk)
begin if(wr_en) begin ram[wr_address] <= din ;end
end //read
always@(posedge rd_clk)
begin if(rd_en) begin dout <= ram[rd_address] ;end
end
endmodule
top.v
module dig_top #(parameter FIFO_WIDTH = 8 ,parameter FIFO_DEPTH = 8 ,parameter FIFO_ADDR_WIDTH = clogb2(FIFO_DEPTH) ,parameter NUMBER1 = 8 ,parameter NUMBER2 = 2 ,parameter RAM_WIDTH = NUMBER1+NUMBER2+1 ,parameter RAM_DEPTH = 8 ,parameter RAM_ADDR_WIDTH = clogb2(RAM_DEPTH)
)(input sys_clk ,input sys_rst_n ,input wr_en ,input rd_en ,input [FIFO_WIDTH-1 : 0] din ,input RAM_rd_en ,input [RAM_ADDR_WIDTH-1 : 0] wr_address ,input [RAM_ADDR_WIDTH-1 : 0] rd_address ,output wire [RAM_WIDTH-1 : 0] dout
);//=============================================================================\
// define parameter and internal signals \
//=============================================================================\
wire full ;
wire empty ;
wire [FIFO_WIDTH-1 : 0] dout1 ;
wire finish_en ;
wire [RAM_WIDTH-1 : 0 ] dout2 ;//===============================================================================\
// next is main code \
//=================================================================================\
function integer clogb2 ;input [31:0] value ;beginvalue = value - 1 ;for( clogb2 = 0 ; value > 0 ; clogb2 = clogb2 + 1)value = value >>1 ;endendfunctionFIFO_syn # (.WIDTH(FIFO_WIDTH),.DEPTH(FIFO_DEPTH),.ADDR_WIDTH(FIFO_ADDR_WIDTH))FIFO_syn_inst (.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.wr_en(wr_en),.rd_en(rd_en),.din(din),.full(full),.empty(empty),.dout(dout1));uumultiplier # (.NUMBER1(NUMBER1),.NUMBER2(2'b10))uumultiplier_inst (.input1(dout1),.input2(2'b10),.clk(sys_clk),.rst_n(sys_rst_n),.begin_en(rd_en),.finish_en(finish_en),.out(dout2));RAM # (.WIDTH(RAM_WIDTH),.DEPTH(RAM_DEPTH),.ADD_WIDTH(RAM_ADDR_WIDTH))RAM_inst (.wr_clk(sys_clk),.rd_clk(sys_clk),.wr_en(finish_en),.rd_en(RAM_rd_en),.din(dout2),.wr_address(wr_address),.dout(dout),.rd_address(rd_address));endmodule
top_tb.v
`timescale 1ns/1ns
module top_tb #(parameter FIFO_WIDTH = 4 ,parameter FIFO_DEPTH = 8 ,parameter FIFO_ADDR_WIDTH = 3 ,parameter NUMBER1 = 4 ,parameter NUMBER2 = 2 ,parameter RAM_WIDTH = 7 ,parameter RAM_DEPTH = 8 ,parameter RAM_ADDR_WIDTH = 3
);
reg sys_clk ;
reg sys_rst_n ;
reg wr_en ;
reg rd_en ;
reg [FIFO_WIDTH-1 : 0] din ;
reg RAM_rd_en ;
reg [RAM_ADDR_WIDTH-1 : 0] wr_address ;
reg [RAM_ADDR_WIDTH-1 : 0] rd_address ;
wire [RAM_WIDTH-1 : 0] dout ;
reg [11:0 ] cnt ;dig_top # (.FIFO_WIDTH(FIFO_WIDTH),.FIFO_DEPTH(FIFO_DEPTH),.FIFO_ADDR_WIDTH(FIFO_ADDR_WIDTH),.NUMBER1(NUMBER1),.NUMBER2(NUMBER2),.RAM_WIDTH(RAM_WIDTH),.RAM_DEPTH(RAM_DEPTH),.RAM_ADDR_WIDTH(RAM_ADDR_WIDTH))dig_top_inst (.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.wr_en(wr_en),.rd_en(rd_en),.din(din),.RAM_rd_en(RAM_rd_en),.wr_address(wr_address),.rd_address(rd_address),.dout(dout));always #5 sys_clk = ~sys_clk ;initial beginsys_clk = 1;sys_rst_n = 0;#100sys_rst_n = 1;endalways #10 sys_clk = ~sys_clk;initial begin sys_clk = 0 ;sys_rst_n = 1 ;wr_en = 0 ; rd_en = 0 ;wr_address = 1 ; rd_address = 1 ;#10sys_rst_n = 0;#10sys_rst_n = 1 ;#10// next is write wr_en = 1 ;rd_en = 1 ; din = 2 ;// RAM read RAM_rd_en = 1 ;end endmodule
这篇关于【【FIFO to multiplier to RAM的 verilog 代码 和 testbnench 】】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!