FPGA_存储器

fpga 存储器有三大部分,RAM、ROM、FIFO,下面还有分支小部分DRAM、SRAM、Flash、CAM等,但是只对三大部分说明,实际使用的也是最多。

一、FIFO

1、FIFO:first in first out ,顺序存取,先入先出,是一种数据缓存器。

        应用场景

                        1不同的时钟域:数据的生成速率,与数据的使用读取速率不相等,使用FIFO作为数据的临时缓存。(异步时钟)

                        2不同位宽/相同位宽:数据的接收与发送位宽不等,这个时候用FIFO来缓存,使数据收发正确。(同步时钟)

        重要参数FIFO 位宽,深度,写满,读空,剩余数据个数,复位信号

        看到网上的比喻很形象,FIFO例如隧道,位宽就是隧道里有几条车道,深度就是每条车道有几辆车,当隧道内车停满时,就是写满标志置1;当隧道内车走完时就是读空,隧道出口每条车道同时出车也就是位宽。如图

        同步FIFO设计原则:空满判断

        FIFO 的设计原则是任何时候都不能向满FIFO中写入数据(写溢出),任何时候都不能从空FIFO中读取数据(读溢出)。FIFO 设计的核心是空满判断。FIFO设置读,写地址指针,FIFO初始化的时候 读指针和写指针都指向地址为0的位置, 当往FIFO里面每写一个数据,写地址指针自动加1指向下一个要写入的地址。当从FIFO里面每读一个数据,读地址指针自动加1指向下一个要读出的地址,最后通过比较读地址指针和写地址指针的大小来确定空满状态.

注意:FIFO指针自动增加,指针不要出问题,不可以指定地址更改数据(RAM可以)。

      

        代码:FIFO的设计可以通过IP核设计,也可以直接用代码设计同步时钟FIFO。

1、代码设计FIFO:

module fifo_savemod
#(
//FIFO 存储数据的宽度数据位 16 
	parameter FIFO_WIDTH = 16,
//FIFO 存储数据的深度16   16 x 16 = 	256位数据
	parameter FIFO_DEPTH = 16,
	
	parameter FIFO_CNT_WIDTH = 5 //log_2_FIFO_DEPTH + 1
)
(
    input clk, rst, 
	input [1:0]iEn,
	input [FIFO_WIDTH - 1 : 0] iData,//写入的数据
	output [FIFO_WIDTH - 1 : 0] oData,//读出的数据
	output [1:0]oTag
);
    //parameter FIFO_DEPTH = 16'd1 << FIFO_CNT_WIDTH - 1;
    
    reg [FIFO_WIDTH - 1 : 0] RAM [FIFO_DEPTH - 1 : 0];
	
	reg [FIFO_WIDTH - 1:0] D1;

    reg [FIFO_CNT_WIDTH - 1 : 0] C1,C2; // N+1
			  
    always @ ( posedge clk or negedge rst )
	    if( !rst ) begin
			C1 <= 0; end
		//iEn[1] == 1 从地址1开始写入数据
		//写入数据  像是一个二位数组
		else if( iEn[1] ) begin
			RAM[ C1[FIFO_CNT_WIDTH - 2 : 0] ] <= iData;
			C1 <= C1 + 1'b1; 
		end
	
    always @ ( posedge clk or negedge rst )
	    if( !rst ) begin
			    D1 <= 0;
				C2 <= 0; end
		//iEn[0] == 1 读出从地址1开始读出数据
		//读出数据到D1也就是oDAta   二维数组
		else if( iEn[0] ) begin
				D1 <= RAM[ C2[FIFO_CNT_WIDTH - 2 : 0] ];
				C2 <= C2 + 1'b1; 
		end

    assign oData = D1;
	assign oTag[1] = ((C1[FIFO_CNT_WIDTH - 1] ^ C2[FIFO_CNT_WIDTH - 1]) & (C1[FIFO_CNT_WIDTH - 2 : 0] == C2[FIFO_CNT_WIDTH - 2 : 0]) ); // Full
	assign oTag[0] = ( C1 == C2 ); // Empty
	
