欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > 构建可变变量的存储方式

构建可变变量的存储方式

2025/4/19 22:18:08 来源:https://blog.csdn.net/q1594/article/details/139335035  浏览:    关键词:构建可变变量的存储方式

简介

  在FPGA中最常用的IP核就是FIFO和RAM了,这两个通常由官方IP来实现,但是在IP中,如果想要修改参数就十分困难。因此就需要构建可变存储空间的FIFO和RAM。通常构建FIFO可以用XILINX提供的源语以及宏来实现,构建小容量的RAM可以用LUT来实现。

FIFO

`timescale 1ns / 1psmodule xpm_asfifo #(parameter FIFO_MEMORY_TYPE  	= "block"	, //block distributed  parameter WRITE_DATA_WIDTH  	= 32		, parameter FIFO_WRITE_DEPTH  	= 2048		,parameter WR_DATA_COUNT_WIDTH   = 12		,parameter READ_MODE         	= "std"		,//"std" "fwft" parameter READ_DATA_WIDTH   	= 32		,parameter RD_DATA_COUNT_WIDTH   = 12		,parameter FIFO_READ_LATENCY 	= 1			 	
)
(input								rst       		,   	input								wr_clk			,		input								rd_clk			,	input	[WRITE_DATA_WIDTH-1:0]		din				,			input								wr_en			,			input								rd_en			,	output	[READ_DATA_WIDTH-1:0]		dout			,	output								full			,			output								empty			,	output	[RD_DATA_COUNT_WIDTH-1:0]	rd_data_count	,output	[WR_DATA_COUNT_WIDTH-1:0]	wr_data_count	
);wire	pre_full	;
wire	wr_rst_busy	;wire [WRITE_DATA_WIDTH-1:0] din_sw	;
wire [READ_DATA_WIDTH-1:0]  dout_sw	;genvar i;
generate if(WRITE_DATA_WIDTH>=READ_DATA_WIDTH)for(i = 0; i < WRITE_DATA_WIDTH/READ_DATA_WIDTH; i = i + 1) beginassign din_sw[i*READ_DATA_WIDTH+:READ_DATA_WIDTH] = din[WRITE_DATA_WIDTH - READ_DATA_WIDTH - i*READ_DATA_WIDTH+:READ_DATA_WIDTH];endelseassign din_sw = din;
endgenerategenvar j;
generate if(WRITE_DATA_WIDTH<READ_DATA_WIDTH)for(j = 0; j < READ_DATA_WIDTH/WRITE_DATA_WIDTH; j = j + 1) beginassign dout[j*WRITE_DATA_WIDTH+:WRITE_DATA_WIDTH] = dout_sw[READ_DATA_WIDTH - WRITE_DATA_WIDTH - j*WRITE_DATA_WIDTH+:WRITE_DATA_WIDTH];endelseassign dout = dout_sw;	
endgenerateassign full = wr_rst_busy|pre_full;xpm_fifo_async #(.CDC_SYNC_STAGES(2),       // DECIMAL.DOUT_RESET_VALUE("0"),    // String.ECC_MODE("no_ecc"),       // String.FIFO_MEMORY_TYPE(FIFO_MEMORY_TYPE), // String.FIFO_READ_LATENCY(FIFO_READ_LATENCY),     // DECIMAL.FIFO_WRITE_DEPTH(FIFO_WRITE_DEPTH),   // DECIMAL.FULL_RESET_VALUE(0),      // DECIMAL.PROG_EMPTY_THRESH(10),    // DECIMAL.PROG_FULL_THRESH(10),     // DECIMAL.RD_DATA_COUNT_WIDTH(RD_DATA_COUNT_WIDTH),   // DECIMAL.READ_DATA_WIDTH(READ_DATA_WIDTH),      // DECIMAL.READ_MODE(READ_MODE),         // String.RELATED_CLOCKS(0),        // DECIMAL//.SIM_ASSERT_CHK(0),        // DECIMAL; 0=disable simulation messages, 1=enable simulation messages.USE_ADV_FEATURES("0707"), // String.WAKEUP_TIME(0),           // DECIMAL.WRITE_DATA_WIDTH(WRITE_DATA_WIDTH),     // DECIMAL.WR_DATA_COUNT_WIDTH(WR_DATA_COUNT_WIDTH)    // DECIMAL
)
xpm_fifo_async_inst (.almost_empty(),   // 1-bit output: Almost Empty : When asserted, this signal indicates that// only one more read can be performed before the FIFO goes to empty..almost_full(),     // 1-bit output: Almost Full: When asserted, this signal indicates that// only one more write can be performed before the FIFO is full..data_valid(),       // 1-bit output: Read Data Valid: When asserted, this signal indicates// that valid data is available on the output bus (dout)..dbiterr(),             // 1-bit output: Double Bit Error: Indicates that the ECC decoder detected// a double-bit error and data in the FIFO core is corrupted..dout(dout_sw),                   // READ_DATA_WIDTH-bit output: Read Data: The output data bus is driven// when reading the FIFO..empty(empty),                 // 1-bit output: Empty Flag: When asserted, this signal indicates that the// FIFO is empty. Read requests are ignored when the FIFO is empty,// initiating a read while empty is not destructive to the FIFO..full(pre_full),                   // 1-bit output: Full Flag: When asserted, this signal indicates that the// FIFO is full. Write requests are ignored when the FIFO is full,// initiating a write when the FIFO is full is not destructive to the// contents of the FIFO..overflow(),           // 1-bit output: Overflow: This signal indicates that a write request// (wren) during the prior clock cycle was rejected, because the FIFO is// full. Overflowing the FIFO is not destructive to the contents of the// FIFO..prog_empty(),       // 1-bit output: Programmable Empty: This signal is asserted when the// number of words in the FIFO is less than or equal to the programmable// empty threshold value. It is de-asserted when the number of words in// the FIFO exceeds the programmable empty threshold value..prog_full(),         // 1-bit output: Programmable Full: This signal is asserted when the// number of words in the FIFO is greater than or equal to the// programmable full threshold value. It is de-asserted when the number of// words in the FIFO is less than the programmable full threshold value..rd_data_count(rd_data_count), // RD_DATA_COUNT_WIDTH-bit output: Read Data Count: This bus indicates the// number of words read from the FIFO..rd_rst_busy(),     // 1-bit output: Read Reset Busy: Active-High indicator that the FIFO read// domain is currently in a reset state..sbiterr(),             // 1-bit output: Single Bit Error: Indicates that the ECC decoder detected// and fixed a single-bit error..underflow(),         // 1-bit output: Underflow: Indicates that the read request (rd_en) during// the previous clock cycle was rejected because the FIFO is empty. Under// flowing the FIFO is not destructive to the FIFO..wr_ack(),               // 1-bit output: Write Acknowledge: This signal indicates that a write// request (wr_en) during the prior clock cycle is succeeded..wr_data_count(wr_data_count), // WR_DATA_COUNT_WIDTH-bit output: Write Data Count: This bus indicates// the number of words written into the FIFO..wr_rst_busy(wr_rst_busy),     // 1-bit output: Write Reset Busy: Active-High indicator that the FIFO// write domain is currently in a reset state..din(din_sw),                     // WRITE_DATA_WIDTH-bit input: Write Data: The input data bus used when// writing the FIFO..injectdbiterr(1'b0), // 1-bit input: Double Bit Error Injection: Injects a double bit error if// the ECC feature is used on block RAMs or UltraRAM macros..injectsbiterr(1'b0), // 1-bit input: Single Bit Error Injection: Injects a single bit error if// the ECC feature is used on block RAMs or UltraRAM macros..rd_clk(rd_clk),               // 1-bit input: Read clock: Used for read operation. rd_clk must be a free// running clock..rd_en(rd_en),                 // 1-bit input: Read Enable: If the FIFO is not empty, asserting this// signal causes data (on dout) to be read from the FIFO. Must be held// active-low when rd_rst_busy is active high..rst(rst),                     // 1-bit input: Reset: Must be l to wr_clk. The clock(s) can be// unstable at the time of applying reset, but reset must be released only// after the clock(s) is/are stable..sleep(1'b0),                 // 1-bit input: Dynamic power saving: If sleep is High, the memory/fifo// block is in power saving mode..wr_clk(wr_clk),               // 1-bit input: Write clock: Used for write operation. wr_clk must be a// free running clock..wr_en(wr_en)                  // 1-bit input: Write Enable: If the FIFO is not full, asserting this// signal causes data (on din) to be written to the FIFO. Must be held// active-low when rst or wr_rst_busy is active high.);// End of xpm_fifo_async_inst instantiation
endmodule

RAM

带有两个写端口的双端RAM

  首先例化一个大的二维数组。端口A和端口B都可写,但只有端口B可读

//带有两个写端口的双端块RAM
module tdpram #(parameter AW = 10, 	//地址位宽parameter DW = 8    //数据位宽
)
(input 					clka	, 	input 					clkb	,input 					wea		,input 					web		,input 		[AW-1:0] 	addra	,input 		[AW-1:0]	addrb	,input 		[DW-1:0]	dina	,input 		[DW-1:0]	dinb	,output reg  [DW-1:0] 	douta	,output reg  [DW-1:0] 	doutb
);reg [DW-1:0] ram [(2**AW)-1:0];    //例化存储空间//初始化存储空间
integer i;
initial for (i=0; i < (2**AW); i=i+1) ram[i] = 0;//port 1
always@(posedge clka)      if (wea) ram[addra] <= dina;always@(posedge clka)douta <= ram[addra];//port 2
always@(posedge clkb)if (web) ram[addrb] <= dinb;//端口b可读
always@(posedge clkb)		doutb <= ram[addrb];	endmodule

写优先模式的单端块RAM

  和上面的例化一样,但是当有写使能的时候,读数据的端口不刷新,即写数据优先

// 写优先模式的单端块RAM,Wrist_first
module spram #(parameter AW = 10,parameter DW = 8 
)
(input 					clka	, input					wea		, input 		[AW-1:0]	addra	, input 		[DW-1:0]	dina	, output reg 	[DW-1:0]	douta
);reg [DW-1:0] ram [(2**AW)-1:0];integer i;
initial for (i=0; i < (2**AW); i=i+1) ram[i] = 0;always @(posedge clka)if (wea)beginram[addra] 	<= dina;douta 		<= dina;endelse douta <= ram[addra];endmodule

双时钟控制,伪双端块RAM

  A时钟写 B时钟读

//双时钟控制,伪双端块RAM
module sdpram #(parameter AW = 10,parameter DW = 8 
)
(input 					clka	,input 					clkb	,input 					wea		,input 		[AW-1:0]	addra	,input 		[AW-1:0]	addrb	,input 		[DW-1:0]	dina	,output reg 	[DW-1:0]	doutb
);reg [DW-1:0] ram [(2**AW)-1:0];integer i;
initial for (i=0; i < (2**AW); i=i+1) ram[i] = 0;always@(posedge clka)if (wea) ram[addra] <= dina;always@(posedge clkb)doutb <= ram[addrb];endmodule

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com