:vpi_module "system"; ; IMPORTANT NOTE: ; ; This example uses constructs that are no longer supported. It will ; not run with the current vvp implementation! ; Copyright (c) 2001-2008 Stephen Williams (steve@icarus.com) ; Copyright (c) 2001 Stephan Boettcher ; ; This source code is free software; you can redistribute it ; and/or modify it in source code form under the terms of the GNU ; General Public License as published by the Free Software ; Foundation; either version 2 of the License, or (at your option) ; any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ; This sample demonstrates memory, also including index register ; arithmetic. And a memory write port main .scope "example"; ;;; Make a memory. ; ; reg [8:2] memory[5:27]; memory .mem "memory", 8,2, 27,5 ; ;;; The word width is 7 bits [8:2]. ;;; The memory size is 23 words, 5..27. ;;; Memory words are always numbered in ascending order. ;;; An address/data port. ; ; reg [4:0] a; ; reg we; ; event wclk; ; reg [5:0] di; ; wire [5:0] d = memory[a][8:3]; ; reg [6:0] m; a .var "a", 4,0; we .var "we", 0,0; wclk .event "wclk"; di .var "di", 5,0; d .net "d", 5,0, mem[0],mem[1],mem[2],mem[3],mem[4],mem[5]; mem .mem/port memory, 6,1, 5, a[0],a[1],a[2],a[3],a[4], wclk, we, di[0],di[1],di[2],di[3],di[4],di[5]; m .var "m", 6,0; ;;; The data port mem[] does not connect to the LSB of the memory. ;;; Initialize some part of the memory. Starting at memory bit [20], ;;; which is in the middle of the third memory word, memory[7]. The ;;; memory words occupy 8 bits each, that is 7 rounded up to the next ;;; multiple of 4. ;;; Four bits per byte. Word fill bits are included. Commas are ;;; optional, there may be a comma after the last byte. .mem/init memory[20], 0x55 0x00 0x00 0x50 0x05 0x05 0x50 0x05 0x05 0x00 0x00 0x00 0x01 0x00 0x04 0x00 0x10 0x00 0x40 0x01 0x00 0x04,0x00, 0x10,0x00, 0x40,0x00, ; ;;; Run through the addresses and display the data output. ; ; always ; begin ; #5 $display("a:%b d:%b", a, d); ; -> wclk; ; #5 a <= a+1; ; end .scope main; always ; %delay 5; %vpi_call "$display", "a:%b d:%b", a, d; %set wclk, 0; %delay 5; %load 10, a[0]; %load 11, a[1]; %load 12, a[2]; %load 13, a[3]; %load 14, a[4]; %mov 20, 1, 1; %mov 21, 0, 4; %add 10, 20, 5; %assign a[0], 0, 10; %assign a[1], 0, 11; %assign a[2], 0, 12; %assign a[3], 0, 13; %assign a[4], 0, 14; %jmp always; .thread always; ;;; Initialize a[], run some cycles, overwrite a memory word, run a ;;; bit more, read a memory word, finish. ; ; initial ; begin ; we = 0; ; di = 'b 10zx10; ; a = 0; ; #220; ; $readmemh("memory.hex", memory); ; #30; ; we = 1; ; #5; ; $display("write to a=%b", a); ; #5; ; we = 0; ; #60; ; memory[23] <= 'b 1xz01; ; #320; ; m = memory[9]; ; $display("memory[9]=%b", m); ; #1; ; $finish; ; end .scope main; initial ; %set we, 0; %set di[0], 0; %set di[1], 1; %set di[2], 2; %set di[3], 3; %set di[4], 0; %set di[5], 1; %set a[0], 0; %set a[1], 0; %set a[2], 0; %set a[3], 0; %set a[4], 0; %delay 220; %vpi_call "$readmemh", "memory.hex", memory; %delay 30; %set we, 1; %delay 5; %vpi_call "$display", "write to a=%b", a; %delay 5; %set we, 0; %delay 60; ;;; Memories are indexed by index register 3. The index register ;;; points to the bit position in the memory. Each memory word ;;; occupies a multiple of 4 bits. Bit position zero is the LSB of ;;; the first memory word, here: memory[5][2]. %ix/load 3, 23 ; memory word index %ix/sub 3, 5 ; minus memory root index %ix/mul 3, 8 ; times memory word size (rounded up) %assign/m memory, 0, 1; %ix/add 3, 1 ; next bit %assign/m memory, 0, 0; %ix/add 3, 1 ; %assign/m memory, 0, 3; %ix/add 3, 1 ; %assign/m memory, 0, 2; %ix/add 3, 1 ; %assign/m memory, 0, 1; %ix/add 3, 1 ; %assign/m memory, 0, 0; %ix/add 3, 1 ; %assign/m memory, 0, 0; %delay 320; %ix/load 3, 32 ; precomputed memory bit index %load/m 10, memory; %set m[0], 10; %ix/add 3, 1 ; %load/m 10, memory; %set m[1], 10; %ix/add 3, 1 ; %load/m 10, memory; %set m[2], 10; %ix/add 3, 1 ; %load/m 10, memory; %set m[3], 10; %ix/add 3, 1 ; %load/m 10, memory; %set m[4], 10; %ix/add 3, 1 ; %load/m 10, memory; %set m[5], 10; %ix/add 3, 1 ; %load/m 10, memory; %set m[6], 10; %vpi_call "$display", "memory[9]=%b", m; #1; %vpi_call "$finish"; %end; .thread initial;