以 Verilog 設計 32 位元記憶體

Verilog

基本語法

型態

全域變數

基本元件

多樣的寫法

指定

assign

always

initial

運算式

分枝

迴圈

模組

函數

Task

陣列

輸出入

觀察

真值表

測試程式

訊息顯示

注意事項

模擬程序

硬體工程

程式範例

Xor

Xor3

全加器

加法器

加減器

快速加法器

乘法器

ALU

閂鎖器

脈衝偵測

計數器

多工器

暫存器群

記憶體

延遲問題

浮點數

狀態機

程式計數器

CPU0-Mini

CPU0

pipeline

工具

QuartusII

Icarus

Veritek

訊息

相關網站

參考文獻

最新修改

簡體版

English

Verilog 程式:mem32.v

module memory(input clock, reset, en, rw, 
                input [31:0] abus, input [31:0] dbus_in, output [31:0] dbus_out);
    reg [7:0] m [0:128];
    reg [31:0] data;

    always @(clock or reset or abus or en or rw or dbus_in) 
    begin
        if (reset == 1) begin
            {m[0],m[1],m[2],m[3]}     = 32'h002F000C; // 0000           LD   R2, K0
            {m[4],m[5],m[6],m[7]}     = 32'h001F000C; // 0004           LD   R1, K1
            {m[8],m[9],m[10],m[11]}   = 32'h13221000; // 0008 LOOP:     ADD  R2, R2, R1
            {m[12],m[13],m[14],m[15]} = 32'h26FFFFF8; // 000C           JMP  LOOP
            {m[16],m[17],m[18],m[19]} = 32'h00000000; // 0010 K0:        WORD 0
            {m[20],m[21],m[22],m[23]} = 32'h00000001; // 0014 K1:        WORD 1
            data = 32'hZZZZZZZZ; 
        end else if (abus >=0 && abus < 128) begin
            if (en == 1 && rw == 0) // r_w==0:write
            begin
                data = dbus_in;
                {m[abus], m[abus+1], m[abus+2], m[abus+3]} = dbus_in;
            end
            else if (en == 1 && rw == 1) // r_w==1:read
                data = {m[abus], m[abus+1], m[abus+2], m[abus+3]};
            else
                data = 32'hZZZZZZZZ;
        end else
            data = 32'hZZZZZZZZ;
    end
    assign dbus_out = data;
endmodule

module main;
reg clock, reset, en, rw;
reg [31:0] addr;
reg [31:0] data_in;
wire [31:0] data_out;

memory DUT (.clock(clock), .reset(reset), .en(en), .rw(rw), 
   .abus(addr), .dbus_in(data_in), .dbus_out(data_out));

initial // reset:設定 memory 內容為 0,1,2,....,127
begin
  clock = 0;
  reset = 1;
  en = 0;
  rw = 1; // rw=1:讀取模式
  #75;
  en = 1;
  reset = 0;
  addr = 0;
  #500;
  addr = 4;
  rw = 0; // 寫入模式
  data_in = 8'h3A;
  #100;
  addr = 0;
  rw = 1; // 讀取模式
  data_in = 0;
end

always #50 begin
  clock = clock + 1; 
  $monitor("%4dns monitor: clk=%d en=%d rw=%d, addr=%8h din=%8h dout=%8h", 
           $stime, clock, en, rw, addr, data_in, data_out);  
end

always #200 
begin
 addr=addr+1;
end

initial #2000 $finish;

endmodule

Icarus 執行結果

D:\ccc101\Verilog>iverilog mem32.v -o mem32

