【iCore1S 双核心板_FPGA】例程十七:基于双口RAM的ARM+FPGA数据存取实验
实验现象:
核心代码:
module DUAL_PORT_RAM( input CLK_12M, inout WR, input RD, input CS0, input [24:16]A, inout [15:0]DB, output FPGA_LEDR, output FPGA_LEDG, output FPGA_LEDB ); //-------------------------------rst_n---------------------------------// reg rst_n; reg [3:0]cnt_rst; always@(posedge CLK_12M) begin if(cnt_rst==4'd10) begin rst_n <= 1'd1; cnt_rst <= 4'd10; end else cnt_rst <= cnt_rst + 1'd1; end //---------------------------------PLL--------------------------------// //实例化PLL my_pll u1( .inclk0(CLK_12M), .c0(PLL_48M) ); //--------------------------------RAM---------------------------------// //实例化双口ram wire [15:0]a_dataout; wire [15:0]b_dataout; my_ram u2( .address_a(a_addr), .address_b(A), .data_a(a_datain), .data_b(DB), .clock_a(!a_clk), .clock_b(b_clk), .wren_a(a_wren), .wren_b(1'd0), .rden_a(a_rden), .rden_b(!rd), .q_a(a_dataout), .q_b(b_dataout) ); //-------------------------------delay-------------------------------// //对CLK_12M做延时处理 reg clk1,clk2; always@(posedge PLL_48M or negedge rst_n) begin if(!rst_n) begin clk1 <= 1'd0; clk2 <= 1'd0; end else begin {clk2,clk1} <= {clk1,CLK_12M}; end end wire a_clk = (CLK_12M & clk2); //---------------------------------ram_cnt----------------------------// //ram地址数据计数器 reg [9:0]cnt_addr; always@(posedge CLK_12M or negedge rst_n) begin if(!rst_n) begin cnt_addr <= 10'd0; end else if(cnt_addr==10'd511) begin cnt_addr <= 10'd0; end else cnt_addr <= cnt_addr + 1'd1; end //------------------------------ram_a wr&rd----------------------------// reg a_wren,a_rden; reg [9:0]a_datain; reg [9:0]a_addr; always@(posedge a_clk or negedge rst_n) begin if(!rst_n) begin a_wren <= 1'd0; a_rden <= 1'd0; a_datain <= 10'd0; a_addr <= 10'd0; end else if(cnt_addr >= 10'd0 && cnt_addr <= 10'd255) begin a_wren <= 1'd1; a_datain <= cnt_addr; a_addr <= cnt_addr; a_rden <= 1'd0; end else if(cnt_addr>=10'd256 && cnt_addr <= 1'd511) begin a_rden <= 1'd1; a_addr <= cnt_addr - 10'd256; a_wren <= 1'd0; end end //------------------------------a_ram_error---------------------------// //判断读取地址与输出数据是否相等。相等,绿灯亮;不相等,红灯亮。 reg error; reg [2:0]led; always@(negedge clk1 or negedge rst_n) begin if(!rst_n) begin error <= 1'd0; end else if(a_wren || a_dataout == a_addr) begin error <= 1'd0; led <= 3'b101; end else begin error <= 1'd1; led <= 3'b011; end end assign {FPGA_LEDR,FPGA_LEDG,FPGA_LEDB} = led; //-------------------------------b_ram_rd-----------------------------// //控制ram_b的读取功能,当读信号来临时,读取数据发送到FSMC总线上 wire wr = (CS0 | WR ); wire rd = (CS0 | RD); reg wr_clk1,wr_clk2; always@(posedge PLL_48M or negedge rst_n) begin if(!rst_n) begin wr_clk1 <= 1'd1; wr_clk2 <= 1'd1; end else begin {wr_clk2,wr_clk1} <= {wr_clk1,wr}; end end wire b_clk = (!wr_clk2 | !rd); assign DB = !rd ? b_dataout : 16'hzzzz; //------------------------------endmodule-----------------------------// endmodule
实验方法及指导书:
链接:http://pan.baidu.com/s/1hsEeYxe 密码:004h