计算机组成与结构 单周期CPU的存储模块设计(vivado)

1.框图

        1. 定义数据存储单元 RAM

名称为 RAM, Native 单口 RAM,无 ECC 校验,最小面积算法。可看到有 5 组 I/O 引脚。

        1. 数据 RAM 的例化

1).读写都是 32 位数据,一共有 16384 个数据,形成 64KB 的 RAM

2).需要初始化文件,初始化文件是 dmem32.coe

上一步注意,刚创建的项目是没有初始文件和相应的路径的,所以在创建 RAM 的时候可以先设置成没有初始文件。

创建好 RAM 后,将 Classfiles\ip\ram 中的初始化文件有存储器初始化文件 dmem32.coe 拷贝到 minisys/minisys.srcs/sources_1/ip/ram/中。

双击刚建立的 RAM IP 核,重新设置其为有初始化文件,并选择已经拷贝好的 dmem32.coe 文件。

3).按 OK 就行了

4).数据 RAM 初始化文件

2.子模块设计

wire ram_clk = !ram_clk_i;   

因为使用Block ram的固有延迟,RAM的地址线来不及在时钟上升沿准备好,使得时钟上升沿数据读出有误,所以采用反相时钟,使得读出数据比地址准备好要晚大约半个时钟,从而得到正确地址。

wire kickOff = upg_rst_i | (~upg_rst_i & upg_done_i);

kickOff = 1的时候CPU 正常工作,否则就是串口下载程序。

仿真顶层模块设置地址为0x00000010,先从这个地址读出原始的数据为0x00000000,然后设置MemWrit为高电平,并设置写数write_data为0xa00000f5。写完之后将MenWrite设置为低电平从0x00000010地址上读数据,读出的数据为0xa00000f5。

五、程序清单

1.设计文件

`timescale 1ns / 1ps

module dmemory32 (

    input                   ram_clk_i,

    input                   ram_wen_i,         // 来自控制单元

input     [13:0]    ram_adr_i,          // 来自memorio模块

input     [31:0]    ram_dat_i,           // 来自译码单元的read_data2

    output   [31:0]    ram_dat_o,          // 从存储器中获得的数据

      

       input           upg_rst_i,      // UPG reset (Active High)

       input           upg_clk_i,      // UPG ram_clk_i (10MHz)

       input           upg_wen_i,              // UPG write enable

       input      [13:0]    upg_adr_i,           // UPG write address

       input      [31:0]    upg_dat_i,           // UPG write data

       input           upg_done_i      // 1 if programming is finished

);

   

wire ram_clk = !ram_clk_i;   

// 因为使用Block ram的固有延迟,RAM的地址线来不及在时钟上升沿准备好,

       // 使得时钟上升沿数据读出有误,所以采用反相时钟,使得读出数据比地址准

       // 备好要晚大约半个时钟,从而得到正确地址。

                                                  

       // kickOff = 1的时候CPU 正常工作,否则就是串口下载程序。

    wire kickOff = upg_rst_i | (~upg_rst_i & upg_done_i);

   

    // 分配64KB RAM,编译器实际只用 64KB RAM

       ram ram (

        .clka    (kickOff ?     ram_clk        : upg_clk_i),

        .wea     (kickOff ?     ram_wen_i   : upg_wen_i),

        .addra  (kickOff ?     ram_adr_i    : upg_adr_i),

        .dina    (kickOff ?     ram_dat_i     : upg_dat_i),

        .douta  (ram_dat_o)

    );

endmodule

2.仿真文件

`timescale 1ns / 1ps

module ram_sim ();

    // input

    reg[31:0] address = 32'h00000010;     //来自memorio模块,源头是来自执行单元算出的alu_result

    reg[31:0] write_data = 32'ha0000000;  //来自译码单元的read_data2

    reg  Memwrite = 1'b0;         //来自控制单元

    reg  clock = 1'b0;

    reg  zero =1'b0;

    reg[31:0] zero32= 32'h00000000;

    reg one = 1'b1;  

    // output

    wire[31:0] read_data;

    dmemory32 Uram (

           .ram_clk_i   (clock),

              .ram_wen_i  (Memwrite),        // 来自控制单元

              .ram_adr_i   (address[15:2]),

// 来自memorio模块,源头是来自执行单元算出的alu_result

              .ram_dat_i    (write_data), // 来自译码单元的read_data2

              .ram_dat_o   (read_data),         // 从存储器中获得的数据

                     // UART Programmer Pinouts

        .upg_rst_i  (zero),      // UPG reset (Active High)

        .upg_clk_i  (zero),      // UPG ram_clk_i (10MHz)

           .upg_wen_i  (zero),        // UPG write enable

        .upg_adr_i   (zero32),         // UPG write address

        .upg_dat_i   (zero32),         // UPG write data

        .upg_done_i         (one)     // 1 if programming is finished

       );

    initial begin

      #200 begin write_data = 32'hA00000F5;Memwrite = 1'b1; end

      #200 Memwrite = 1'b0;

    end

    always #50 clock = ~clock;

endmodule

六、时序仿真结果及分析和硬件测试结果及分析

1.程序仿真图:

2.管脚分配图:

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值