這篇談的是 j1 CPU 的 Verilog 程式中的算術邏輯單元(ALU),請見以下檔案:
src/hardware/verilog/j1.v
為了方便說明,以下程式的次序不一定和 j1.v 中一致。
wire [15:0] insn;
wire [15:0] immediate = { 1'b0, insn[14:0] };
wire is_alu = (insn[15:13] == 3'b011);
wire is_lit = (insn[15]);
reg [3:0] st0sel;
always @*
begin
case (insn[14:13])
2'b00: st0sel = 0; // ubranch
2'b01: st0sel = 1; // 0branch
2'b10: st0sel = 0; // call
2'b11: st0sel = insn[11:8]; // ALU
default: st0sel = 4'bxxxx;
endcase
end
always @*
begin
if (insn[15])
_st0 = immediate;
else
case (st0sel)
4'b0000: _st0 = st0;
4'b0001: _st0 = st1;
4'b0010: _st0 = st0 + st1;
4'b0011: _st0 = st0 & st1;
4'b0100: _st0 = st0 | st1;
4'b0101: _st0 = st0 ^ st1;
4'b0110: _st0 = ~st0;
4'b0111: _st0 = {16{(st1 == st0)}};
4'b1000: _st0 = {16{($signed(st1) < $signed(st0))}};
4'b1001: _st0 = st1 >> st0[3:0];
4'b1010: _st0 = st0 - 1;
4'b1011: _st0 = rst0;
4'b1100: _st0 = |st0[15:14] ? io_din : ramrd;
4'b1101: _st0 = st1 << st0[3:0];
4'b1110: _st0 = {rsp, 3'b000, dsp};
4'b1111: _st0 = {16{(st1 < st0)}};
default: _st0 = 16'hxxxx;
endcase
end
以上總共 40 行,加上之前的 90 行,我們已經看懂了 j1.v 的 130/200。接下來的兩篇處理RAM 及 memory mapped I/O,我們對 j1.v 的探索就算完成。
沒有留言:
張貼留言