| 49 | | |
| 50 | | |
| 51 | | |
| | 49 | メモリ(Memory.v)は、データを格納しておくために利用し、読み出しおよび書き込みの両方ができるメモリです。 |
| | 50 | |
| | 51 | {{{ |
| | 52 | module Memory(Address, WriteData, ReadData, MemWrite, MemRead, CK); |
| | 53 | |
| | 54 | input[31:0] Address, WriteData; |
| | 55 | input MemWrite, MemRead, CK; |
| | 56 | output[31:0] ReadData; |
| | 57 | |
| | 58 | always @(posedge CK) |
| | 59 | begin |
| | 60 | if (( MemWrite == 1'b1 ) && (32'h00000000 <= Address) && ( Address <= 32'h0000ffff) ) |
| | 61 | begin |
| | 62 | Mem.cell[Address] = WriteData; |
| | 63 | end |
| | 64 | end |
| | 65 | |
| | 66 | assign #5 ReadData = (MemRead == 1'b1) && (32'h00000000 <= Address) && ( Address <= 32'h0000ffff) ? Mem.cell[Address] : 32'bx; |
| | 67 | |
| | 68 | endmodule |
| | 69 | |
| | 70 | |
| | 71 | module Mem (); |
| | 72 | reg [31:0] cell [0:65535]; |
| | 73 | endmodule |
| | 74 | }}} |
| | 75 | |
| | 76 | === メモリMemoryの入出力信号の説明 === |
| | 77 | * 制御入力Memwriteが1のときデータの書き込みが、MemReadが1のときデータの読み込みが行われます。 |
| | 78 | * データを書き込むときは、Memwriteを1にすると、次のクロックの立ち上がりで、アドレスAddressにデータWriteDataが書き込まれます。アドレスは32'h00000000から32'h0000ffffが 有効です。これ以外の範囲の場合は書き込みは行われません。 |
| | 79 | * データを読み出すときは、MemReadを1にすると、ReadDataにそのアドレスに格納されたデータが出力されます。有効なアドレスは、書き込みの場合と同じです。 |
| | 80 | |
| | 81 | == メモリ初期化について == |
| | 82 | メモリの初期設定はテストベンチ記述で行います。 |
| | 83 | 今後の演習ではメモリの初期化は、xspimが出力するテストベンチ用のVerilogHDL記述を利用します。 |
| | 84 | |
| | 85 | xspimのdumpコマンドを用いて出力されるVerilogHDL記述は以下のような形式になっています。 |
| | 86 | {{{ |
| | 87 | // text segment |
| | 88 | Mem.cell['h00000000] = 32'h08000400; // j 0x1000 |
| | 89 | Mem.cell['h00001000] = 32'h********; 以下プログラムに対するコードが続く |
| | 90 | ... |
| | 91 | |
| | 92 | // data segment |
| | 93 | Mem.cell['h00005000] = 32'h********; 以下データに対するコードが続く |
| | 94 | ... |
| | 95 | }}} |
| | 96 | |
| | 97 | この記述をテストベンチにコピーして、プログラムおよびデータ領域の初期化を行います。 |
| | 98 | {{{ |
| | 99 | Mem.cell['h00000000] = 32'h08000400; |
| | 100 | }}} |
| | 101 | という記述で、テストベンチからモジュールMemのレジスタcellに 直接アクセスしています。 |