:ivl_version "12.0" "vec4-stack"; :vpi_module "system"; ; Copyright (c) 2001-2015 Stephen Williams (steve@icarus.com) ; Copyright (c) 2001 Stephan Boettcher ; ; This program is free software; you can redistribute it and/or modify ; it 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 module, "example" "example" 0 0; ;;; Make a memory. ; ; reg [8:2] memory[5:27]; memory .array "memory", 27 5, 8 2; ;;; 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, m_part; mem_prt .array/port memory, mem_idx; ; The memory index is normalized (a-5) using one extra bit to allow negative ; (wrapped) values to be out of range. mem_idx .arith/sub 6, a_pad, C4<000101>; a_pad .concat [5 1 0 0], a, C4<0>; ; Select 6 bits from the memory port starting at the second bit. m_part .part mem_prt, 1, 6; m .var "m", 6 0; ;;; The data port mem[] does not connect to the LSB of the memory. ;;; Initialize the last part of the memory. Starting at the middle of the ;;; the third memory word, memory[7] bit 6. ; ; initial begin ; memory[7][8:6] = 8'h55; ; memory[8] = 8'h00; ; memory[9] = 8'h00; ; memory[10] = 8'h50; ; memory[11] = 8'h05; ; memory[12] = 8'h05; ; memory[13] = 8'h50; ; memory[14] = 8'h05; ; memory[15] = 8'h05; ; memory[16] = 8'h00; ; memory[17] = 8'h00; ; memory[18] = 8'h00; ; memory[19] = 8'h01; ; memory[20] = 8'h00; ; memory[21] = 8'h04; ; memory[22] = 8'h00; ; memory[23] = 8'h10; ; memory[24] = 8'h00; ; memory[25] = 8'h40; ; memory[26] = 8'h01; ; memory[27] = 8'h00; ; end .scope main; mem_init ; %pushi/vec4 5, 0, 3; value to store %ix/load 4, 2, 0; word index (7 -> zero based) %ix/load 5, 4, 0; bit index (6 -> zero based) %flag_set/imm 4, 0; the index values are defined %store/vec4a memory, 4, 5; %pushi/vec4 0, 0, 7; value to store %ix/load 4, 3, 0; word index (8 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 0, 0, 7; value to store %ix/load 4, 4, 0; word index (9 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 80, 0, 7; value to store %ix/load 4, 5, 0; word index (10 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 5, 0, 7; value to store %ix/load 4, 6, 0; word index (11 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 5, 0, 7; value to store %ix/load 4, 7, 0; word index (12 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 80, 0, 7; value to store %ix/load 4, 8, 0; word index (13 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 5, 0, 7; value to store %ix/load 4, 9, 0; word index (14 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 5, 0, 7; value to store %ix/load 4, 10, 0; word index (15 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 0, 0, 7; value to store %ix/load 4, 11, 0; word index (16 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 0, 0, 7; value to store %ix/load 4, 12, 0; word index (17 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 0, 0, 7; value to store %ix/load 4, 13, 0; word index (18 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 1, 0, 7; value to store %ix/load 4, 14, 0; word index (19 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 0, 0, 7; value to store %ix/load 4, 15, 0; word index (20 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 4, 0, 7; value to store %ix/load 4, 16, 0; word index (21 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 0, 0, 7; value to store %ix/load 4, 17, 0; word index (22 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 16, 0, 7; value to store %ix/load 4, 18, 0; word index (23 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 0, 0, 7; value to store %ix/load 4, 19, 0; word index (24 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 64, 0, 7; value to store %ix/load 4, 20, 0; word index (25 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 1, 0, 7; value to store %ix/load 4, 21, 0; word index (26 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %pushi/vec4 0, 0, 7; value to store %ix/load 4, 22, 0; word index (27 -> zero based) %flag_set/imm 4, 0; the index value is defined %store/vec4a memory, 4, 0; %end; .thread mem_init; ;;; 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, 0; %vpi_call 0 0 "$display", "a:%b d:%b", a, d {0 0 0}; %event wclk; %delay 5, 0; %load/vec4 a; %addi 1, 0, 5; %assign/vec4 a, 0; %jmp always; .thread always; ;;; Initialize the variables, 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 ; %pushi/vec4 0, 0, 1; %store/vec4 we, 0, 1; %pushi/vec4 38, 12, 6; %store/vec4 di, 0, 6; %pushi/vec4 0, 0, 5; %store/vec4 a, 0, 5; %delay 220, 0; %vpi_call 0 0 "$readmemh", "memory.hex", memory {0 0 0}; %delay 30, 0; %pushi/vec4 1, 0, 1; %store/vec4 we, 0, 1; %delay 5, 0; %vpi_call 0 0 "$display", "write to a=%b", a {0 0 0}; %delay 5, 0; %pushi/vec4 0, 0, 1; %store/vec4 we, 0, 1; %delay 60, 0; ;;; Memories are indexed by index register 3. The index register ;;; points to the zero based word position in the memory. %pushi/vec4 25, 12, 7; %ix/load 3, 18, 0; memory word index (23 -> zero based) %flag_set/imm 4, 0; the index value is defined %assign/vec4/a/d memory, 0, 0; %delay 320, 0; %ix/load 4, 4, 0; memory word index (9 -> zero based) %flag_set/imm 4, 0; the index value is defined %load/vec4a memory, 4; %store/vec4 m, 0, 7; %vpi_call 0 0 "$display", "memory[9]=%b", m {0 0 0}; %delay 1, 0; %vpi_call 0 0 "$finish" {0 0 0}; %end; .thread initial; :file_names 2; "N/A"; "";