commit ab5cc9ce5f7b503cbe762a15c3e71729c917fa18
parent 59efd750e9acc57dbbe70fb1e8bbbbcab987bdbb
Author: Brian Swetland <swetland@frotz.net>
Date: Sun, 2 Dec 2018 23:06:24 -0800
cleanup: remove old v3 cpu impl and v3/v4 isa docs
- the v3 cpu was never fully operational
- the old docs are not terribly useful
Diffstat:
5 files changed, 0 insertions(+), 573 deletions(-)
diff --git a/docs/isa16v3.txt b/docs/isa16v3.txt
@@ -1,66 +0,0 @@
-
-Basic Instructions Assembly Syntax Operation
---------------------- -------------------- -----------------------------
-iiii iiii aaaa 0000 mov Ra, si8 Ra = si8
-iiii iiii aaaa 0001 mhi Ra, si8 Ra = (Ra & 0xFF) | (si8 << 8)
-ffff bbbb aaaa 0010 alu Ra, Ra, Rb Ra = Ra <fn> Rb
-iiii ffff aaaa 0011 alu Ra, Ra, si4 Ra = Ra <fn> si4
-ffff bbbb aaaa 01cc alu Rc, Ra, Rb Rc = Ra <fn> Rb
-iiii bbbb aaaa 1000 lw Ra, [Rb, si4] Ra = [Rb + si4]
-iiii bbbb aaaa 1001 sw Ra, [Rb, si4] [Rb + si4] = Ra
-iiii iiii aaaa 1010 bnz Ra, si8 if (Ra != 0) PC += si8
-iiii iiii aaaa 1011 bz Ra, si8 if (Ra == 0) PC += si8
-iiii iiii iiii 1100 b si12 PC += si12
-iiii iiii iiii 1101 bl si12 R14 = PC, PC += si12,
-0000 bbbb xxxx 1110 b Rb PC = Rb
-0001 bbbb xxxx 1110 bl Rb R14 = PC, PC = Rb
-0010 0000 0000 1110 nop
-0010 nnnn aaaa 1110 debug Ra, x4 DEBUG(Ra, n4)
-
-Extended Instructions <--- Not implemented yet.
---------------------- Will likely change during
-0011 xxxx xxxx 1110 iret implementation.
-0100 nnnn aaaa 1110 mov Ra, Sn
-0101 nnnn aaaa 1110 mov Sn, Ra
-0110 aaaa bbbb 1110 mov Ra', Rb
-0111 aaaa bbbb 1110 mov Ra, Rb'
-1xxx xxxx xxxx 1110 undefined
-nnnn nnnn 0000 1111 syscall n
-nnnn nnnn 0001 1111 break;
-nnnn nnnn 0010 1111 set <flags>
-nnnn nnnn 0011 1111 clr <flags>
-xxxx xxxx 0011 1111 undefined
-xxxx xxxx 01xx 1111 undefined
-xxxx xxxx 1xxx 1111 undefined
-
-ALU Functions (<fn>) Key
--------------------------------------- ----------------------------------
-0000 mov r = b si4 signed 4bit immediate
-0001 and r = a & b si8 signed 8bit immediate
-0010 orr r = a | b si12 signed 12bit immediate
-0011 xor r = a ^ b fn ALU function
-0100 add r = a + b R0-R15 general purpose registers
-0101 sub r = a - b PC program counter
-0110 mul r = a * b
-0111 mhi r = (b << 8) | (a & 0xFF) S0-S15 system control registers
-1000 slt r = a < b F0-F7 system flag bits
-1001 sle r = a <= b R0'-R15' banked registers
-1010 shr r = a >> 1
-1011 shl r = a << 1
-1100 bis r = a | (1 << b[3:0])
-1101 bic r = a & (~(1 << b[3:0]))
-1110 tbs r = a & (1 << b[3:0])
-1111 bit r = 1 << b[3:0]
-
-Register Usage / Procedure Call Standard
------------------------------------------
-R0 - R3 parameters & results
-R4 - R11 caller save, working variables
-R12 reserved for OS/runtime global use
-R13 stack pointer
-R14 link register* (for branch-and-link)
-R15 scratch (for assembler/linker use)
-
-* The processor can *only* save PC to R14 on BL calls.
- All other register assignements are merely to simplify
- software interworking, not required by the architecture.
diff --git a/docs/isa16v4.txt b/docs/isa16v4.txt
@@ -1,37 +0,0 @@
-instruction formats constant encodings alu opcodes
------------------------ ------------------- --------------------
- FED CBA 987 654 3210 000 add R = A + B
-A fff bbb aaa ccc 0ooo 001 sub R = A - B
-B sii iii aaa ccc 0ooo si6 siiiii 010 and R = A & B
-C sii iii kkk ccc 0ooo si9 skkkiiiii 011 or R = A | B
-D sii iii xjj jjj 0ooo si11 sjjjjjiiiii 100 xor R = A ^ B
-E sii iii aaa mxx 0ooo si7 smiiiii 101 slt R = A < B
-F sii iii aaa ccc 1fff si6 siiiii 110 sge R = A >= B
-G sii iii jjj jjj 0ooo si12 sjjjjjjiiiii 111 mul R = A * B
-
-instruction encodings
----------------------
-A 0000 alu Rc, Ra, Rb Rc = Ra <fn> Rb
-? 0001 <expansion>
-G 0010 ext si12 Ex = 1*, Ev = si12[11:0]
-C 0011 mov Rc, si9 Rc = Ex ? { Ev, si9[3:0] } : si9
-B 0100 lw Rc, [Ra, si6] Rc = mem[Ra + si6]
-B 0101 sw Rc, [Ra, si6] mem[Ra + si6] = Rc
-D 0110 0 b si11 PC = PC + si11
-D 0110 1 bl si11 R7 = PC + 1, PC = PC + si11
-E 0111 00 bz Ra, si7 (Ra == 0) ? PC = PC + si7
-E 0111 01 bnz Ra, si7 (Ra != 0) ? PC = PC + si7
-E 0111 10 b Ra PC = Ra
-E 0111 11 bl Ra R7 = PC + 1, PC = Ra
-F 1fff alu Rc, Ra, si6 Rc = Ra <fn> ( Ex ? { Ev, si6[3:0] } : si6 )
-
-* Ex reset to 0 after all ops but "ext"
-
-notes
------
-- consider changing ext to use si10 instead and the reclaimed two bits
- to open up more instruction set space
-- consider allowing ext to work with b/bl and/or bz/bnz for long branches
-- in which case maybe si11->si10 and compact branch instruction footprint
- a bit too
-
diff --git a/hdl/cpu/alu.v b/hdl/cpu/alu.v
@@ -1,53 +0,0 @@
-// Copyright 2015, Brian Swetland <swetland@frotz.net>
-// Licensed under the Apache License, Version 2.0.
-
-`timescale 1ns / 1ps
-
-module alu #(
- parameter DWIDTH = 16,
- parameter SWIDTH = 4
- )(
- input [3:0]op,
- input [DWIDTH-1:0]adata,
- input [DWIDTH-1:0]bdata,
- output reg[DWIDTH-1:0]rdata
- );
-
-`ifdef BIT_OPS
-wire [DWIDTH-1:0]bits = (1 << bdata[SWIDTH-1:0]);
-`endif
-
-always @(*) begin
- case (op)
- 4'b0000: rdata = bdata;
- 4'b0001: rdata = adata & bdata;
- 4'b0010: rdata = adata | bdata;
- 4'b0011: rdata = adata ^ bdata;
- 4'b0100: rdata = adata + bdata;
- 4'b0101: rdata = adata - bdata;
- 4'b0110: rdata = adata * bdata;
- 4'b0111: rdata = { bdata[7:0], adata[7:0] };
- 4'b1000: rdata = { {(DWIDTH-1){1'b0}}, adata < bdata };
- 4'b1001: rdata = { {(DWIDTH-1){1'b0}}, adata <= bdata };
-`ifdef FULL_SHIFTER
- 4'b1010: rdata = adata >> bdata[SWIDTH-1:0];
- 4'b1011: rdata = adata << bdata[SWIDTH-1:0];
-`else
- 4'b1010: rdata = { 1'b0, adata[DWIDTH-1:1] };
- 4'b1011: rdata = { adata[DWIDTH-2:0], 1'b0 };
-`endif
-`ifdef BIT_OPS
- 4'b1100: rdata = adata | bits;
- 4'b1101: rdata = adata & (~bits);
- 4'b1110: rdata = adata & bits;
- 4'b1111: rdata = bits;
-`else
- 4'b1100: rdata = {DWIDTH{1'bX}};
- 4'b1101: rdata = {DWIDTH{1'bX}};
- 4'b1110: rdata = {DWIDTH{1'bX}};
- 4'b1111: rdata = {DWIDTH{1'bX}};
-`endif
- endcase
-end
-
-endmodule
diff --git a/hdl/cpu/cpu.v b/hdl/cpu/cpu.v
@@ -1,388 +0,0 @@
-// Copyright 2015, Brian Swetland <swetland@frotz.net>
-// Licensed under the Apache License, Version 2.0.
-
-`timescale 1ns / 1ps
-
-module cpu #(
- parameter RWIDTH = 16,
- parameter SWIDTH = 4
- )(
- input clk,
-`ifdef WITH_DEBUG
- output [RWIDTH-1:0]debug_data
- output [3:0]debug_op,
- output debug_wr,
-`endif
- output [15:0]mem_raddr_o,
- input [15:0]mem_rdata_i,
- output [15:0]mem_waddr_o,
- output [15:0]mem_wdata_o,
- output mem_wr_o,
- output mem_rd_o,
- input reset
- );
-
-localparam AWIDTH = 16;
-localparam DWIDTH = 16;
-localparam IWIDTH = 16;
-
-// control signals
-reg do_fetch;
-reg do_load;
-reg do_store;
-wire do_wreg;
-reg [1:0]do_sel_bdata;
-reg [1:0]do_sel_wsel;
-reg [1:0]do_sel_branch;
-reg [1:0]do_sel_alu_op;
-reg do_exe_alu;
-reg do_exe_load;
-reg do_exe_branch;
-reg do_load_pc;
-
-// processor registers
-reg [AWIDTH-1:0]pc = 16'b0;
-reg [15:0]ir = 16'b0;
-reg ir_valid = 1'b0;
-reg ir_loading = 1'b0;
-
-reg [AWIDTH-1:0]pc_next;
-reg [15:0]ir_next;
-reg ir_valid_next;
-reg ir_loading_next;
-
-// registers that allow/disallow EXEC/LOAD and IMMEDIATE
-reg exe_alu = 1'b0;
-reg exe_load = 1'b0;
-reg exe_branch = 1'b0;
-
-// registers loaded during DECODE for use in EXEC/LOAD
-reg [3:0]alu_op = 4'b0;
-reg [RWIDTH-1:0]adata = 16'b0;
-reg [RWIDTH-1:0]bdata = 16'b0;
-reg [3:0]wsel = 4'b0;
-
-// in/out of alu
-wire [RWIDTH-1:0]alu_rdata;
-
-// values computed
-wire [3:0]ir_asel = ir[7:4];
-wire [3:0]ir_bsel = ir[11:8];
-wire [RWIDTH-1:0]ir_imm_s4 = { {(RWIDTH-3) {ir[15]}}, ir[14:12] };
-wire [RWIDTH-1:0]ir_imm_s8 = { {(RWIDTH-7) {ir[15]}}, ir[14:8] };
-wire [RWIDTH-1:0]ir_imm_s12 = { {(RWIDTH-11){ir[15]}}, ir[14:4] };
-
-// in/out of reg file
-wire [3:0]regs_asel = ir_asel;
-wire [3:0]regs_bsel = ir_bsel;
-wire [RWIDTH-1:0]regs_wdata = exe_load ? { {(RWIDTH-DWIDTH){1'b0}}, mem_rdata_i } : alu_rdata;
-wire [RWIDTH-1:0]regs_adata;
-wire [RWIDTH-1:0]regs_bdata;
-
-wire [RWIDTH-1:0]load_store_addr = regs_bdata + ir_imm_s4;
-
-wire [AWIDTH-1:0]new_pc = exe_branch ? branch_target : (pc + 16'd1);
-
-reg [AWIDTH-1:0]branch_target;
-
-localparam BR_REL_S8 = 2'b00; // PC + S8 a short branch
-localparam BR_REL_S12 = 2'b01; // PC + S12 a long branch
-localparam BR_ABS_RB = 2'b10; // RB an indirect branch
-
-wire [RWIDTH-1:0]branch_imm = do_sel_branch[0] ? ir_imm_s12 : ir_imm_s8;
-wire [RWIDTH-1:0]branch_tgt = do_sel_branch[1] ? regs_bdata : (pc + branch_imm);
-wire [AWIDTH-1:0]branch_target_next = branch_tgt[AWIDTH-1:0];
-
-// memory interface
-assign mem_wr_o = do_store;
-assign mem_rd_o = 1;
-assign mem_raddr_o = do_load ? load_store_addr[AWIDTH-1:0] : pc_next;
-assign mem_waddr_o = load_store_addr[AWIDTH-1:0];
-assign mem_wdata_o = regs_adata[AWIDTH-1:0];
-
-always_comb begin
- ir_next = ir;
- ir_valid_next = ir_valid;
- ir_loading_next = ir_loading;
-
- do_load_pc = 1'b0;
-
- // we try to read an instruction every cycle
- // unless we're pre-empted by a data load
- //XXX don't issue a read if we know it's useless?
- ir_loading_next = ~do_load;
-
- if (exe_branch) begin
- // branch is always highest priority
- ir_valid_next = 1'b0;
- do_load_pc = 1'b1;
- end else if (ir_loading) begin
- // we've read an instruction
- if ((~ir_valid) | do_fetch) begin
- // ir was empty or is being consumed
- // fill it with the just-read instruction
- // and advance the pc
- ir_next = mem_rdata_i;
- ir_valid_next = 1'b1;
- do_load_pc = 1'b1;
- end else if (do_fetch) begin
- // ir has been consumed if it was non-empty
- ir_valid_next = 1'b0;
- end
- end else begin
- // not loading
- if (do_fetch) begin
- ir_valid_next = 1'b0;
- end
- end
-
- pc_next = do_load_pc ? new_pc : pc;
-end
-
-/*
-always_ff @(posedge clk) begin
- pc <= reset ? 16'd0 : pc_next;
- ir_valid <= reset ? 1'd0 : ir_valid_next;
- ir_loading <= reset ? 1'd0 : ir_loading_next;
- ir <= ir_next;
-end
-*/
-
-always_ff @(posedge clk) begin
- if (reset) begin
- pc <= 16'd0;
- ir_valid <= 1'd0;
- ir_loading <= 1'd0;
- end else begin
- pc <= pc_next;
- ir_valid <= ir_valid_next;
- ir_loading <= ir_loading_next;
- end
- ir <= ir_next;
-end
-
-localparam BDATA_RB = 2'b00;
-localparam BDATA_PC = 2'b01;
-localparam BDATA_S4 = 2'b10;
-localparam BDATA_S8 = 2'b11;
-reg [RWIDTH-1:0]bdata_mux;
-always_comb begin
- case (do_sel_bdata)
- BDATA_RB: bdata_mux = regs_bdata;
- BDATA_PC: bdata_mux = pc;
- BDATA_S4: bdata_mux = ir_imm_s4;
- BDATA_S8: bdata_mux = ir_imm_s8;
- endcase
-end
-
-localparam WSEL_RA = 2'b00;
-localparam WSEL_RB = 2'b01;
-localparam WSEL_OP = 2'b10;
-localparam WSEL_LR = 2'b11;
-reg [3:0]wsel_mux;
-always_comb begin
- case (do_sel_wsel)
- WSEL_RA: wsel_mux = ir[7:4];
- WSEL_RB: wsel_mux = ir[11:8];
- WSEL_OP: wsel_mux = { 2'b0, ir[1:0] };
- WSEL_LR: wsel_mux = 4'd14;
- endcase
-end
-
-localparam ALU_MOV = 2'b00;
-localparam ALU_MHI = 2'b01;
-localparam ALU_FN_HI = 2'b10;
-localparam ALU_FN_LO = 2'b11;
-reg [3:0]alu_op_mux;
-always_comb begin
- case (do_sel_alu_op)
- ALU_MOV: alu_op_mux = 4'b0000;
- ALU_MHI: alu_op_mux = 4'b0111;
- ALU_FN_HI: alu_op_mux = ir[15:12];
- ALU_FN_LO: alu_op_mux = ir[11:8];
- endcase
-end
-
-wire regs_adata_zero = (regs_adata == 16'd0);
-
-assign do_wreg = exe_alu | exe_load;
-
-//`define WITH_BYPASS
-
-localparam USE_RA = 2'b10;
-localparam USE_RB = 2'b01;
-localparam USE_RA_RB = 2'b11;
-localparam USE_NONE = 2'b00;
-reg [1:0]using;
-wire conflict_a = (wsel == ir_asel) & using[1];
-wire conflict_b = (wsel == ir_bsel) & using[0];
-
-`ifdef WITH_DEBUG
-assign debug_op = ir_bsel;
-assign debug_data = regs_adata;
-assign debug_wr = do_fetch & ir_valid & (ir[15:12] == 4'b0010) & (ir[3:0] == 4'b1110);
-`endif
-
-always_comb begin
- // decode stage
- do_fetch = 1'b1;
- do_load = 1'b0;
- do_store = 1'b0;
- do_sel_branch = BR_ABS_RB;
- do_sel_bdata = BDATA_RB;
- do_sel_wsel = WSEL_RA;
- do_sel_alu_op = ALU_MOV;
-
- do_exe_alu = 1'b0;
- do_exe_load = 1'b0;
- do_exe_branch = 1'b0;
-
- using = USE_RA_RB;
-
- if (exe_branch) begin
- do_fetch = 1'b0;
- end
-`ifndef WITH_BYPASS
- else if (exe_alu | exe_load) begin
- do_fetch = ~(conflict_a | conflict_b);
- end
-`endif
-
- casez (ir[3:0])
- 4'b0000: begin // mov Ra, imm
- using = USE_NONE;
- do_exe_alu = 1'b1;
- do_sel_alu_op = ALU_MOV;
- do_sel_wsel = WSEL_RA;
- do_sel_bdata = BDATA_S8;
- end
- 4'b0001: begin // mhi Ra, imm
- using = USE_RA;
- do_exe_alu = 1'b1;
- do_sel_alu_op = ALU_MHI;
- do_sel_wsel = WSEL_RA;
- do_sel_bdata = BDATA_S8;
- end
- 4'b0010: begin // alu Ra, Ra, Rb
- using = USE_RA_RB;
- do_exe_alu = 1'b1;
- do_sel_alu_op = ALU_FN_HI;
- do_sel_wsel = WSEL_RA;
- do_sel_bdata = BDATA_RB;
- end
- 4'b0011: begin // alu Ra, Ra, imm4
- using = USE_RA;
- do_exe_alu = 1'b1;
- do_sel_alu_op = ALU_FN_LO;
- do_sel_wsel = WSEL_RA;
- do_sel_bdata = BDATA_S4;
- end
- 4'b01??: begin // alu Rd, Ra, Rb
- using = USE_RA_RB;
- do_exe_alu = 1'b1;
- do_sel_alu_op = ALU_FN_HI;
- do_sel_wsel = WSEL_OP;
- do_sel_bdata = BDATA_RB;
- end
- 4'b1000: begin // lw Ra, [Rb, imm]
- using = USE_RB;
- do_exe_load = 1'b1;
- do_load = ir_valid;
- end
- 4'b1001: begin // sw Ra, [Rb, imm]
- using = USE_RA_RB;
- do_store = ir_valid;
- end
- 4'b1010: begin // bnz Ra, rel8
- using = USE_RA;
- do_exe_branch = ~regs_adata_zero;
- do_sel_branch = BR_REL_S8;
- end
- 4'b1011: begin // bz Ra, rel8
- using = USE_RA;
- do_exe_branch = regs_adata_zero;
- do_sel_branch = BR_REL_S8;
- end
- 4'b1100: begin // b rel12
- using = USE_NONE;
- do_exe_branch = 1'b1;
- do_sel_branch = BR_REL_S12;
- end
- 4'b1101: begin // bl rel12
- using = USE_NONE;
- do_exe_alu = 1'b1;
- do_exe_branch = 1'b1;
- do_sel_branch = BR_REL_S12;
- do_sel_alu_op = ALU_MOV;
- do_sel_bdata = BDATA_PC;
- do_sel_wsel = WSEL_LR;
- end
- 4'b1110: begin
- if (ir[15:13] == 3'b000) begin // b Rb / bl Rb
- using = USE_RB;
- do_exe_branch = 1'b1;
- do_sel_branch = BR_ABS_RB;
- if (ir[12]) begin
- do_exe_alu = 1'b1;
- do_sel_alu_op = ALU_MOV;
- do_sel_bdata = BDATA_PC;
- do_sel_wsel = WSEL_LR;
- end
- end
- end
- default: begin
- // treat undefined as NOP
- end
- endcase
-end
-
-always_ff @(posedge clk) begin
- alu_op <= alu_op_mux;
- adata <= regs_adata;
- bdata <= bdata_mux;
- wsel <= wsel_mux;
- exe_alu <= ir_valid & do_fetch & do_exe_alu;
- exe_load <= ir_valid & do_fetch & do_exe_load;
- exe_branch <= ir_valid & do_fetch & do_exe_branch;
- branch_target <= branch_target_next;
-
-end
-
-wire [RWIDTH-1:0]raw_regs_adata;
-wire [RWIDTH-1:0]raw_regs_bdata;
-
-regfile #(
- .DWIDTH(RWIDTH)
- )regs(
- .clk(clk),
- .asel(regs_asel),
- .bsel(regs_bsel),
- .adata(raw_regs_adata),
- .bdata(raw_regs_bdata),
- .wsel(wsel),
- .wdata(regs_wdata),
- .wreg(do_wreg)
- );
-
-`ifdef WITH_BYPASS
-wire bypass_a = do_wreg & (wsel == ir_asel) & (~exe_load);
-wire bypass_b = do_wreg & (wsel == ir_bsel) & (~exe_load);
-assign regs_adata = bypass_a ? regs_wdata : raw_regs_adata;
-assign regs_bdata = bypass_b ? regs_wdata : raw_regs_bdata;
-`else
-assign regs_adata = raw_regs_adata;
-assign regs_bdata = raw_regs_bdata;
-`endif
-
-alu #(
- .DWIDTH(RWIDTH),
- .SWIDTH(SWIDTH)
- )alu0(
- .op(alu_op),
- .adata(adata),
- .bdata(bdata),
- .rdata(alu_rdata)
- );
-
-endmodule
-
diff --git a/hdl/cpu/regfile.v b/hdl/cpu/regfile.v
@@ -1,29 +0,0 @@
-// Copyright 2015, Brian Swetland <swetland@frotz.net>
-// Licensed under the Apache License, Version 2.0.
-
-`timescale 1ns / 1ps
-
-module regfile #(
- parameter AWIDTH = 4,
- parameter DWIDTH = 16
- )(
- input clk,
- input [AWIDTH-1:0]asel,
- input [AWIDTH-1:0]bsel,
- input [AWIDTH-1:0]wsel,
- input wreg,
- output [DWIDTH-1:0]adata,
- output [DWIDTH-1:0]bdata,
- input [DWIDTH-1:0]wdata
- );
-
-reg [DWIDTH-1:0] R[0:((1<<AWIDTH)-1)];
-
-always @(posedge clk) begin
- if (wreg)
- R[wsel] <= wdata;
-end
-assign adata = R[asel];
-assign bdata = R[bsel];
-
-endmodule