【原创】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,有驱动电路。

原文地址:https://www.cnblogs.com/halflife/p/2025301.html