Modeling Memory - RAM and ROM - Ando KI June 2009
Copyright © 2009 by Ando KiModule overview ( 2 ) Objectives Learn how to model memory in general. Learn how to use Verilog for modeling ROM. Learn how to use Verilog for modeling RAM. Learn how to use $readmemh system task. Learn how to use parameter.
Copyright © 2009 by Ando KiModule overview ( 3 ) Semiconductor memory types volatileNon-volatile ROMFuse (mask) ROM PROMUV EPROM EEPROM RWMSRAMASRAMFRAM SSRAM DRAMSDRAMFlashNOR Flash SDR, DDR, DDR2NAND Flash ROM: Read-Only Memory; RWM: Read-Write Memory PROM: Programmable ROM; EPROM: Erasable ROM (UV ROM); EEPROM: Electrically Erasable PROM; SRAM: Static Random Access Memory; ASRAM: Asynchronous SRAM; SSRAM: Synchronous SRAM; DRAM: Dynamic RAM; SDRAM: Synchronous DRAM; FRAM: Ferroelectric RAM; SDR SDRAM: Single Data Rate SDRAM; DDR: Double Data Rate DDR2: Double Data Rate Two; EDO DRAM: Extended Data Out DRAM
Copyright © 2009 by Ando KiModule overview ( 4 ) Modeling one-dimensional ROM module rom_case( output reg [3:0] z, input wire [2:0] a; // Address - 8 deep memory. case (a) 3'b000: z = 4'b1011; 3'b001: z = 4'b0001; 3'b100: z = 4'b0011; 3'b110: z = 4'b0010; 3'b111: z = 4'b1110; default: z = 4'b0000; endcase endmodule // rom_case // z is the ROM, and its address size is // determined by a.
Copyright © 2009 by Ando KiModule overview ( 5 ) Modeling two-dimensional ROM With fixed contentsWith data in text file module rom_2dimarray_initial ( output wire [3:0] z, input wire [2:0] a; // address- 8 deep memory // Declare a memory rom of 8 4-bit registers. // The indices are 0 to 7: reg [3:0] rom[0:7]; initial begin rom[0] = 4'b1011; rom[1] = 4'b0001; rom[2] = 4'b0011; rom[3] = 4'b0010; rom[4] = 4'b1110; rom[5] = 4'b0111; rom[6] = 4'b0101; rom[7] = 4'b0100; end assign z = rom[a]; endmodule module rom_2dimarray_initial_readmem ( output wire [3:0] z, input wire [2:0] a); // Declare a memory rom of 8 4-bit registers. // The indices are 0 to 7: reg [3:0] rom[0:7]; initial $readmemb("rom.data", rom); assign z = rom[a]; endmodule // with data in text file // Example of content rom.data file: 1011 // addr= // addr= // addr= // addr= // addr= // addr= // addr= // addr=
Copyright © 2009 by Ando KiModule overview ( 6 ) Modeling RAM // A RAM element is an edge-sensitive storage // element: module ram_test( output wire [7:0] q, input wire [7:0] d, input wire [6:0] a, input wire clk, we); reg [7:0] mem [127:0]; clk) if (we) mem[a] <= d; assign q = mem[a]; endmodule // A RAM element is a level-sensitive storage // element: module ramlatch ( output wire [7:0] q, // output input wire [7:0] d, // data input input wire [6:0] a, // address input wire we; // clock and write enable // Memory 128 deep, 8 wide: reg [7:0] mem [127:0]; if (we) mem[a] <= d; assign q = mem[a]; endmodule RAM element with edge-sensitiveRAM element with level-sensitive
Copyright © 2009 by Ando KiModule overview ( 7 ) Loading memory data from a file (1/2) Two system tasks ($readmemb and $readmemh) read and load data from a specified text file into a specified memory. It can be called at any time during simulation. The text file shall contain only the following: White space (space, new line, tab, form- feed) Comments (// or /* */) Binary for $readmemb and hexadecimal for $readmemh Upper and lower cases are allowed. X, x, Z, z, and _ can be used. Do not use the base format, such as 4h, 8b, and so on. Address can be specified by a hexadecimal Load_memory_tasks ::= $readmemb(file_name, mem_name [, start_addr [, finish_addr]]); |$readmemh(file_name, mem_name [, start_addr [, finish_addr]]);
Copyright © 2009 by Ando KiModule overview ( 8 ) Loading memory data from a file (2/2) reg [7:0] mem[1:128]; … initial $readmemh(mem.dat, mem); // case A initial $readmemh(mem.dat, mem, 16); // case B initial $readmemh(mem.dat, mem, 128, 1); // case C Case A: Load up the memory at simulation time 0 starting at the memory address 1. Case B: Load up the memory at simulation time 0 starting at the memory address 16. Case C: Load up the memory at simulation time 0 starting at the memory address 128 down to 1.
Copyright © 2009 by Ando KiModule overview ( 9 ) A simple ROM (1/2) Specifications Asynchronous, i.e. no clock Data is uni-directional Address width WIDTH_ADDR, which is varying from 1 to any. The depth of memory depends on WIDTH_ADDR. Data width WIDTH_DATA=8 Data is driven only when cs&as&oe is true. Otherwise, it stays at Z. It is initialized with memory_data.txt file at simulation time 0. ROM addr[ ] as oe data[7:0] cs addr as oe cs data ZZ
Copyright © 2009 by Ando KiModule overview ( 10 ) A simple ROM (2/2) signaldirectiondescription addr[m:0]InputAddress – memory location for data read from asInputAddress strobe – indicates valid address data[7:0]OutData input/output – data oeInputOutput enable – allows data to be driven csInputChip select – enables access to memory via read and write operations
Copyright © 2009 by Ando KiModule overview ( 11 ) A simple synchronous SRAM (1/2) Specifications Synchronous, i.e. clock Separated data bus Address width WIDTH_ADDR, which is varying from 1 to any. Data width WIDTH_DATA=8 Write-first (read-after-write or transparent) mode SSRAM addr[ ] en din[7:0] dout[7:0] clk we
Copyright © 2009 by Ando KiModule overview ( 12 ) A simple synchronous SRAM (2/2) signaldirectiondescription din[7:0]InputData input – data written into memory dout[7:0]OutputData output – synchronous output of the memory addr[m:0]InputAddress – memory location for data written to/read from weInputWrite enable – allows data transfer into memory enInputEnable – enables access to memory via read and write operations
Copyright © 2009 by Ando KiModule overview ( 13 ) top Testing configuration 1. Text data is read into the ROM using $readmemh system task. 2. The contents of ROM is copied to RAM. Read data from the ROM and then write the data into the RAM. 3. Compare ROM and RAM. Read data from both ROM and RAM, and compare them. ROM addr[ ] as oe data[7:0] cs SSRAM addr[ ] en din[7:0] dout[7:0] clk tester we
Copyright © 2009 by Ando KiModule overview ( 14 ) Verilog code segments: top.v // top.v `ifdef WIDTH_ADDR `else `define WIDTH_ADDR 3 `endif module top; parameter WIDTH_ADDR=`WIDTH_ADDR; wire ram_clk; wire [WIDTH_ADDR-1:0] ram_addr; wire ram_en; wire ram_we; wire [7:0] ram_din; wire [7:0] ram_dout; wire rom_cs; wire [WIDTH_ADDR-1:0] rom_addr; wire rom_as; wire rom_oe; wire [7:0] rom_data; // rom #(WIDTH_ADDR) Urom (.cs (rom_cs),.addr(rom_addr),.as (rom_as),.oe (rom_oe),.data(rom_data) ); ram #(WIDTH_ADDR) Uram (.clk (ram_clk),.addr(ram_addr),.en (ram_en),.we (ram_we),.din (ram_din),.dout(ram_dout) ); tester #(WIDTH_ADDR) Utester (.ram_clk (ram_clk ),.ram_addr(ram_addr),.ram_en (ram_en ),.ram_we (ram_we ),.ram_din (ram_din ),.ram_dout(ram_dout),.rom_cs (rom_cs ),.rom_addr(rom_addr),.rom_as (rom_as ),.rom_oe (rom_oe ),.rom_data(rom_data) ); // `ifdef _VCD_ initial begin $dumpfile("wave.vcd"); $dumpvars(1, ram_clk); $dumpvars(1, rom_cs); end `endif endmodule
Copyright © 2009 by Ando KiModule overview ( 15 ) Verilog code segments: tester.v (1/3) // tester.v module tester ( ram_clk, ram_addr, ram_en, ram_we, ram_din, ram_dout, rom_cs, rom_addr, rom_as, rom_oe, rom_data); parameter WIDTH_ADDR=3; output ram_clk; reg ram_clk; output [WIDTH_ADDR-1:0] ram_addr; reg [WIDTH_ADDR-1:0] ram_addr; output ram_en; reg ram_en; output ram_we; reg ram_we; output [7:0] ram_din; reg [7:0] ram_din; input [7:0] ram_dout; wire [7:0] ram_dout; output rom_cs; reg rom_cs; output [WIDTH_ADDR-1:0] rom_addr; reg [WIDTH_ADDR-1:0] rom_addr; output rom_as; reg rom_as; output rom_oe; reg rom_oe; input [7:0] rom_data; wire [7:0] rom_data; // initial begin ram_addr = 0; ram_en = 0; ram_we = 0; ram_din = 0; rom_cs = 0; rom_addr = 0; rom_as = 0; rom_oe = 0; ram_clk = 0; forever #5 ram_clk = ~ram_clk; end //
Copyright © 2009 by Ando KiModule overview ( 16 ) Verilog code segments: tester.v (2/3) parameter MEMORY_DEPTH=(1<<WIDTH_ADDR); integer index; reg [7:0] data, tmp; initial begin repeat (posedge ram_clk); // ROM->RAM for (index=0; index<MEMORY_DEPTH; index=index+1) begin read_rom(index, (posedge ram_clk); write_ram(index, (posedge ram_clk); (posedge ram_clk); for (index=MEMORY_DEPTH-1; index>=0; index=index-1) begin read_rom(index, (posedge ram_clk); read_ram(index, (posedge ram_clk); if (data!=tmp) $display($time,,"Error: A[0x%x], ROM=0x%x, RAM=0x%x", index, data, tmp); end $finish(2); end
Copyright © 2009 by Ando KiModule overview ( 17 ) task read_rom; input [WIDTH_ADDR-1:0] addr; output [7:0] data; begin rom_addr <= addr; rom_as <= 1'b1; #1; rom_cs <= 1'b1; #2; rom_oe <= 1'b1; #7; data <= rom_data; #1; rom_oe <= 1'b0; #1; rom_addr <= 'b0; rom_as <= 1'b0; rom_cs <= 1'b0; #2; end endtask Verilog code segments: tester.v (3/3) task read_ram; input [WIDTH_ADDR-1:0] addr; output [7:0] data; (negedge ram_clk); ram_addr <= addr; ram_en <= 1'b1; ram_we <= (posedge (negedge ram_clk); ram_addr <= 'b0; ram_en <= (posedge ram_clk); data <= #1 ram_dout; // must be blocking without the following (negedge ram_clk); end endtask task write_ram; input [WIDTH_ADDR-1:0] addr; input [7:0] data; (negedge ram_clk); ram_addr <= addr; ram_en <= 1'b1; ram_we <= 1'b1; ram_din <= (posedge (negedge ram_clk); ram_addr <= 'b0; ram_en <= 1'b0; ram_we <= 1'b0; ram_din <= 'b0; end endtask endmodule
Copyright © 2009 by Ando KiModule overview ( 18 ) Verilog code segments: rom.v & ram.v module rom ( cs, addr, as, oe, data ); parameter WIDTH_ADDR=3; input cs; // 1: active ROM input [WIDTH_ADDR-1:0] addr; // address input as; // address strobe; 1 for valid address input oe; // output enable; 1 for active output [7:0] data; // data // need something // endmodule module ram ( clk, addr, en, we, din, dout ); parameter WIDTH_ADDR=3; input clk; // clock input [WIDTH_ADDR-1:0] addr; // address input en; // enable input we; // write enable input [7:0] din; // data output [7:0] dout; // data // need something // endmodule
Copyright © 2009 by Ando KiModule overview ( 19 ) Verilog code segments: memory_data.txt
Copyright © 2009 by Ando KiModule overview ( 20 ) Simulation (1/2) make -f Makefile.modelsim make[1]: Entering directory `/cygdrive/z/Lectures/Incheon/2005fall/projects/project_03_mem_code/sim' /c/Modeltech_xe_starter/win32xoem/vlib work for F in../design/top.v../design/tester.v../design/rom.v../design/ram.v; do\ /c/Modeltech_xe_starter/win32xoem/vlog -lint -work work\ +define+_VCD_\ +define+WIDTH_ADDR=2\ +define+DEBUG\ +incdir+../design $F;\ done Model Technology ModelSim XE III vlog 6.0a Compiler Nov Compiling module top Top level modules: top Model Technology ModelSim XE III vlog 6.0a Compiler Nov Compiling module tester Top level modules: tester Model Technology ModelSim XE III vlog 6.0a Compiler Nov Compiling module rom Top level modules: rom Model Technology ModelSim XE III vlog 6.0a Compiler Nov Compiling module ram Top level modules: ram /c/Modeltech_xe_starter/win32xoem/vsim -c -do "run -all" work.top Reading C:/Modeltech_xe_starter/tcl/vsim/pref.tcl # 6.0a
Copyright © 2009 by Ando KiModule overview ( 21 ) Simulation (2/2) # 6.0a # vsim -do {run -all} -c work.top # Loading C:\iTUTOR\eda\modelsim\5.7c\iprvpi.dll # Loading work.top # Loading work.rom # Loading work.ram # Loading work.tester # run -all # INFO: Loading iprvpi.so(dll) # WARNING: Can't find parameter 'iPROVE_EIF_FILE' in top module. Disable iPROVE emulation and go on. # INFO: Start time: Thu Sep 15 00:53: # # ** Warning: (vsim-PLI-3407) Too many data words read at line 5 of "memory_data.txt". (Current address 4, address range [0:3]) : z:/Lectures/Incheon/2005fall/projects/project_03_mem_code/sim/../design/rom.v(32) # Time: 0 ps Iteration: 0 Instance: /top/Urom # 0 Info: WIDTH_ADDR= 2, MEMORY_DEPTH= 4 # 0 Info: ROM[ 0]=0x01 # 0 Info: ROM[ 1]=0x02 # 0 Info: ROM[ 2]=0x03 # 0 Info: ROM[ 3]=0x04 # ** Note: Data structure takes bytes of memory # Process time 0.02 seconds # $finish : z:/Lectures/Incheon/2005fall/projects/project_03_mem_code/sim/../design/tester.v(60) # Time: 385 ps Iteration: 0 Instance: /top/Utester # INFO: End time: Thu Sep 15 00:53: # INFO: Total time: secs # INFO: CPU time: secs in simulation make[1]: Leaving directory `/cygdrive/z/Lectures/Incheon/2005fall/projects/project_03_mem_code/sim'
Copyright © 2009 by Ando KiModule overview ( 22 ) Simulation result
Copyright © 2009 by Ando KiModule overview ( 23 ) Simulation result