| Version 4 (modified by nakasato, 11 years ago) (diff) |
|---|
トップ:http://galaxy.u-aizu.ac.jp/note/wiki/CAEX2015
メモリとレジスタ
課題1 レジスタの利用方法
以下のテストベンチは、レジスタファイルをインスタンス化して、$a0レジスタに"0xffffffff"を書き込んでいる。
`timescale 1ns/1ps
`include "Registers.v"
module RegTest;
reg [4:0] read_adr1, read_adr2, write_adr;
reg [31:0] write_data;
reg write_enable;
reg ck,clear;
wire [31:0] read_data1, read_data2;
Registers regs(read_adr1, read_adr2, write_data, write_enable, write_adr, ck, clear, read_data1, read_data2);
initial
begin
$dumpfile("RegTest.vcd");
$dumpvars(0, RegTest);
#0
ck = 1'b1;
clear = 1'b1;
#110
clear = 1'b0;
#190
read_adr1 = 5'b00100;
#100
write_enable = 1'b1;
write_adr = 5'b00100;
write_data = 32'hffffffff;
$display("%x %x",read_adr1, read_data1);
#100
write_enable = 1'b0;
$display("%x %x",read_adr1, read_data1);
#900
$finish;
end // initial begin
always #50 ck = ~ck;
endmodule
これを参考にして、以下のテーブルに示すように、レジスタに値の値を書き込んで、読み出すテストベンチを作成し実行したうえで、クロック信号(ck)、読み出しているレジスタのアドレス(read_adr1)と読み出し結果(read_data1)の波形を確認しなさい。波形には、この三つの信号のみを表示すること。表示する順番は、小さいアドレスから大きいアドレスになるようにすること。なお、表示している信号名がわかるようにすること。
| レジスタ | 値 |
| $sp | 0xfffff |
| $v0 | 0xfafa |
| $v1 | 0x1010 |
| $t0 | 0xffffffff |
| $t1 | 0xaaaaaaaa |
| $ra | 0x98765432 |
| $t2 | 0x98765432 |
| $t3 | 0x12121 |
波形の例
以下のように各レジスタにデータを書き込んだ場合:
| $at | 0xf |
| $v0 | 0xff |
| $v1 | 0xfff |
| $a0 | 0xffff |
実行結果の波形の例:
課題2 メモリの利用方法
以下のテストベンチファイルでは、レジスタファイルとメモリとALUをインスタンス化し、テストするためのテンプレートである。
`timescale 1ns/1ps
`include "Registers.v"
`include "Memory.v"
`include "ALU.v"
module MemTest;
// for Memory
reg [31:0] address;
reg [31:0] write_data;
reg write_enable, read_enable;
reg ck;
wire [31:0] read_data;
// for Registers
reg [4:0] read_adr1_reg, read_adr2_reg, write_adr_reg;
reg [31:0] write_data_reg;
reg write_enable_reg;
reg clear_reg;
wire [31:0] read_data1_reg, read_data2_reg;
// for ALU
reg [31:0] A, B;
reg [3:0] ALUop;
wire Zero;
wire [31:0] Result;
Memory mem(address, write_data, read_data, write_enable, read_enable, ck);
Registers regs(read_adr1_reg, read_adr2_reg, write_data_reg, write_enable_reg, write_adr_reg,
ck, clear_reg,
read_data1_reg, read_data2_reg);
ALU alu(A, B, ALUop, Result, Zero);
initial
begin
$dumpfile("MemTest.vcd");
$dumpvars(0, MemTest);
// data segment
Mem.cell['h00005000] = 32'h0000000a;
Mem.cell['h00005004] = 32'h0000000b;
Mem.cell['h00005008] = 32'h00000000;
Mem.cell['h00005010] = 32'h00000000;
Mem.cell['h00005014] = 32'h00000000;
Mem.cell['h00005018] = 32'h00000000;
#0
ck = 1'b1;
clear_reg = 1'b1;
read_enable = 1'b0;
address = 32'h00000000;
write_enable_reg = 1'b0;
write_adr_reg = 5'b00000;
write_data_reg = 32'h00000000;
#110
clear_reg = 1'b0;
#190 // read memory at 0x5000
read_enable = 1'b1;
address = 32'h00005000;
#100 // write data to $v0 and read memory at 0x5004
write_enable_reg = 1'b1;
write_adr_reg = 5'b00010;
write_data_reg = read_data;
#100
read_enable = 1'b0;
write_enable_reg = 1'b0;
#100
read_adr1_reg = 5'b00010;
#100
$display("$v0 = %x",read_data1_reg);
#2000
$finish;
end // initial begin
always #50 ck = ~ck;
endmodule
実行結果は以下のようになるはずである。
% ncverilog test_mem.v ....省略 ncsim> run $v0 = 0000000a ....省略
ちなみに、以下の部分でメモリからデータを読み出し、レジスタファイル($v0)に書き込んでいる。
#190 // read memory at 0x5000
read_enable = 1'b1;
address = 32'h00005000;
#100 // write data to $v0
write_enable_reg = 1'b1;
write_adr_reg = 5'b00010;
write_data_reg = read_data;
#100
read_enable = 1'b0;
write_enable_reg = 1'b0;
実行結果の波形の例:
このテンプレートを元にして、アドレス0x5000と0x5004にあるデータを演算した結果を、再びメモリに書き込むテストベンチを作成せよ。格納アドレスと演算結果の対応は以下の通りとする。特に、レジスタへの読み書き、演算をして結果をメモリに書き込む部分の波形を確認すること。
| 0x5008 | 加算 |
| 0x500c | 減算 |
| 0x5010 | AND演算 |
| 0x5014 | 3*"0x5000のデータ"+"0x5004のデータ" |
Attachments (2)
- comparch_ex6_mem.png (11.1 KB) - added by nakasato 11 years ago.
- comparch_ex6_reg.png (6.4 KB) - added by nakasato 11 years ago.
Download all attachments as: .zip


