iverilog/vvp/examples/memory.vvp

227 lines
4.9 KiB
Plaintext

: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 <stephan@nevis.columbia.edu>
;
; 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 ber 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;