【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

posted @ 2017-10-13 08:49  XiaomaGee  阅读(801)  评论(0编辑  收藏  举报