zoukankan      html  css  js  c++  java
  • 【原创】DE2实验解答—lab8 (Quartus) (Digital Logic) (Verilog HDL)

    Introduction

        本练习主要研究FPGA片内/外存储器。实现32X8-bit的RAM。

        image

    Design

     

    Part I 用LPM实现RAM

        LPM的用法参阅<Using Library Module in Verilog Design>。

        1. Tools / MegaWizard Plug-in Manger /…/ memory compiles创建一个名为ramlpm.v的RAM。

            image

        2. 编译,并查看编译报告。RAM占用1个M4K块,256B。

        3. 仿真。

            仿真结果:

            clip_image002

     代码part 1:

    1 //part 1 用altsyncram LPM构建一个32*8bit RAM
    2  
    3  module part1(
    4 input [4:0] Address,
    5 input [7:0] DataIn,
    6 input Write,Clock,
    7 output [7:0] DataOut
    8 );
    9
    10 ramlpm u0(
    11 .address(Address),
    12 .clock(Clock),
    13 .data(DataIn),
    14 .wren(Write),
    15 .q(DataOut)
    16 );
    17
    18  endmodule
    19
    20
    21
    22  // megafunction wizard: %RAM: 1-PORT%
    23  // GENERATION: STANDARD
    24  // VERSION: WM1.0
    25  // MODULE: altsyncram
    26
    27  // ============================================================
    28  // File Name: ramlpm.v
    29  // Megafunction Name(s):
    30  // altsyncram
    31  //
    32  // Simulation Library Files(s):
    33  // altera_mf
    34  // ============================================================
    35  // ************************************************************
    36  // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
    37  //
    38 // 9.1 Build 222 10/21/2009 SJ Full Version
    39 // ************************************************************
    40
    41
    42 //Copyright (C) 1991-2009 Altera Corporation
    43 //Your use of Altera Corporation's design tools, logic functions
    44 //and other software and tools, and its AMPP partner logic
    45 //functions, and any output files from any of the foregoing
    46 //(including device programming or simulation files), and any
    47 //associated documentation or information are expressly subject
    48 //to the terms and conditions of the Altera Program License
    49 //Subscription Agreement, Altera MegaCore Function License
    50 //Agreement, or other applicable license agreement, including,
    51 //without limitation, that your use is for the sole purpose of
    52 //programming logic devices manufactured by Altera and sold by
    53 //Altera or its authorized distributors. Please refer to the
    54 //applicable agreement for further details.
    55
    56
    57 // synopsys translate_off
    58 `timescale 1 ps / 1 ps
    59 // synopsys translate_on
    60 module ramlpm (
    61 address,
    62 clock,
    63 data,
    64 wren,
    65 q);
    66
    67 input [4:0] address;
    68 input clock;
    69 input [7:0] data;
    70 input wren;
    71 output [7:0] q;
    72
    73 wire [7:0] sub_wire0;
    74 wire [7:0] q = sub_wire0[7:0];
    75
    76 altsyncram altsyncram_component (
    77 .wren_a (wren),
    78 .clock0 (clock),
    79 .address_a (address),
    80 .data_a (data),
    81 .q_a (sub_wire0),
    82 .aclr0 (1'b0),
    83 .aclr1 (1'b0),
    84 .address_b (1'b1),
    85 .addressstall_a (1'b0),
    86 .addressstall_b (1'b0),
    87 .byteena_a (1'b1),
    88 .byteena_b (1'b1),
    89 .clock1 (1'b1),
    90 .clocken0 (1'b1),
    91 .clocken1 (1'b1),
    92 .clocken2 (1'b1),
    93 .clocken3 (1'b1),
    94 .data_b (1'b1),
    95 .eccstatus (),
    96 .q_b (),
    97 .rden_a (1'b1),
    98 .rden_b (1'b1),
    99 .wren_b (1'b0));
    100 defparam
    101 altsyncram_component.clock_enable_input_a = "BYPASS",
    102 altsyncram_component.clock_enable_output_a = "BYPASS",
    103 altsyncram_component.intended_device_family = "Cyclone II",
    104 altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO",
    105 altsyncram_component.lpm_type = "altsyncram",
    106 altsyncram_component.numwords_a = 32,
    107 altsyncram_component.operation_mode = "SINGLE_PORT",
    108 altsyncram_component.outdata_aclr_a = "NONE",
    109 altsyncram_component.outdata_reg_a = "UNREGISTERED",
    110 altsyncram_component.power_up_uninitialized = "FALSE",
    111 altsyncram_component.ram_block_type = "M4K",
    112 altsyncram_component.widthad_a = 5,
    113 altsyncram_component.width_a = 8,
    114 altsyncram_component.width_byteena_a = 1;
    115
    116
    117 endmodule
    118
    119 // ============================================================
    120 // CNX file retrieval info
    121 // ============================================================
    122 // Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
    123 // Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
    124 // Retrieval info: PRIVATE: AclrByte NUMERIC "0"
    125 // Retrieval info: PRIVATE: AclrData NUMERIC "0"
    126 // Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
    127 // Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
    128 // Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
    129 // Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
    130 // Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
    131 // Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
    132 // Retrieval info: PRIVATE: Clken NUMERIC "0"
    133 // Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1"
    134 // Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
    135 // Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
    136 // Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
    137 // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
    138 // Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
    139 // Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
    140 // Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
    141 // Retrieval info: PRIVATE: MIFfilename STRING ""
    142 // Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "32"
    143 // Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "2"
    144 // Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
    145 // Retrieval info: PRIVATE: RegAddr NUMERIC "1"
    146 // Retrieval info: PRIVATE: RegData NUMERIC "1"
    147 // Retrieval info: PRIVATE: RegOutput NUMERIC "0"
    148 // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
    149 // Retrieval info: PRIVATE: SingleClock NUMERIC "1"
    150 // Retrieval info: PRIVATE: UseDQRAM NUMERIC "1"
    151 // Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0"
    152 // Retrieval info: PRIVATE: WidthAddr NUMERIC "5"
    153 // Retrieval info: PRIVATE: WidthData NUMERIC "8"
    154 // Retrieval info: PRIVATE: rden NUMERIC "0"
    155 // Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
    156 // Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
    157 // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
    158 // Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
    159 // Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
    160 // Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "32"
    161 // Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT"
    162 // Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
    163 // Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
    164 // Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
    165 // Retrieval info: CONSTANT: RAM_BLOCK_TYPE STRING "M4K"
    166 // Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "5"
    167 // Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
    168 // Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
    169 // Retrieval info: USED_PORT: address 0 0 5 0 INPUT NODEFVAL address[4..0]
    170 // Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
    171 // Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL data[7..0]
    172 // Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0]
    173 // Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL wren
    174 // Retrieval info: CONNECT: @address_a 0 0 5 0 address 0 0 5 0
    175 // Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
    176 // Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
    177 // Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0
    178 // Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
    179 // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
    180 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm.v TRUE
    181 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm.inc FALSE
    182 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm.cmp FALSE
    183 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm.bsf FALSE
    184 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm_inst.v FALSE
    185 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm_bb.v FALSE
    186 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm_waveforms.html TRUE
    187 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm_wave*.jpg FALSE
    188 // Retrieval info: LIB_FILE: altera_mf

    Part II 验证part I的RAM

     

        本练习验证part I的RAM,即在DE2上用拨动开关写一部分数据到RAM,并读出,显示在数码管上。

    代码part II:

    1 //part 2 在DE2上验证Part的设计
    2 //引脚说明:
    3 // input: SW7-0 --DataIn SW15-11--Address SW17--Write KEY0--Clock
    4 // output : HEX7-6--Address HEX5-4--DataIn HEX1-0--DataOut LEDG0--Write
    5
    6 module part2(
    7 input [17:0] SW,
    8 input [0:0] KEY,
    9 output [0:0] LEDG,
    10 output [0:6] HEX7,HEX6,HEX5,HEX4,HEX1,HEX0
    11 );
    12
    13 wire [7:0] DataOut;
    14
    15 ramlpm u0(
    16 .address(SW[15:11]),
    17 .clock(KEY),
    18 .data(SW[7:0]),
    19 .wren(SW[17]),
    20 .q(DataOut[7:0])
    21 );
    22
    23 assign LEDG=SW[17]; //Write的标记
    24
    25 //调用7-seg显示模块
    26 seg_lut h5(HEX5,SW[7:4]);
    27 seg_lut h4(HEX4,SW[3:0]);
    28
    29 seg_lut h7(HEX7,{{3{1'b0}},SW[15]});
    30 seg_lut h6(HEX6,SW[14:11]);
    31
    32 seg_lut h1(HEX1,DataOut[7:4]);
    33 seg_lut h0(HEX0,DataOut[3:0]);
    34
    35 endmodule
    36
    37 //7-seg
    38
    39 module seg_lut(oseg,idig);
    40 input [3:0] idig;
    41 output reg [0:6] oseg;
    42
    43 always @(idig)
    44 case(idig)
    45 4'h1: oseg=7'b100_1111; // --------0--------
    46 4'h2: oseg=7'b001_0010; // | |
    47 4'h3: oseg=7'b000_0110; // | | 1
    48 4'h4: oseg=7'b100_1100; // | 5 |
    49 4'h5: oseg=7'b010_0100; // | |
    50 4'h6: oseg=7'b010_0000; // --------6--------
    51 4'h7: oseg=7'b000_1111; // | |
    52 4'h8: oseg=7'b000_0000; // | |
    53 4'h9: oseg=7'b000_1100; // | 4 | 2
    54 4'hA: oseg=7'b000_1000; // | |
    55 4'hb: oseg=7'b110_0000; // --------3---------
    56 4'hC: oseg=7'b011_0001;
    57 4'hd: oseg=7'b100_0010;
    58 4'hE: oseg=7'b011_0000;
    59 4'hF: oseg=7'b011_1000;
    60 default: oseg=7'b111_1111;
    61 endcase
    62
    63 endmodule
    64

    Part III 自己编写RAM

     

        用多维数组定义存储器。32X8-bit的RAM可以定义为32X8的数组,如:

        reg [7:0] memory_array [31:0];

        对于Cyclone II系列的FPGA,实现这种数组可用触发器或M4K存储器块。确保使用M4K实现有两种方法:一是调用LPM库,二是用适当形式的Verilog代码定义RAM,这部分可查阅Quartus II 的帮助,搜索“Inferred memory”。

    代码part 3:

    1 module part3(
    2 input [17:0] SW,
    3 input [0:0] KEY,
    4 output [0:0] LEDG,
    5 output [0:6] HEX7,HEX6,HEX5,HEX4,HEX1,HEX0
    6 );
    7
    8 wire [7:0] DataOut;
    9
    10 ram_single u0(
    11 .a(SW[15:11]),
    12 .clk(KEY),
    13 .d(SW[7:0]),
    14 .we(SW[17]),
    15 .q(DataOut[7:0])
    16 );
    17
    18 assign LEDG=SW[17]; //Write的标记
    19
    20 //调用7-seg显示模块
    21 seg_lut h5(HEX5,SW[7:4]);
    22 seg_lut h4(HEX4,SW[3:0]);
    23
    24 seg_lut h7(HEX7,{{3{1'b0}},SW[15]});
    25 seg_lut h6(HEX6,SW[14:11]);
    26
    27 seg_lut h1(HEX1,DataOut[7:4]);
    28 seg_lut h0(HEX0,DataOut[3:0]);
    29
    30 endmodule
    31
    32 //7-seg
    33
    34 module seg_lut(oseg,idig);
    35 input [3:0] idig;
    36 output reg [0:6] oseg;
    37
    38 always @(idig)
    39 case(idig)
    40 4'h1: oseg=7'b100_1111; // --------0--------
    41 4'h2: oseg=7'b001_0010; // | |
    42 4'h3: oseg=7'b000_0110; // | | 1
    43 4'h4: oseg=7'b100_1100; // | 5 |
    44 4'h5: oseg=7'b010_0100; // | |
    45 4'h6: oseg=7'b010_0000; // --------6--------
    46 4'h7: oseg=7'b000_1111; // | |
    47 4'h8: oseg=7'b000_0000; // | |
    48 4'h9: oseg=7'b000_1100; // | 4 | 2
    49 4'hA: oseg=7'b000_1000; // | |
    50 4'hb: oseg=7'b110_0000; // --------3---------
    51 4'hC: oseg=7'b011_0001;
    52 4'hd: oseg=7'b100_0010;
    53 4'hE: oseg=7'b011_0000;
    54 4'hF: oseg=7'b011_1000;
    55 default: oseg=7'b111_1111;
    56 endcase
    57
    58 endmodule
    59
    60 //32*8 bit RAM
    61
    62 module ram_single(q,a,d,we,clk);
    63 output reg [7:0] q;
    64 input [7:0] d;
    65 input [4:0] a;
    66 input we,clk;
    67
    68 reg [7:0] mem [31:0] ;
    69
    70 always @(posedge clk)
    71 begin
    72 if(we)
    73 mem[a]<=d;
    74 q<=mem[a];
    75 end
    76
    77 endmodule

    RAM Summary

    clip_image002[5]

    与part 2的区别,读出RAM的数据慢一个时钟。

    Part IV 使用SRAM

        本练习使用DE2上的SRAM—IS61LV25616AL-10.其参数可查看数据手册。为简化设计,控制端口除WE外,都缺省有效,即赋0值。

    代码part 4:

    1 //练习SRAM的读/写功能,通过FPGA控制SRAM
    2 //引脚说明:
    3 //---------------------------------------------------------
    4 // SW[17] write
    5 // SW[15:11] address
    6 // SW[7:0] datain
    7 // KEY[1] rst_n
    8 // KEY[0] clk
    9
    10 module part4(
    11 input [17:0] SW,
    12 input [1:0] KEY, //rst_n,clk
    13 output [0:0] LEDG,
    14 output [0:6] HEX7,HEX6,HEX5,HEX4,HEX1,HEX0,
    15
    16 //SRAM pors
    17 output [17:0] SRAM_ADDR, //address
    18 inout [15:0] SRAM_DQ, //datain , dataout
    19 output SRAM_CE_N, //chip enable
    20 SRAM_OE_N, //output enable
    21 SRAM_WE_N, //write enable
    22 SRAM_UB_N, //upper byte
    23 SRAM_LB_N //lower byte
    24 );
    25
    26 wire [7:0] DataOut,DataIn;
    27 wire [4:0] address;
    28 wire [15:0] DataIn_reg;
    29 wire clk,rst_n,write,ce_n;
    30
    31 assign clk=KEY[0];
    32 assign rst_n=KEY[1];
    33
    34 assign write=SW[17];
    35 regne #(.n(1) ) r0(write,clk,rst_n,1'b1,SRAM_WE_N); //同步write
    36
    37 assign address=SW[15:11];
    38 regne #(.n(5)) r1(address,clk,rst_n,1'b1,SRAM_ADDR[4:0]); //同步address
    39 assign SRAM_ADDR[17:5]=13'b0;
    40
    41 assign DataIn=SW[7:0];
    42 regne #(.n(8)) r2(DataIn,clk,rst_n,1'b1,DataIn_reg[7:0]); //同步DataIn
    43 assign DataIn_reg[15:8]=8'b0;
    44
    45 assign SRAM_DQ=(SRAM_WE_N==0)?DataIn_reg:16'bz;
    46
    47 assign DataOut=SRAM_DQ[7:0];
    48
    49 regne #(.n(1)) r3(1'b1,clk,rst_n,1'b1,ce_n); //CE初始化,上电为无效,避免写入
    50 assign SRAM_CE_N=~ce_n;
    51
    52 assign
    53 SRAM_OE_N=1'b0,
    54 SRAM_UB_N=1'b0,
    55 SRAM_LB_N=1'b0;
    56
    57 assign LEDG=SW[17]; //Write的标记
    58
    59 //调用7-seg显示模块
    60 seg_lut h5(HEX5,DataIn[7:4]); //DataIn
    61 seg_lut h4(HEX4,DataIn[3:0]);
    62
    63 seg_lut h7(HEX7,{{3{1'b0}},address[4]}); //address
    64 seg_lut h6(HEX6,address[3:0]);
    65
    66 seg_lut h1(HEX1,DataOut[7:4]); //DataOut
    67 seg_lut h0(HEX0,DataOut[3:0]);
    68
    69 endmodule
    70
    71 //7-seg
    72
    73 module seg_lut(oseg,idig);
    74 input [3:0] idig;
    75 output reg [0:6] oseg;
    76
    77 always @(idig)
    78 case(idig)
    79 4'h0: oseg=7'b000_0001;
    80 4'h1: oseg=7'b100_1111; // --------0--------
    81 4'h2: oseg=7'b001_0010; // | |
    82 4'h3: oseg=7'b000_0110; // | | 1
    83 4'h4: oseg=7'b100_1100; // | 5 |
    84 4'h5: oseg=7'b010_0100; // | |
    85 4'h6: oseg=7'b010_0000; // --------6--------
    86 4'h7: oseg=7'b000_1111; // | |
    87 4'h8: oseg=7'b000_0000; // | |
    88 4'h9: oseg=7'b000_1100; // | 4 | 2
    89 4'hA: oseg=7'b000_1000; // | |
    90 4'hb: oseg=7'b110_0000; // --------3---------
    91 4'hC: oseg=7'b011_0001;
    92 4'hd: oseg=7'b100_0010;
    93 4'hE: oseg=7'b011_0000;
    94 4'hF: oseg=7'b011_1000;
    95 default: oseg=7'b111_1111;
    96 endcase
    97
    98 endmodule
    99
    100 //register 用来同步输入信号
    101
    102 module regne(r,clk,rst_n,e,q);
    103 parameter n=7;
    104 input [n-1:0] r;
    105 input clk,rst_n,e;
    106 output reg [n-1:0] q;
    107
    108 always @(posedge clk)
    109 begin
    110 if(rst_n==0)
    111 q<={n{1'b0}};
    112 else if(e)
    113 q<=r;
    114 end
    115
    116 endmodule
    117

    Part V 用LPM创建双口RAM

        所谓双口,即读/写的地址端口分开,即选择Simple dual-port mode。本练习可对存储器初始化,建立一个mif文件。最终在数码管上实现循环显示RAM的数据和地址,间隔为1s。

    代码part 5:

    1 //part 5
    2 // 创建一个读写分开控制的RAM,要求上电后,读地址和其对应的数据以1s的间隔
    3 //循环显示在HEX3-2和HEX1-0上,通过写地址和写控制,可以随时修改对应地址
    4 //的内容。RAM用mif文件初始化。
    5
    6 //引脚说明:
    7 //-------------------------------------------------------------------
    8 // SW[17] write_en
    9 // SW[15:11] address
    10 // SW[7:0] datain
    11 // LEDG0 write
    12 // HEX7-6 address
    13 // HEX5-4 datain
    14 // HEX3-2 read_address
    15 // HEX1-0 dataout
    16 // KEY0 rst_n
    17 // CLOCK_50 clk
    18
    19 module part5(
    20 input CLOCK_50,
    21 input [0:0] KEY,
    22 input [17:0] SW,
    23 output [0:6] HEX7,HEX6,HEX5,HEX4,HEX3,HEX2,HEX1,HEX0,
    24 output [0:0] LEDG
    25 );
    26
    27 wire clk,rst_n,write,write_sync;
    28 wire [4:0] write_address,write_address_sync;
    29 wire [7:0] datain,datain_sync,dataout;
    30
    31 assign rst_n=KEY[0];
    32 assign clk=CLOCK_50;
    33
    34 //同步输入信号
    35
    36 regne #(.n(1)) r0(SW[17],clk,rst_n,1'b1,write_sync);
    37 regne #(.n(1)) r1(write_sync,clk,rst_n,1'b1,write);
    38
    39 regne #(.n(5)) r2(SW[15:11],clk,rst_n,1'b1,write_address_sync);
    40 regne #(.n(5)) r3(write_address_sync,clk,rst_n,1'b1,write_address);
    41
    42 regne #(.n(8)) r4(SW[7:0],clk,rst_n,1'b1,datain_sync);
    43 regne #(.n(8)) r5(datain_sync,clk,rst_n,1'b1,datain);
    44
    45 //分频,产生约1s的时钟
    46
    47 parameter m=26; //(2^26-1)*20*10^(-9)=1.3s
    48 reg [m-1:0] div_count;
    49 reg [4:0] read_address; //0-31
    50
    51 //寻址计数
    52
    53 always @(posedge clk)
    54 div_count<=div_count+1'b1;
    55 always @(posedge clk)
    56 if(!rst_n)
    57 read_address<=5'b0;
    58 else if(div_count==0) //每过约1s
    59 read_address<=read_address+1'b1;
    60
    61 //引用LPM
    62 ramlpm u0(
    63 .clock(clk),
    64 .data(datain),
    65 .rdaddress(read_address),
    66 .wraddress(write_address),
    67 .wren(write),
    68 .q(dataout)
    69 );
    70
    71
    72 assign LEDG=write; //Write的标记
    73
    74 //调用7-seg显示模块
    75 seg_lut h5(HEX5,datain[7:4]); //DataIn
    76 seg_lut h4(HEX4,datain[3:0]);
    77
    78 seg_lut h7(HEX7,{{3{1'b0}},write_address[4]}); //address
    79 seg_lut h6(HEX6,write_address[3:0]);
    80
    81 seg_lut h1(HEX1,dataout[7:4]); //DataOut
    82 seg_lut h0(HEX0,dataout[3:0]);
    83
    84 seg_lut h3(HEX3,{{3{1'b0}},read_address[4]}); //address
    85 seg_lut h2(HEX2,read_address[3:0]);
    86
    87 endmodule
    88
    89 //7-seg
    90
    91 module seg_lut(oseg,idig);
    92 input [3:0] idig;
    93 output reg [0:6] oseg;
    94
    95 always @(idig)
    96 case(idig)
    97 4'h0: oseg=7'b000_0001;
    98 4'h1: oseg=7'b100_1111; // --------0--------
    99 4'h2: oseg=7'b001_0010; // | |
    100 4'h3: oseg=7'b000_0110; // | | 1
    101 4'h4: oseg=7'b100_1100; // | 5 |
    102 4'h5: oseg=7'b010_0100; // | |
    103 4'h6: oseg=7'b010_0000; // --------6--------
    104 4'h7: oseg=7'b000_1111; // | |
    105 4'h8: oseg=7'b000_0000; // | |
    106 4'h9: oseg=7'b000_1100; // | 4 | 2
    107 4'hA: oseg=7'b000_1000; // | |
    108 4'hb: oseg=7'b110_0000; // --------3---------
    109 4'hC: oseg=7'b011_0001;
    110 4'hd: oseg=7'b100_0010;
    111 4'hE: oseg=7'b011_0000;
    112 4'hF: oseg=7'b011_1000;
    113 default: oseg=7'b111_1111;
    114 endcase
    115
    116 endmodule
    117
    118 //register 用来同步输入信号
    119
    120 module regne(r,clk,rst_n,e,q);
    121 parameter n=7;
    122 input [n-1:0] r;
    123 input clk,rst_n,e;
    124 output reg [n-1:0] q;
    125
    126 always @(posedge clk)
    127 begin
    128 if(rst_n==0)
    129 q<={n{1'b0}};
    130 else if(e)
    131 q<=r;
    132 end
    133
    134 endmodule
    135
    136
    137

    View Code
    1 // megafunction wizard: %RAM: 2-PORT%
    2 // GENERATION: STANDARD
    3 // VERSION: WM1.0
    4 // MODULE: altsyncram
    5
    6 // ============================================================
    7 // File Name: ramlpm.v
    8 // Megafunction Name(s):
    9 // altsyncram
    10 //
    11 // Simulation Library Files(s):
    12 // altera_mf
    13 // ============================================================
    14 // ************************************************************
    15 // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
    16 //
    17 // 9.1 Build 222 10/21/2009 SJ Full Version
    18 // ************************************************************
    19
    20
    21 //Copyright (C) 1991-2009 Altera Corporation
    22 //Your use of Altera Corporation's design tools, logic functions
    23 //and other software and tools, and its AMPP partner logic
    24 //functions, and any output files from any of the foregoing
    25 //(including device programming or simulation files), and any
    26 //associated documentation or information are expressly subject
    27 //to the terms and conditions of the Altera Program License
    28 //Subscription Agreement, Altera MegaCore Function License
    29 //Agreement, or other applicable license agreement, including,
    30 //without limitation, that your use is for the sole purpose of
    31 //programming logic devices manufactured by Altera and sold by
    32 //Altera or its authorized distributors. Please refer to the
    33 //applicable agreement for further details.
    34
    35
    36 // synopsys translate_off
    37 `timescale 1 ps / 1 ps
    38 // synopsys translate_on
    39 module ramlpm (
    40 clock,
    41 data,
    42 rdaddress,
    43 wraddress,
    44 wren,
    45 q);
    46
    47 input clock;
    48 input [7:0] data;
    49 input [4:0] rdaddress;
    50 input [4:0] wraddress;
    51 input wren;
    52 output [7:0] q;
    53 `ifndef ALTERA_RESERVED_QIS
    54 // synopsys translate_off
    55 `endif
    56 tri1 wren;
    57 `ifndef ALTERA_RESERVED_QIS
    58 // synopsys translate_on
    59 `endif
    60
    61 wire [7:0] sub_wire0;
    62 wire [7:0] q = sub_wire0[7:0];
    63
    64 altsyncram altsyncram_component (
    65 .wren_a (wren),
    66 .clock0 (clock),
    67 .address_a (wraddress),
    68 .address_b (rdaddress),
    69 .data_a (data),
    70 .q_b (sub_wire0),
    71 .aclr0 (1'b0),
    72 .aclr1 (1'b0),
    73 .addressstall_a (1'b0),
    74 .addressstall_b (1'b0),
    75 .byteena_a (1'b1),
    76 .byteena_b (1'b1),
    77 .clock1 (1'b1),
    78 .clocken0 (1'b1),
    79 .clocken1 (1'b1),
    80 .clocken2 (1'b1),
    81 .clocken3 (1'b1),
    82 .data_b ({8{1'b1}}),
    83 .eccstatus (),
    84 .q_a (),
    85 .rden_a (1'b1),
    86 .rden_b (1'b1),
    87 .wren_b (1'b0));
    88 defparam
    89 altsyncram_component.address_reg_b = "CLOCK0",
    90 altsyncram_component.clock_enable_input_a = "BYPASS",
    91 altsyncram_component.clock_enable_input_b = "BYPASS",
    92 altsyncram_component.clock_enable_output_a = "BYPASS",
    93 altsyncram_component.clock_enable_output_b = "BYPASS",
    94 altsyncram_component.init_file = "ramlpm.mif",
    95 altsyncram_component.intended_device_family = "Cyclone II",
    96 altsyncram_component.lpm_type = "altsyncram",
    97 altsyncram_component.numwords_a = 32,
    98 altsyncram_component.numwords_b = 32,
    99 altsyncram_component.operation_mode = "DUAL_PORT",
    100 altsyncram_component.outdata_aclr_b = "NONE",
    101 altsyncram_component.outdata_reg_b = "UNREGISTERED",
    102 altsyncram_component.power_up_uninitialized = "FALSE",
    103 altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",
    104 altsyncram_component.widthad_a = 5,
    105 altsyncram_component.widthad_b = 5,
    106 altsyncram_component.width_a = 8,
    107 altsyncram_component.width_b = 8,
    108 altsyncram_component.width_byteena_a = 1;
    109
    110
    111 endmodule
    112
    113 // ============================================================
    114 // CNX file retrieval info
    115 // ============================================================
    116 // Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
    117 // Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
    118 // Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
    119 // Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
    120 // Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
    121 // Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
    122 // Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
    123 // Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
    124 // Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
    125 // Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
    126 // Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
    127 // Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
    128 // Retrieval info: PRIVATE: CLRdata NUMERIC "0"
    129 // Retrieval info: PRIVATE: CLRq NUMERIC "0"
    130 // Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
    131 // Retrieval info: PRIVATE: CLRrren NUMERIC "0"
    132 // Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
    133 // Retrieval info: PRIVATE: CLRwren NUMERIC "0"
    134 // Retrieval info: PRIVATE: Clock NUMERIC "0"
    135 // Retrieval info: PRIVATE: Clock_A NUMERIC "0"
    136 // Retrieval info: PRIVATE: Clock_B NUMERIC "0"
    137 // Retrieval info: PRIVATE: ECC NUMERIC "0"
    138 // Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
    139 // Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
    140 // Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0"
    141 // Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B"
    142 // Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
    143 // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
    144 // Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
    145 // Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
    146 // Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
    147 // Retrieval info: PRIVATE: MEMSIZE NUMERIC "256"
    148 // Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
    149 // Retrieval info: PRIVATE: MIFfilename STRING "ramlpm.mif"
    150 // Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2"
    151 // Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
    152 // Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0"
    153 // Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
    154 // Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
    155 // Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "4"
    156 // Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "4"
    157 // Retrieval info: PRIVATE: REGdata NUMERIC "1"
    158 // Retrieval info: PRIVATE: REGq NUMERIC "1"
    159 // Retrieval info: PRIVATE: REGrdaddress NUMERIC "1"
    160 // Retrieval info: PRIVATE: REGrren NUMERIC "1"
    161 // Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
    162 // Retrieval info: PRIVATE: REGwren NUMERIC "1"
    163 // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
    164 // Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
    165 // Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
    166 // Retrieval info: PRIVATE: VarWidth NUMERIC "0"
    167 // Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8"
    168 // Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "8"
    169 // Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8"
    170 // Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "8"
    171 // Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
    172 // Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0"
    173 // Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
    174 // Retrieval info: PRIVATE: enable NUMERIC "0"
    175 // Retrieval info: PRIVATE: rden NUMERIC "0"
    176 // Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0"
    177 // Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
    178 // Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
    179 // Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
    180 // Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
    181 // Retrieval info: CONSTANT: INIT_FILE STRING "ramlpm.mif"
    182 // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
    183 // Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
    184 // Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "32"
    185 // Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "32"
    186 // Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT"
    187 // Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
    188 // Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED"
    189 // Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
    190 // Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE"
    191 // Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "5"
    192 // Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "5"
    193 // Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
    194 // Retrieval info: CONSTANT: WIDTH_B NUMERIC "8"
    195 // Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
    196 // Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
    197 // Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL data[7..0]
    198 // Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0]
    199 // Retrieval info: USED_PORT: rdaddress 0 0 5 0 INPUT NODEFVAL rdaddress[4..0]
    200 // Retrieval info: USED_PORT: wraddress 0 0 5 0 INPUT NODEFVAL wraddress[4..0]
    201 // Retrieval info: USED_PORT: wren 0 0 0 0 INPUT VCC wren
    202 // Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0
    203 // Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
    204 // Retrieval info: CONNECT: q 0 0 8 0 @q_b 0 0 8 0
    205 // Retrieval info: CONNECT: @address_a 0 0 5 0 wraddress 0 0 5 0
    206 // Retrieval info: CONNECT: @address_b 0 0 5 0 rdaddress 0 0 5 0
    207 // Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
    208 // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
    209 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm.v TRUE
    210 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm.inc FALSE
    211 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm.cmp FALSE
    212 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm.bsf FALSE
    213 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm_inst.v FALSE
    214 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm_bb.v FALSE
    215 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm_waveforms.html TRUE
    216 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm_wave*.jpg FALSE
    217 // Retrieval info: LIB_FILE: altera_mf

    Part VI 单口复用RAM

        修改Part V的RAM,用多路器实现一个地址端口复用。在LPM里选择Allow In-system Memory Content Editor to capture and update content independently of the system clock。存储器ID设为32X8.

        调用这个RAM模块,实现与Part 5同样的功能。

        在使用In-System Memory Content Editor之前,需要设置参数。Assignment / setting / Analysis & Synthesis Setting / Defualt Parameters 添加一个参数CYCLONEII_SAFE_WRITE, 值为RESTRUCTURE。

        编译、测试。与Part 5的结果比较。

        Tools / In-System Memory Content Editor读取和修改RAM的内容,并与数码管的显示比较。

    代码part 6;

    1 //part 6 单端口的RAM,读写共用地址总线。练习In-system memory content editor
    2 ///引脚说明:
    3 //-------------------------------------------------------------------
    4 // SW[17] write_en
    5 // SW[15:11] address
    6 // SW[7:0] datain
    7 // LEDG0 write
    8 // HEX7-6 address
    9 // HEX5-4 datain
    10 // HEX3-2 read_address
    11 // HEX1-0 dataout
    12 // KEY0 rst_n
    13 // CLOCK_50 clk
    14
    15 module part6(
    16 input CLOCK_50,
    17 input [0:0] KEY,
    18 input [17:0] SW,
    19 output [0:6] HEX7,HEX6,HEX5,HEX4,HEX3,HEX2,HEX1,HEX0,
    20 output [0:0] LEDG
    21 );
    22
    23 wire clk,rst_n,write,write_sync;
    24 wire [4:0] write_address,write_address_sync;
    25 wire [7:0] datain,datain_sync,dataout;
    26
    27 assign rst_n=KEY[0];
    28 assign clk=CLOCK_50;
    29
    30 //同步输入信号
    31
    32 regne #(.n(1)) r0(SW[17],clk,rst_n,1'b1,write_sync);
    33 regne #(.n(1)) r1(write_sync,clk,rst_n,1'b1,write);
    34
    35 regne #(.n(5)) r2(SW[15:11],clk,rst_n,1'b1,write_address_sync);
    36 regne #(.n(5)) r3(write_address_sync,clk,rst_n,1'b1,write_address);
    37
    38 regne #(.n(8)) r4(SW[7:0],clk,rst_n,1'b1,datain_sync);
    39 regne #(.n(8)) r5(datain_sync,clk,rst_n,1'b1,datain);
    40
    41 //分频,产生约1s的时钟
    42
    43 parameter m=26; //(2^26-1)*20*10^(-9)=1.3s
    44 reg [m-1:0] div_count;
    45 reg [4:0] read_address; //0-31
    46
    47 //寻址计数
    48
    49 always @(posedge clk)
    50 div_count<=div_count+1'b1;
    51 always @(posedge clk)
    52 if(!rst_n)
    53 read_address<=5'b0;
    54 else if(div_count==0) //每过约1s
    55 read_address<=read_address+1'b1;
    56
    57 //用multiplexer决定地址
    58 wire [4:0] address;
    59 assign address=(write==1'b1)?write_address:read_address;
    60
    61 //引用LPM
    62 ramlpm u0(
    63 .clock(clk),
    64 .data(datain),
    65 .address(address),
    66 .wren(write),
    67 .q(dataout)
    68 );
    69
    70
    71 assign LEDG=write; //Write的标记
    72
    73 //调用7-seg显示模块
    74 seg_lut h5(HEX5,datain[7:4]); //DataIn
    75 seg_lut h4(HEX4,datain[3:0]);
    76
    77 seg_lut h7(HEX7,{{3{1'b0}},write_address[4]}); //address
    78 seg_lut h6(HEX6,write_address[3:0]);
    79
    80 seg_lut h1(HEX1,dataout[7:4]); //DataOut
    81 seg_lut h0(HEX0,dataout[3:0]);
    82
    83 seg_lut h3(HEX3,{{3{1'b0}},read_address[4]}); //address
    84 seg_lut h2(HEX2,read_address[3:0]);
    85
    86 endmodule
    87
    88 //7-seg
    89
    90 module seg_lut(oseg,idig);
    91 input [3:0] idig;
    92 output reg [0:6] oseg;
    93
    94 always @(idig)
    95 case(idig)
    96 4'h0: oseg=7'b000_0001;
    97 4'h1: oseg=7'b100_1111; // --------0--------
    98 4'h2: oseg=7'b001_0010; // | |
    99 4'h3: oseg=7'b000_0110; // | | 1
    100 4'h4: oseg=7'b100_1100; // | 5 |
    101 4'h5: oseg=7'b010_0100; // | |
    102 4'h6: oseg=7'b010_0000; // --------6--------
    103 4'h7: oseg=7'b000_1111; // | |
    104 4'h8: oseg=7'b000_0000; // | |
    105 4'h9: oseg=7'b000_1100; // | 4 | 2
    106 4'hA: oseg=7'b000_1000; // | |
    107 4'hb: oseg=7'b110_0000; // --------3---------
    108 4'hC: oseg=7'b011_0001;
    109 4'hd: oseg=7'b100_0010;
    110 4'hE: oseg=7'b011_0000;
    111 4'hF: oseg=7'b011_1000;
    112 default: oseg=7'b111_1111;
    113 endcase
    114
    115 endmodule
    116
    117 //register 用来同步输入信号
    118
    119 module regne(r,clk,rst_n,e,q);
    120 parameter n=7;
    121 input [n-1:0] r;
    122 input clk,rst_n,e;
    123 output reg [n-1:0] q;
    124
    125 always @(posedge clk)
    126 begin
    127 if(rst_n==0)
    128 q<={n{1'b0}};
    129 else if(e)
    130 q<=r;
    131 end
    132
    133 endmodule

    ramlpm.v
    1 // megafunction wizard: %RAM: 1-PORT%
    2 // GENERATION: STANDARD
    3 // VERSION: WM1.0
    4 // MODULE: altsyncram
    5
    6 // ============================================================
    7 // File Name: ramlpm.v
    8 // Megafunction Name(s):
    9 // altsyncram
    10 //
    11 // Simulation Library Files(s):
    12 // altera_mf
    13 // ============================================================
    14 // ************************************************************
    15 // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
    16 //
    17 // 9.1 Build 222 10/21/2009 SJ Full Version
    18 // ************************************************************
    19
    20
    21 //Copyright (C) 1991-2009 Altera Corporation
    22 //Your use of Altera Corporation's design tools, logic functions
    23 //and other software and tools, and its AMPP partner logic
    24 //functions, and any output files from any of the foregoing
    25 //(including device programming or simulation files), and any
    26 //associated documentation or information are expressly subject
    27 //to the terms and conditions of the Altera Program License
    28 //Subscription Agreement, Altera MegaCore Function License
    29 //Agreement, or other applicable license agreement, including,
    30 //without limitation, that your use is for the sole purpose of
    31 //programming logic devices manufactured by Altera and sold by
    32 //Altera or its authorized distributors. Please refer to the
    33 //applicable agreement for further details.
    34
    35
    36 // synopsys translate_off
    37 `timescale 1 ps / 1 ps
    38 // synopsys translate_on
    39 module ramlpm (
    40 address,
    41 clock,
    42 data,
    43 wren,
    44 q);
    45
    46 input [4:0] address;
    47 input clock;
    48 input [7:0] data;
    49 input wren;
    50 output [7:0] q;
    51
    52 wire [7:0] sub_wire0;
    53 wire [7:0] q = sub_wire0[7:0];
    54
    55 altsyncram altsyncram_component (
    56 .wren_a (wren),
    57 .clock0 (clock),
    58 .address_a (address),
    59 .data_a (data),
    60 .q_a (sub_wire0),
    61 .aclr0 (1'b0),
    62 .aclr1 (1'b0),
    63 .address_b (1'b1),
    64 .addressstall_a (1'b0),
    65 .addressstall_b (1'b0),
    66 .byteena_a (1'b1),
    67 .byteena_b (1'b1),
    68 .clock1 (1'b1),
    69 .clocken0 (1'b1),
    70 .clocken1 (1'b1),
    71 .clocken2 (1'b1),
    72 .clocken3 (1'b1),
    73 .data_b (1'b1),
    74 .eccstatus (),
    75 .q_b (),
    76 .rden_a (1'b1),
    77 .rden_b (1'b1),
    78 .wren_b (1'b0));
    79 defparam
    80 altsyncram_component.clock_enable_input_a = "BYPASS",
    81 altsyncram_component.clock_enable_output_a = "BYPASS",
    82 altsyncram_component.init_file = "../part5/ramlpm.mif",
    83 altsyncram_component.intended_device_family = "Cyclone II",
    84 altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME=32x8",
    85 altsyncram_component.lpm_type = "altsyncram",
    86 altsyncram_component.numwords_a = 32,
    87 altsyncram_component.operation_mode = "SINGLE_PORT",
    88 altsyncram_component.outdata_aclr_a = "NONE",
    89 altsyncram_component.outdata_reg_a = "UNREGISTERED",
    90 altsyncram_component.power_up_uninitialized = "FALSE",
    91 altsyncram_component.ram_block_type = "M4K",
    92 altsyncram_component.widthad_a = 5,
    93 altsyncram_component.width_a = 8,
    94 altsyncram_component.width_byteena_a = 1;
    95
    96
    97 endmodule
    98
    99 // ============================================================
    100 // CNX file retrieval info
    101 // ============================================================
    102 // Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
    103 // Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
    104 // Retrieval info: PRIVATE: AclrByte NUMERIC "0"
    105 // Retrieval info: PRIVATE: AclrData NUMERIC "0"
    106 // Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
    107 // Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
    108 // Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
    109 // Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
    110 // Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
    111 // Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
    112 // Retrieval info: PRIVATE: Clken NUMERIC "0"
    113 // Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1"
    114 // Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
    115 // Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
    116 // Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
    117 // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
    118 // Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "1"
    119 // Retrieval info: PRIVATE: JTAG_ID STRING "32x8"
    120 // Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
    121 // Retrieval info: PRIVATE: MIFfilename STRING "../part5/ramlpm.mif"
    122 // Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "32"
    123 // Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "2"
    124 // Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
    125 // Retrieval info: PRIVATE: RegAddr NUMERIC "1"
    126 // Retrieval info: PRIVATE: RegData NUMERIC "1"
    127 // Retrieval info: PRIVATE: RegOutput NUMERIC "0"
    128 // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
    129 // Retrieval info: PRIVATE: SingleClock NUMERIC "1"
    130 // Retrieval info: PRIVATE: UseDQRAM NUMERIC "1"
    131 // Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0"
    132 // Retrieval info: PRIVATE: WidthAddr NUMERIC "5"
    133 // Retrieval info: PRIVATE: WidthData NUMERIC "8"
    134 // Retrieval info: PRIVATE: rden NUMERIC "0"
    135 // Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
    136 // Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
    137 // Retrieval info: CONSTANT: INIT_FILE STRING "../part5/ramlpm.mif"
    138 // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
    139 // Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME=32x8"
    140 // Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
    141 // Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "32"
    142 // Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT"
    143 // Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
    144 // Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
    145 // Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
    146 // Retrieval info: CONSTANT: RAM_BLOCK_TYPE STRING "M4K"
    147 // Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "5"
    148 // Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
    149 // Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
    150 // Retrieval info: USED_PORT: address 0 0 5 0 INPUT NODEFVAL address[4..0]
    151 // Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock
    152 // Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL data[7..0]
    153 // Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL q[7..0]
    154 // Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL wren
    155 // Retrieval info: CONNECT: @address_a 0 0 5 0 address 0 0 5 0
    156 // Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
    157 // Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
    158 // Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0
    159 // Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
    160 // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
    161 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm.v TRUE
    162 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm.inc FALSE
    163 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm.cmp FALSE
    164 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm.bsf FALSE
    165 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm_inst.v FALSE
    166 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm_bb.v FALSE
    167 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm_waveforms.html TRUE
    168 // Retrieval info: GEN_FILE: TYPE_NORMAL ramlpm_wave*.jpg FALSE
    169 // Retrieval info: LIB_FILE: altera_mf

    Part VII 用DE2控制面板查看并修改SRAM的内容

        本练习借助DE2 控制面板这个工具来对片外存储器初始化和查看、修改。

        DE2 control panel的使用方法可查阅用户手册。下载相应的电路,打开应用程序,启动接口,即可实现对SRAM的控制。

    代码part 7:

    1 //练习SRAM的读/写功能,通过FPGA控制SRAM和通过DE2 control pannel控制SRAM
    2
    3 ///引脚说明:
    4 //-------------------------------------------------------------------
    5 // SW[17] write_en
    6 // SW[15:11] address
    7 // SW[7:0] datain
    8 // LEDG0 write
    9 // HEX7-6 address
    10 // HEX5-4 datain
    11 // HEX3-2 read_address
    12 // HEX1-0 dataout
    13 // KEY0 rst_n
    14 // CLOCK_50 clk
    15
    16 module part7(
    17 input CLOCK_50,
    18 input [17:0] SW,
    19 input [0:0] KEY, //rst_n
    20 output [0:0] LEDG,
    21 output [0:6] HEX7,HEX6,HEX5,HEX4,HEX3,HEX2,HEX1,HEX0,
    22
    23 //SRAM pors
    24 output [17:0] SRAM_ADDR, //address
    25 inout [15:0] SRAM_DQ, //datain , dataout
    26 output SRAM_CE_N, //chip enable
    27 SRAM_OE_N, //output enable
    28 SRAM_WE_N, //write enable
    29 SRAM_UB_N, //upper byte
    30 SRAM_LB_N //lower byte
    31 );
    32
    33
    34 wire rst_n,clk,writen_sync,ce,ce1,ce2;
    35 wire [7:0] datain,datain_sync,dataout;
    36 wire [4:0] write_address,write_address_sync;
    37
    38 assign clk=CLOCK_50;
    39 assign rst_n=KEY[0];
    40
    41 //同步输入信号
    42
    43 regne #(.n(1)) r0(!SW[17],clk,rst_n,1'b1,writen_sync);
    44 regne #(.n(1) ) r1(writen_sync,clk,rst_n,1'b1,SRAM_WE_N); //同步write
    45
    46 regne #(.n(5)) r2(SW[15:11],clk,rst_n,1'b1,write_address_sync);
    47 regne #(.n(5)) r3(write_address_sync,clk,rst_n,1'b1,write_address); //同步address
    48
    49 regne #(.n(8)) r4(SW[7:0],clk,rst_n,1'b1,datain_sync);
    50 regne #(.n(8)) r5(datain_sync,clk,rst_n,1'b1,datain); //同步DataIn
    51
    52 //分频,产生约1s的时钟
    53 parameter m=26;
    54 reg [m-1:0] div_count;
    55 reg [4:0] read_address;
    56
    57 //寻址
    58 always @(posedge clk)
    59 div_count<=div_count+1;
    60
    61 always @(posedge clk)
    62 if(!rst_n)
    63 read_address<=5'b0;
    64 else if(div_count==0)
    65 read_address<=read_address+1'b1;
    66
    67 //读/写选择
    68 assign SRAM_ADDR=(SRAM_WE_N==1'b0)?{13'b0,write_address}:{13'b0,read_address};
    69
    70 assign SRAM_DQ=(SRAM_WE_N==1'b0)?{8'b0,datain}:16'bz;
    71
    72 assign dataout=SRAM_DQ[7:0];
    73
    74 regne #(.n(1)) r6(1'b1,clk,rst_n,1'b1,ce1); //CE初始化,上电后2个时钟,避免写入
    75 regne #(.n(1)) r7(ce1,clk,rst_n,1'b1,ce2);
    76 regne #(.n(1)) r8(ce2,clk,rst_n,1'b1,ce);
    77 assign SRAM_CE_N=~ce;
    78
    79 assign
    80 SRAM_OE_N=1'b0,
    81 SRAM_UB_N=1'b0,
    82 SRAM_LB_N=1'b0;
    83
    84 assign LEDG=SRAM_WE_N; //Write的标记
    85
    86 //调用7-seg显示模块
    87 seg_lut h5(HEX5,datain[7:4]); //DataIn
    88 seg_lut h4(HEX4,datain[3:0]);
    89
    90 seg_lut h7(HEX7,{{3{1'b0}},write_address[4]}); //address
    91 seg_lut h6(HEX6,write_address[3:0]);
    92
    93 seg_lut h1(HEX1,dataout[7:4]); //DataOut
    94 seg_lut h0(HEX0,dataout[3:0]);
    95
    96 seg_lut h3(HEX3,{3'b0,read_address[4]}); //read_address
    97 seg_lut h2(HEX2,read_address[3:0]);
    98
    99 endmodule
    100
    101 //7-seg
    102
    103 module seg_lut(oseg,idig);
    104 input [3:0] idig;
    105 output reg [0:6] oseg;
    106
    107 always @(idig)
    108 case(idig)
    109 4'h0: oseg=7'b000_0001;
    110 4'h1: oseg=7'b100_1111; // --------0--------
    111 4'h2: oseg=7'b001_0010; // | |
    112 4'h3: oseg=7'b000_0110; // | | 1
    113 4'h4: oseg=7'b100_1100; // | 5 |
    114 4'h5: oseg=7'b010_0100; // | |
    115 4'h6: oseg=7'b010_0000; // --------6--------
    116 4'h7: oseg=7'b000_1111; // | |
    117 4'h8: oseg=7'b000_0000; // | |
    118 4'h9: oseg=7'b000_1100; // | 4 | 2
    119 4'hA: oseg=7'b000_1000; // | |
    120 4'hb: oseg=7'b110_0000; // --------3---------
    121 4'hC: oseg=7'b011_0001;
    122 4'hd: oseg=7'b100_0010;
    123 4'hE: oseg=7'b011_0000;
    124 4'hF: oseg=7'b011_1000;
    125 default: oseg=7'b111_1111;
    126 endcase
    127
    128 endmodule
    129
    130 //register 用来同步输入信号
    131
    132 module regne(r,clk,rst_n,e,q);
    133 parameter n=7;
    134 input [n-1:0] r;
    135 input clk,rst_n,e;
    136 output reg [n-1:0] q;
    137
    138 always @(posedge clk)
    139 begin
    140 if(rst_n==0)
    141 q<={n{1'b0}};
    142 else if(e)
    143 q<=r;
    144 end
    145
    146 endmodule
    147

    Conclue

        以上7个小练习逐步熟悉对RAM的操作。有意思的是part 7的控制面板。有UI,有驱动电路。

  • 相关阅读:
    【NOIP 2003】 加分二叉树
    【POJ 1655】 Balancing Act
    【HDU 3613】Best Reward
    【POJ 3461】 Oulipo
    【POJ 2752】 Seek the Name, Seek the Fame
    【POJ 1961】 Period
    【POJ 2406】 Power Strings
    BZOJ3028 食物(生成函数)
    BZOJ5372 PKUSC2018神仙的游戏(NTT)
    BZOJ4836 二元运算(分治FFT)
  • 原文地址:https://www.cnblogs.com/halflife/p/2025301.html
Copyright © 2011-2022 走看看