CPU0 的跳躍指令 -- 在 Altera DE2-70 FPGA 板上的執行結果

# Verilog 程式

``````module Computer0m(input clock, reset,
output [0:7] segPc1, output [0:7] segPc0, output [0:7] segTick);
wire [31:0] counter;
wire [31:0] pc;
wire [3:0] tick;
wire [31:0] ir;
wire [31:0] mar;
wire [31:0] mdr;
wire [31:0] dbus;
wire m_en, m_rw;

Counter mCounter(clock, counter);

cpu0m cpu (.clock(counter[24]), .reset(reset), .pc(pc), .tick(tick), .ir(ir),
.mar(mar), .mdr(mdr), .dbus(dbus), .m_en(m_en), .m_rw(m_rw));

memory0m mem (.clock(counter[24]), .reset(reset), .en(m_en), .rw(m_rw),
.abus(mar), .dbus_in(dbus), .dbus_out(dbus));

Seg7 mSegPc1(pc[7:4], segPc1);
Seg7 mSegPc0(pc[3:0], segPc0);
Seg7 mSegTick(tick, segTick);

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);
reg [7:0] op;

always @(posedge clock) begin
if (reset)
begin
pc = 0;
tick = 0;
m_en = 1;
end
else begin
tick = tick+1;
case (tick)
1:
mar = pc; // MAR = PC
end
2:
begin
mdr = dbus;
ir = mdr; // IR = dbus = m[PC]
op = ir[31:24];
end
3:
begin
pc = pc+4;
end
4:
begin
case (op)
8'h26:
begin
end
default:
begin
end
endcase
end
5:
begin
end
6:
begin
tick = 0;
end
default:
begin
end
endcase
end
end

endmodule

module Seg7(input [3:0] num, output [0:7] seg);
reg [7:0] nseg;
always @(num) begin
case (num)
4'b0000: nseg = 8'b11111100; // 0
4'b0001: nseg = 8'b01100000; // 1
4'b0010: nseg = 8'b11011010; // 2
4'b0011: nseg = 8'b11110010; // 3
4'b0100: nseg = 8'b01100110; // 4
4'b0101: nseg = 8'b10110110; // 5
4'b0110: nseg = 8'b10111110; // 6
4'b0111: nseg = 8'b11100100; // 7
4'b1000: nseg = 8'b11111110; // 8
4'b1001: nseg = 8'b11110110; // 9
4'b1010: nseg = 8'b11101110; // A
4'b1011: nseg = 8'b00111110; // b
4'b1100: nseg = 8'b10011100; // C
4'b1101: nseg = 8'b01111010; // d
4'b1110: nseg = 8'b10011110; // E
4'b1111: nseg = 8'b10001110; // F
default: nseg = 8'b00000000; //
endcase
end
assign seg = ~nseg;
endmodule

module Counter(input clock, output reg [31:0] counter);
always @(posedge clock) begin
counter = counter + 1;
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; // 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```
```