endmodule

2、FIFO 读写测试


module uart_fifo_send(
		input sys_clk,
		input sys_rst_n,
		
		input [1:0]tis_tx_otag,
		input AT_OK_STATE_buffer,
		input [232-1:0] tis_tx_fifo,
		input uart_tx_busy,
		output reg [1:0] tis_tx_ien,
		output reg uart_send_en,
		output reg [7:0]uart_send_data,
		output reg AT_OK_DOWN,
		output reg [232-1:0] tis_tx_dat
		

);
reg [3:0] irtf;
reg [15:0] i;
//fifo 数据发送
reg [7:0] tis_tx_buf [39:0];
reg [232-1:0] sa_tx_buf [15:0];
reg en_flga;
reg        uart_en_d0; 
reg        uart_en_d1;  

/*
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)begin
		tis_tx_ien[1]<= 1'b0;
		sa_tx_buf[0] <= {8'hff,16'hffff,{64{1'b1}},{{8'd232-8'd64-8'd24}{1'b1}}};
	end
	else
	tis_tx_ien[1]<= 1'b1;
		tis_tx_dat <= sa_tx_buf[0];
end
*/
//捕获uart_tx_busy下降沿,得到一个时钟周期的脉冲信号
assign en_flag = uart_en_d1 & (~uart_en_d0);

//对发送使能信号uart_en延迟两个时钟周期
always @(posedge sys_clk or negedge sys_rst_n) begin         
    if (!sys_rst_n) begin
        uart_en_d0 <= 1'b0;                                  
        uart_en_d1 <= 1'b0;
    end                                                      
    else begin                                               
        uart_en_d0 <= uart_tx_busy;                               
        uart_en_d1 <= uart_en_d0;                            
    end
