訊息
|
說明:此版本的記憶體已經改成以 8 bit 為一單位,因此指令碼符合 CPU0 的格式。
程式碼
0000 LD R2, K0 L 0 002F000C
0004 LD R1, K1 L 0 001F000C
0008 LOOP: FF
0008 ADD R2, R2, R1 A 13 13221000
000C JMP LOOP J 26 26FFFFF8
0010 K0: WORD 0 D F2 00000000
0014 K1: WORD 1 D F2 00000001
0018 SUM: WORD 0 D F2 00000000
Verilog 模組
module computer0m(input clock, reset, output [31:0] pc,
output [2:0] tick, output [31:0] ir,
output [31:0] mar, output [31:0] mdr,
inout [31:0] dbus, output m_en, m_rw,
output [7:0] op, output signed [23:0] addr24);
cpu0m cpu (.clock(clock), .reset(reset), .pc(pc), .tick(tick), .ir(ir),
.mar(mar), .mdr(mdr), .dbus(dbus), .m_en(m_en), .m_rw(m_rw),
.op(op), .addr24(addr24));
memory0m mem (.clock(clock), .reset(reset), .en(m_en), .rw(m_rw),
.abus(mar), .dbus_in(dbus), .dbus_out(dbus));
endmodule
module cpu0m(input clock, reset, output reg [31:0] pc,
output reg [2:0] tick, output reg [31:0] ir,
output reg [31:0] mar, output reg [31:0] mdr,
inout [31:0] dbus, output reg m_en, m_rw,
output reg [7:0] op, output reg signed [23:0] addr24);
// reg [7:0] op;
// reg signed [23:0] addr24;
reg signed [31:0] addr32;
always @(posedge clock) begin
if (reset)
begin
pc = 0;
tick = 0;
m_en = 1;
end
else begin
tick = tick+1;
case (tick)
1:
begin // memory.read(m[PC])
mar = pc; // MAR = PC
m_rw = 1; // m_rw=1 is read mode, read(m[MAR]) => read(m[PC])
end
2:
begin
mdr = dbus;
ir = mdr; // IR = dbus = m[PC]
op = ir[31:24];
addr24 = ir[23:0];
end
3:
begin
pc = pc+4;
end
4:
begin
case (op)
8'h26:
begin
addr32 = addr24;
pc = pc+addr32;
end
default:
begin
end
endcase
end
5:
begin
end
6:
begin
tick = 0;
end
default:
begin
end
endcase
end
end
endmodule
module memory0m(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; // LD R2, K0
{m[4],m[5],m[6],m[7]} = 32'h001F000C; // LD R1, K1
{m[8],m[9],m[10],m[11]} = 32'h13221000; // LOOP:
{m[12],m[13],m[14],m[15]} = 32'h26FFFFF8; // ADD R2, R2, R1
{m[16],m[17],m[18],m[19]} = 32'h00000000; // JMP LOOP
{m[20],m[21],m[22],m[23]} = 32'h00000001; // K0: WORD 0
{m[24],m[25],m[26],m[27]} = 32'h00000000; // K1: WORD 1
data = 32'hZZZZZZZZ; // SUM: WORD 0
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
測試程式
`timescale 1ns/10ps
module computer0mTest;
reg clock;
reg reset;
wire [2:0] tick;
wire [31:0] pc;
wire [31:0] ir;
wire [31:0] mar;
wire [31:0] mdr;
wire [31:0] dbus;
wire m_en, m_rw;
wire [7:0] op;
wire [23:0] addr24;
computer0m DUT (.clock(clock), .reset(reset), .pc(pc), .tick(tick), .ir(ir),
.mar(mar), .mdr(mdr), .dbus(dbus), .m_en(m_en), .m_rw(m_rw),
.op(op), .addr24(addr24));
initial
begin
clock = 0;
reset = 1;
end
initial #100 reset = 0;
always #50 clock=clock+1;
endmodule
執行結果
參考文獻
- sign extension in verilog Options
- How to sign-extend a number in Verilog
- http://www.dev.idv.tw/mediawiki/index.php/%E6%88%91%E7%9A%84Verilog_Coding_Style
- 正負號的擴展:應多加利用Verilog的implicity signed extension,避免手動進行轉換。
- input signed [7:0] a, b;
- input signed [8:0] o;
- assign o = a + b; // Verilog會自動進行符號的擴展。
- CS61c: Verilog Tutorial, J. Wawrzynek, October 17, 2007
For instance we can sign extend a 16-bit signed number X, to form a signed 32-bit number, Y, as follows.
wire X[15:0], Y[31:0]; // description of X
assign Y = { 16{X[31]}, X };
Facebook
|
Post preview:
Close preview