D:\ccc101\Verilog>vvp mem32
  50ns monitor: clk=1 en=0 rw=1, addr=xxxxxxxx din=xxxxxxxx dout=zzzzzzzz
  75ns monitor: clk=1 en=1 rw=1, addr=00000000 din=xxxxxxxx dout=002f000c
 100ns monitor: clk=0 en=1 rw=1, addr=00000000 din=xxxxxxxx dout=002f000c
 150ns monitor: clk=1 en=1 rw=1, addr=00000000 din=xxxxxxxx dout=002f000c
 200ns monitor: clk=0 en=1 rw=1, addr=00000001 din=xxxxxxxx dout=2f000c00
 250ns monitor: clk=1 en=1 rw=1, addr=00000001 din=xxxxxxxx dout=2f000c00
 300ns monitor: clk=0 en=1 rw=1, addr=00000001 din=xxxxxxxx dout=2f000c00
 350ns monitor: clk=1 en=1 rw=1, addr=00000001 din=xxxxxxxx dout=2f000c00
 400ns monitor: clk=0 en=1 rw=1, addr=00000002 din=xxxxxxxx dout=000c001f
 450ns monitor: clk=1 en=1 rw=1, addr=00000002 din=xxxxxxxx dout=000c001f
 500ns monitor: clk=0 en=1 rw=1, addr=00000002 din=xxxxxxxx dout=000c001f
 550ns monitor: clk=1 en=1 rw=1, addr=00000002 din=xxxxxxxx dout=000c001f
 575ns monitor: clk=1 en=1 rw=0, addr=00000004 din=0000003a dout=0000003a
 600ns monitor: clk=0 en=1 rw=0, addr=00000005 din=0000003a dout=0000003a
 650ns monitor: clk=1 en=1 rw=0, addr=00000005 din=0000003a dout=0000003a
 675ns monitor: clk=1 en=1 rw=1, addr=00000000 din=00000000 dout=002f000c
 700ns monitor: clk=0 en=1 rw=1, addr=00000000 din=00000000 dout=002f000c
 750ns monitor: clk=1 en=1 rw=1, addr=00000000 din=00000000 dout=002f000c
 800ns monitor: clk=0 en=1 rw=1, addr=00000001 din=00000000 dout=2f000c00
 850ns monitor: clk=1 en=1 rw=1, addr=00000001 din=00000000 dout=2f000c00
 900ns monitor: clk=0 en=1 rw=1, addr=00000001 din=00000000 dout=2f000c00
 950ns monitor: clk=1 en=1 rw=1, addr=00000001 din=00000000 dout=2f000c00
1000ns monitor: clk=0 en=1 rw=1, addr=00000002 din=00000000 dout=000c0000
1050ns monitor: clk=1 en=1 rw=1, addr=00000002 din=00000000 dout=000c0000
1100ns monitor: clk=0 en=1 rw=1, addr=00000002 din=00000000 dout=000c0000
1150ns monitor: clk=1 en=1 rw=1, addr=00000002 din=00000000 dout=000c0000
1200ns monitor: clk=0 en=1 rw=1, addr=00000003 din=00000000 dout=0c000000
1250ns monitor: clk=1 en=1 rw=1, addr=00000003 din=00000000 dout=0c000000
1300ns monitor: clk=0 en=1 rw=1, addr=00000003 din=00000000 dout=0c000000
1350ns monitor: clk=1 en=1 rw=1, addr=00000003 din=00000000 dout=0c000000
1400ns monitor: clk=0 en=1 rw=1, addr=00000004 din=00000000 dout=00000000
1450ns monitor: clk=1 en=1 rw=1, addr=00000004 din=00000000 dout=00000000
1500ns monitor: clk=0 en=1 rw=1, addr=00000004 din=00000000 dout=00000000
1550ns monitor: clk=1 en=1 rw=1, addr=00000004 din=00000000 dout=00000000
1600ns monitor: clk=0 en=1 rw=1, addr=00000005 din=00000000 dout=0000003a
1650ns monitor: clk=1 en=1 rw=1, addr=00000005 din=00000000 dout=0000003a
1700ns monitor: clk=0 en=1 rw=1, addr=00000005 din=00000000 dout=0000003a
1750ns monitor: clk=1 en=1 rw=1, addr=00000005 din=00000000 dout=0000003a
1800ns monitor: clk=0 en=1 rw=1, addr=00000006 din=00000000 dout=00003a22
1850ns monitor: clk=1 en=1 rw=1, addr=00000006 din=00000000 dout=00003a22
1900ns monitor: clk=0 en=1 rw=1, addr=00000006 din=00000000 dout=00003a22
1950ns monitor: clk=1 en=1 rw=1, addr=00000006 din=00000000 dout=00003a22
2000ns monitor: clk=0 en=1 rw=1, addr=00000007 din=00000000 dout=003a2210

Facebook

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License