end
reg tx_ready;
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)begin
		i <= 16'b0;
		irtf <= 4'd0;
		tx_ready  <= 1'b0;
		AT_OK_DOWN <= 1'b0;
		tis_tx_ien[1]<= 1'b0;
		sa_tx_buf[0] <= {8'h00,16'h1122,{64{1'b1}},{{8'd232-8'd64-8'd40}{1'b1}},8'h0D,8'h0A};
	end
		
	else if((AT_OK_STATE_buffer == 1'b1) && (i <= 16'd33))begin
			case(irtf)
					0:
						begin
							tis_tx_ien[1]<= 1'b1;
							tis_tx_dat <= sa_tx_buf[0];
							irtf <= irtf + 1'b1;
						end
					1:
						begin
							tis_tx_ien[1]<= 1'b0;
							irtf <= irtf + 1'b1;
						end
					2:
						 if(!tis_tx_otag[0]) begin
							 // tis_tx_ien[1] <= 1'b0;
							  tis_tx_ien[0] <= 1'b1;
							  //faf0
							  tis_tx_buf[0] <= 8'hfa;
							  //faf0
							  tis_tx_buf[1] <= 8'hf0;
							  //8'h1b 8'd37
							  tis_tx_buf[2] <= 8'hf1;
							  //8'ha4
							  tis_tx_buf[3] <= 8'ha4;
							  tis_tx_buf[4] <= 8'ha5;
							  tis_tx_buf[5] <= 8'ha6;
							  //8'd37-3'd4=33
							 // tis_tx_data_len <= COM_PTL_LEN_AX_VEL-3'd4;
							  //状态机到下一状态
							  irtf <= irtf + 1'b1; end
					   else begin
						     tis_tx_ien[0] <= 1'b0;
						     irtf <= irtf + 1'b1;
					   end
					3:  begin 
						tis_tx_ien[0] <= 1'b0; 
						irtf <= irtf + 1'b1; end
					4:
						 begin
							  for(i=16'd4;i<16'd33;i=i+1'b1) begin
								 tis_tx_buf[i] <= tis_tx_fifo[(16'd37-16'd4-i)*8-1 -:8]; 
							  end
							  irtf <= irtf + 1'b1;
							  i <= 1'b0;
						 end
					5:
						begin
								uart_send_data <= tis_tx_buf[i];
								tx_ready  <= 1'b1;
							
								if(tx_ready && (~uart_tx_busy)) begin   //检测串口发送模块空闲
										tx_ready <= 1'b0;                   //准备过程结束
										uart_send_en  <= 1'b1;                   //拉高发送使能信号
										//i <= i + 1'b1;
										irtf <= 4'd5;
								end
								else if(uart_send_en == 1'b1)begin
									i <= i + 1'b1;
									tx_ready  <= 1'b0;
									uart_send_en <= 1'b0;
									irtf <= 4'd5;
										if(i > 16'd33)begin
											i <= 16'b0;
										end
								end
								else if(i == 16'd33)begin
									i <= 16'b0;
									irtf <= 4'd5;
									AT_OK_DOWN <= 1'b1;
								end
						end
					default: begin 
						irtf <= 4'd5;
						i <= i;	
						//AT_OK_STATE_buffer <= 1'b0;
					end
					endcase
				end
			else if(tx_ready && (~uart_tx_busy)) begin   //检测串口发送模块空闲
           //tx_ready <= 1'b0;                   //准备过程结束
           //uart_send_en  <= 1'b1;                   //拉高发送使能信号
			  i <= i;
			  if(i == 16'b0)begin
					i <= 16'b0;
					AT_OK_DOWN <= 1'b0;
			  end
			end
			else if(i == 16'b0)begin
				i <= 16'b0;
				AT_OK_DOWN <= 1'b0;
			end
			
	
end
endmodule

3、顶层模块

module uart_loop_test(
     input  sys_clk, 
	  input  sys_rst_n,
	  
	  input  uart_rxd,

	  output uart_txd
);

//parameter
parameter CLK_FREQ = 50000000;
parameter UART_BPS = 115200;

//fifo
parameter TIS_OUT_FIFO_BIT_WIDTH = 9'd232; //8'd64;
parameter TIS_OUT_FIFO_CNT = 4'd8;//5;3;7;
parameter TIS_OUT_FIFO_DEPTH = 8'd128;//16;4;64;
//wire define
wire uart_recv_done;
wire [7:0] uart_recv_data;
wire uart_send_en;
wire AT_OK_STATE;
wire [7:0] uart_send_data;
wire uart_tx_busy;
wire clk_100m_0;
wire clk_150m;
//

wire [1:0] tis_tx_otag;
wire [232-1:0] tis_tx_fifo;
//reg//

reg [232-1:0] sa_tx_dat;
wire [1:0]tis_tx_ien;
wire [232-1:0] tis_tx_dat;
wire AT_OK_DOWN;
//************************************
//***    main code
//************************************
//模块例化时对应
uart_receive #(
  .CLK_FREQ (CLK_FREQ),     //设置系统时钟频率
  .UART_BPS (UART_BPS))     //设置串口接收波特率
  u_uart_recv(
  .clk (sys_clk),
  .rst_n(sys_rst_n),
  
  .uart_rxd(uart_rxd),
  .uart_done(uart_recv_done),
  .uart_data(uart_recv_data)
);

//串口发送模块
uart_send#(
      .CLK_FREQ(CLK_FREQ),   //设置系统时钟频率
		.UART_BPS(UART_BPS))   //设置串口发送波特率
u_uart_send(
      .sys_clk(sys_clk),
		.sys_rst_n(sys_rst_n),
		.uart_en(uart_send_en),
		.uart_din(uart_send_data),
		.uart_tx_busy(uart_tx_busy),
		.uart_txd(uart_txd)
);

//串口环回模块
uart_loop u_uart_loop(
     .sys_clk(sys_clk),
	  .sys_rst_n(sys_rst_n),
	  
	  .recv_done(uart_recv_done), //接收一帧数据完成标志位
	  .recv_data(uart_recv_data), //接收数据
	  .AT_OK(AT_OK_STATE),
	  .AT_OK_DOWN_LOOP(AT_OK_DOWN),
	  .tx_busy(),     //发送忙状态标志
	  .send_en(),     //发送使能信号
	  .send_data()  //待发送数据
	  
);


pll	pll_inst (
	.inclk0 (sys_clk),
	.c0 (clk_100m_0),
	.c1 (clk_150m)
	//.c4 ( clk_1m )
);


fifo_savemod
	#(
		.FIFO_WIDTH(TIS_OUT_FIFO_BIT_WIDTH),
		.FIFO_DEPTH(TIS_OUT_FIFO_DEPTH),
		.FIFO_CNT_WIDTH(TIS_OUT_FIFO_CNT)
	) TIS_SEND_FIFO
	(
		.clk(sys_clk),
		.rst(sys_rst_n),
		.iEn(tis_tx_ien),
		.iData(tis_tx_dat),
		.oData(tis_tx_fifo),
		.oTag(tis_tx_otag)
	);

/*
fifo_v fifo_v (
	clock(sys_clk),
	data(tis_tx_dat),
	rdreq(tis_tx_otag),
	wrreq(tis_tx_ien),
	q(tis_tx_fifo)
	);
*/	
	
	
	
	
	
	
	
	
uart_fifo_send uart_fifo_send(
		.sys_clk(sys_clk),
		.sys_rst_n(sys_rst_n),
		
		.tis_tx_otag(tis_tx_otag),
		.AT_OK_STATE_buffer(AT_OK_STATE),
		.tis_tx_ien(tis_tx_ien),
		.uart_send_en(uart_send_en),
		.uart_send_data(uart_send_data),
		.tis_tx_fifo(tis_tx_fifo),
		.uart_tx_busy(uart_tx_busy),
		.AT_OK_DOWN(AT_OK_DOWN),
		.tis_tx_dat(tis_tx_dat)
);





	
	
	
endmodule

        IP核设计:FIFO的设计可以通过IP核设计异步时钟FIFO。

1、IP核设计

        位宽232,深度32,读写时钟,读写使能,读写端口,写满读空标志位。不同位宽设置可以在IP核设计选项中实现,输入输出位宽不一样。

        对于FIFO的深度与位宽的需求计算根据同一时刻写入的数据与读出的数据做差得到的值就是FIFO的大小。

        2、读数据

                注意,读代码流程,以及读使能后需要几个时钟周期才有数据。

module fifo_rd(

		input sys_clk,
		input sys_rst_n,
		
		input [231:0] 	data		,
		input 			rdfull	,
		input 			rdempty	,
		output reg 		rdreq		,
		input                AT_OK	   			,
		input 					uart_tx_busy		,
		output reg 				uart_send_en		,
		output reg 				AT_OK_DOWN			,
		output reg [7:0] send_data_buffer
);
//reg define
reg [4:0] rd_num;
reg [7:0]data_buffer[29:0];
reg [7:0] i;
reg tx_ready;
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)begin
		rd_num <= 5'd0;
		rdreq  <= 1'b0;
		send_data_buffer <= 8'd0;
		i <= 8'd0;
	end
	else if((AT_OK == 1'b1) && (i <= 8'd29))begin
		case(rd_num)
			5'd0:
				begin
					//如果fifo满,下一个状态,否则当前状态
					if(rdfull)begin
						rdreq <= 1'b1;
						rd_num <= rd_num + 1'b1;
					end
						rd_num <= rd_num + 1'b1;
				end
			5'd1:
				begin
					rdreq <= 1'b1;
					rd_num <= rd_num + 1'b1;
					i <= 8'd0;
				end
			5'd2:
				begin
					rdreq <= 1'b1;
					rd_num <= rd_num + 1'b1;
					i <= 8'd0;
				end
			5'd3:
				begin
					if(rdempty)begin
						rdreq <= 1'b0;
						rd_num <= 5'd0;
					end
					else begin
						rdreq <= 1'b1;
						for(i=8'd0;i<8'd29;i=i+1'b1) begin
							data_buffer[i] <= data[(8'd29-i)*8-1 -:8]; 
						end
						rd_num <= rd_num + 1'b1;
						i <= 8'd0;
					end
				end
			5'd4:
				begin
					rdreq <= 1'b0;
					rd_num <= rd_num + 1'b1;
				end
			5'd5:
				begin
									send_data_buffer <= data_buffer[i];
									tx_ready  <= 1'b1;
								
									if(tx_ready && (~uart_tx_busy)) begin   //检测串口发送模块空闲
											tx_ready <= 1'b0;                 //准备过程结束
											uart_send_en  <= 1'b1;            //拉高发送使能信号
											//i <= i + 1'b1;
											rd_num <= 5'd5;
									end
									else if(uart_send_en == 1'b1)begin
										i <= i + 1'b1;
										tx_ready  <= 1'b0;
										uart_send_en <= 1'b0;
										rd_num <= 5'd5;
											if(i > 8'd29)begin
												i <= 8'd0;
												rd_num <= 5'd0;
											end
									end
									else if(i == 8'd29)begin
										i <= 8'd0;
										rd_num <= 5'd0;
										AT_OK_DOWN <= 1'b1;
									end
				end
			
		default:;
		endcase
	end
	else if(tx_ready && (~uart_tx_busy)) begin  		//检测串口发送模块空闲
           //tx_ready <= 1'b0;                   		//准备过程结束
           //uart_send_en  <= 1'b1;                   //拉高发送使能信号
			  i <= i;
			  if(i == 8'd0)begin
					i <= 8'd0;
					AT_OK_DOWN <= 1'b0;
					rd_num <= 5'd0;
			  end	
		end
		else if(i == 8'd0)begin
				i <= 8'd0;
				AT_OK_DOWN <= 1'b0;
				rd_num <= 5'd0;
		end
end
endmodule

3、写数据

        注意:判断写满和写空标志

module fifo_wr(
		input sys_clk	,
		input sys_rst_n,
		
		input 					wrempty	,
		input 					wrfull	,
		input 					AT_OK		,
		output reg [231:0] 	data		,
		output reg 				wrreq
		

);
reg [232-1:0] ram_buf [15:0];
reg [4:0] fifo_num;
//写数据
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(!sys_rst_n)begin
		ram_buf[0] <= {8'haa,16'hbbcc,{64{1'b1}},{{8'd232-8'd64-8'd40}{1'b1}},8'h0D,8'h0A};
		fifo_num <= 4'd0;
		data <= 232'd0;
		wrreq <= 1'b0;
	end
	//接收到指令写入数据
	else if(1'b1)begin
		case(fifo_num)
			5'd0:
				begin
					//如果写是空的,进入下一个状态,否则在当前状态
					if(wrempty == 1'b1)begin
						wrreq <= 1'b1;
						fifo_num <= fifo_num + 1'b1;
					end
					else
						fifo_num <= fifo_num;
				end
			5'd1:
				begin
				//如果写满了,返回上一个状态,如果没有写满,继续写
					if(wrfull == 1'b1)begin
						wrreq <= 1'b0;
						data <= 232'd0;
						fifo_num <= 5'd0;
					end
					else
						wrreq <= 1'b1;
						data <= ram_buf[0];
						fifo_num <= 5'd2;
				end
		default:fifo_num <= 5'd0;
		endcase
	end
	
end
endmodule

4、顶层模块

module uart_loop_test(
     input  sys_clk, 
	  input  sys_rst_n,
	  
	  input  uart_rxd,

	  output uart_txd
);

//parameter
parameter CLK_FREQ = 50000000;
parameter UART_BPS = 921600;

//fifo
parameter TIS_OUT_FIFO_BIT_WIDTH = 9'd232; //8'd64;
parameter TIS_OUT_FIFO_CNT = 4'd8;//5;3;7;
parameter TIS_OUT_FIFO_DEPTH = 8'd128;//16;4;64;
//wire define
wire uart_recv_done;
wire [7:0] uart_recv_data;
wire uart_send_en;
wire AT_OK_STATE;
wire AT_OK_STATE_2;
wire [7:0] uart_send_data;
wire uart_tx_busy;
wire clk_100m_0;
wire clk_150m;
wire clk_50m;
wire clk_25m;
//

wire [1:0] tis_tx_otag;
wire [232-1:0] tis_tx_fifo;
//reg//

reg [232-1:0] sa_tx_dat;
wire [1:0]tis_tx_ien;
wire [232-1:0] tis_tx_dat;
wire AT_OK_DOWN;
//************************************
//***    main code
//************************************
//模块例化时对应
uart_receive #(
  .CLK_FREQ (CLK_FREQ),     //设置系统时钟频率
  .UART_BPS (UART_BPS))     //设置串口接收波特率
  u_uart_recv(
  .clk (sys_clk),
  .rst_n(sys_rst_n),
  
  .uart_rxd(uart_rxd),
  .uart_done(uart_recv_done),
  .uart_data(uart_recv_data)
);

//串口发送模块
uart_send#(
      .CLK_FREQ(CLK_FREQ),   //设置系统时钟频率
		.UART_BPS(UART_BPS))   //设置串口发送波特率
u_uart_send(
      .sys_clk(sys_clk),
		.sys_rst_n(sys_rst_n),
		.uart_en(uart_send_en),
		.uart_din(uart_send_data),
		.uart_tx_busy(uart_tx_busy),
		.uart_txd(uart_txd)
);

//串口环回模块
uart_loop u_uart_loop(
     .sys_clk(sys_clk),
	  .sys_rst_n(sys_rst_n),
	  
	  .recv_done(uart_recv_done), //接收一帧数据完成标志位
	  .recv_data(uart_recv_data), //接收数据
	  .AT_OK(AT_OK_STATE),
	  .AT_OK_2(AT_OK_STATE_2),
	  .AT_OK_DOWN_LOOP(AT_OK_DOWN)
	  //.tx_busy(),     //发送忙状态标志
	  //.send_en(),     //发送使能信号
	  //.send_data()  //待发送数据
	  
);


pll	pll_inst (
	.inclk0 (sys_clk),
	.c0 (clk_100m_0),
	.c1 (clk_150m),
	.c2 (clk_50m),
	.c3 (clk_25m)
);


fifo_savemod
	#(
		.FIFO_WIDTH(TIS_OUT_FIFO_BIT_WIDTH),
		.FIFO_DEPTH(TIS_OUT_FIFO_DEPTH),
		.FIFO_CNT_WIDTH(TIS_OUT_FIFO_CNT)
	) TIS_SEND_FIFO
	(
		.clk(sys_clk),
		.rst(sys_rst_n),
		.iEn(tis_tx_ien),
		.iData(tis_tx_dat),
		.oData(tis_tx_fifo),
		.oTag(tis_tx_otag)
	);

/*
fifo_v fifo_v (
	clock(sys_clk),
	data(tis_tx_dat),
	rdreq(tis_tx_otag),
	wrreq(tis_tx_ien),
	q(tis_tx_fifo)
	);
*/
uart_fifo_send uart_fifo_send(
		.sys_clk(sys_clk),
		.sys_rst_n(sys_rst_n),
		
		.tis_tx_otag(),
		.AT_OK_STATE_buffer(),
		.tis_tx_ien(),
		.uart_send_en(),
		//.uart_send_data(),
		.tis_tx_fifo(),
		.uart_tx_busy(),
		.AT_OK_DOWN(),
		.tis_tx_dat()
);


//把指定数据写入,在根据收到信号,把数据读出,
wire [12:0] ram_addr;		 //读写地址
//wire [231:0] ram_wr_data;//写数据
//wire ram_rd_en; 			 //读使能
//wire ram_wr_en; 			 //写使能
//wire [231:0] ram_rd_data;//读数据
ram_1port u_ram_1port(
 .address (ram_addr),
 .clock (sys_clk),
 .data (),
 .rden (),
 .wren (),
 .q ()
 );
/*
//读写 ram 操作模块
uart_ram_send uart_ram_send(
		.sys_clk(sys_clk),
		.sys_rst_n(sys_rst_n),
		
		.ram_wr_en(),         	//写使能
		.ram_rd_en(),         	//读使能
		.ram_addr(ram_addr),    			//ram读写地址
		
		.ram_wr_data(), 		//ram写数据
		.ram_rd_data(),			//ram读数据
													
		.uart_send_data(),
		.uart_send_en(),										//串口接收数据正确,发送使能
		.uart_tx_busy(),
		.AT_OK_DOWN(),
		.AT_OK_STATE_buffer(),
		.AT_OK_STATE_buffer_2()
);
*/
//2ram define
ram_2port ram_2port_inst (
			.data (ram_wr_data),
			.wraddress (ram_wr_addr),
			.wrclock (clk_100m_0 ),
			.wren (ram_wr_en ), 
			
			.q (ram_rd_data ),
			.rdaddress (ram_rd_addr ),
			.rdclock (clk_50m ),
			.rden (ram_rd_en )
 );


//wire define  
wire  ram_wr_en;
wire [9:0] ram_wr_addr;
wire [231:0] ram_wr_data;
//  写入数据
uart_2ram_write uart_2ram_write(
			.sys_clk	 (clk_100m_0)			  	,
			.sys_rst_n(sys_rst_n)			,
			
			.AT_OK(),
			//ram写端口操作
			.ram_wr_en(ram_wr_en)			,  //ram写使能
			.ram_wr_addr(ram_wr_addr)		,	//写地址
			.ram_wr_data(ram_wr_data)		,	//写数据
			
);

//wire
wire    ram_rd_en;
wire [9:0] ram_rd_addr;
wire [231:0] ram_rd_data;
wire [231:0] ram_rd_data_buffer;
wire    read_done;
//读出数据

uart_2ram_read uart_2ram_read(
			.sys_clk	(clk_50m),
			.sys_rst_n(sys_rst_n),
			
			//RAM读出数据
			.ram_rd_en(ram_rd_en)						,
			.ram_rd_addr(ram_rd_addr)					,
			.ram_rd_data(ram_rd_data)					,
			
			.AT_OK()							,
			.uart_tx_busy(),
			.uart_send_en(),
			.AT_OK_DOWN(),
			//.read_done(read_done)
			.uart_send_data()
);



//FIFO
wire wrreq;
wire [231:0] data;
wire wrempty;
wire wrfull;
wire wrusedw;


wire rdreq;
wire [231:0] q;
wire rdempty;
wire rdfull;
wire rdusedw;
fifo fifo(
		 .wrclk 	( clk_100m_0 )	, // 写时钟
		 .wrreq 	( wrreq )	, // 写请求
		 .data 	( data )		, // 写入 FIFO 的数据
		 .wrempty( wrempty )	, // 写空信号
		 .wrfull ( wrfull )	, // 写满信号
		 .wrusedw( wrusedw )	, // 写侧数据量
		 
		 .rdclk 	( clk_25m )	, // 读时钟
		 .rdreq 	( rdreq )	, // 读请求
		 .q 		( q )			, // 从 FIFO 输出的数据
		 .rdempty( rdempty )	, // 读空信号
		 .rdfull ( rdfull )	, // 读满信号
		 .rdusedw( rdusedw )   // 读侧数据量
);


fifo_wr fifo_wr(
		.sys_clk		(clk_100m_0)	 ,
		.sys_rst_n	(sys_rst_n)  ,
		
		.wrempty		(wrempty)	 ,
		.wrfull		(wrfull)		 ,
		.AT_OK		(AT_OK_STATE),
		.data			(data)		 ,
		.wrreq		(wrreq)
);


fifo_rd fifo_rd(

		.sys_clk					(clk_25m)			,
		.sys_rst_n				(sys_rst_n) 		,
		
		.data						(q)					,
		.rdfull 					(rdfull)				,
		.rdempty 				(rdempty)			,
		.rdreq					(rdreq)				,
		.AT_OK					(AT_OK_STATE)   	,
		.uart_tx_busy 			(uart_tx_busy)		,
		.uart_send_en 			(uart_send_en)		,
		.AT_OK_DOWN				(AT_OK_DOWN)		,
		.send_data_buffer 	(uart_send_data)
);















endmodule

二、RAM

三、ROM

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值