• 【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

  • 相关阅读:
    Python+request+unittest实现接口测试框架集成实例
    真正解决Jenkins安装插件总是报错的问题(网上查的解决方案都无效)
    Rancher 2.2.2
    Rancher管理k8s集群
    清理cosbench工具所占用磁盘空间的小脚本
    一个检查本机和远程机器的根目录所在磁盘的剩余空间的bash小脚本
    当df命令hang住了, 怎么办?
    OpenCV操作像素的几种方法(单个像素|操作多像素|遍历像素)
    OpenCV-颜色通道的分离、合并(转)
    ImageMagick 提取四通道png图片的alpha及magick使用
  • 原文地址:https://www.cnblogs.com/xiaomagee/p/7659336.html
Copyright © 2020-2023  润新知