URL
https://opencores.org/ocsvn/klc32/klc32/trunk
Subversion Repositories klc32
Compare Revisions
- This comparison shows the changes necessary to convert path
/klc32/trunk
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/rtl/verilog/WRITEBACK.v
0,0 → 1,146
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// WRITEBACK.v - update register file / generate flags |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
WRITEBACK: |
begin |
if (opcode==`POP) |
state <= POP1; |
else |
state <= WRITE_FLAGS; |
if (opcode!=`CMPI && !(opcode==`RR && func==`CMP)) begin |
regfile[Rn] <= res; |
if (Rn==5'd31) begin |
if (sf) ssp <= res; |
else usp <= res; |
end |
end |
case(opcode) |
`R: |
case(func) |
`ABS: |
begin |
vf <= res[31]; |
cf <= 1'b0; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`SGN,`NOT,`EXTB,`EXTH: |
begin |
vf <= 1'b0; |
cf <= 1'b0; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`NEG: |
begin |
vf <= v_rr; |
cf <= c_rr; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
endcase |
`RR: |
case(func) |
`ADD,`SUB: |
begin |
vf <= v_rr; |
cf <= c_rr; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`CMP: |
begin |
vf <= 1'b0; |
cf <= c_rr; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`AND,`OR,`EOR,`NAND,`NOR,`ENOR,`MIN,`MAX, |
`LWX,`LHX,`LBX,`LHUX,`LBUX: |
begin |
vf <= 1'b0; |
cf <= 1'b0; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`SHL,`ROL: |
begin |
vf <= 1'b0; |
cf <= shlo[32]; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`SHR,`ROR: |
begin |
vf <= 1'b0; |
cf <= shro[31]; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`BCDADD: |
begin |
vf <= 1'b0; |
cf <= bcdaddc; |
nf <= res[7]; |
zf <= res[7:0]==8'd0; |
end |
`BCDSUB: |
begin |
vf <= 1'b0; |
cf <= bcdsubc; |
nf <= res[7]; |
zf <= res[7:0]==8'd0; |
end |
endcase |
`ADDI,`SUBI: |
begin |
vf <= v_ri; |
cf <= c_ri; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`CMPI: |
begin |
vf <= 1'b0; |
cf <= c_ri; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`ANDI,`ORI,`EORI,`LW,`LH,`LB,`LHU,`LBU,`POP,`TAS: |
begin |
vf <= 1'b0; |
cf <= 1'b0; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`LINK: |
begin |
state <= IFETCH; |
if (sf) |
ssp <= ssp + imm; |
else |
usp <= usp + imm; |
end |
endcase |
end |
|
/rtl/verilog/KLC32.v
0,0 → 1,437
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32.v |
// - 32 bit CPU |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
`define STACK_VECTOR 32'h00000000 |
`define RESET_VECTOR 32'h00000004 |
`define NMI_VECTOR 32'h0000007C |
`define IRQ_VECTOR 32'h00000064 |
`define TRAP_VECTOR 32'h00000080 |
`define TRAPV_VECTOR 32'h0000001C |
`define TRACE_VECTOR 32'h00000024 |
`define BUS_ERR_VECTOR 32'h00000008 |
`define ILLEGAL_INSN 32'h00000010 |
`define PRIVILEGE_VIOLATION 32'h00000020 |
|
`define MISC 6'd0 |
`define JMP32 6'd32 |
`define JSR32 6'd33 |
`define RTS 6'd34 |
`define RTI 6'd35 |
`define TRACE_ON 6'd48 |
`define TRACE_OFF 6'd49 |
`define USER_MODE 6'd50 |
`define SET_IM 6'd51 |
`define RST 6'd52 |
`define STOP 6'd53 |
`define R 6'd1 |
`define ABS 6'd4 |
`define SGN 6'd2 |
`define NEG 6'd3 |
`define NOT 6'd4 |
`define EXTB 6'd5 |
`define EXTH 6'd6 |
`define MOV_REG2USP 6'd32 |
`define MOV_USP2REG 6'd33 |
`define MOV_CRn2CRn 6'd48 |
`define MOV_CRn2REG 6'd49 |
`define MOV_REG2CRn 6'd50 |
`define MOV_REG2CR 6'd51 |
`define MOV_CR2REG 6'd52 |
`define MOV_REG2IM 6'd53 |
`define MOV_IM2REG 6'd54 |
`define MFTICK 6'd55 |
`define MTLC 6'd56 |
`define MFLC 6'd57 |
`define EXEC 6'd63 |
`define RR 6'd2 |
`define ADD 6'd4 |
`define SUB 6'd5 |
`define CMP 6'd6 |
`define AND 6'd8 |
`define OR 6'd9 |
`define EOR 6'd10 |
`define NAND 6'd12 |
`define NOR 6'd13 |
`define ENOR 6'd14 |
`define SHL 6'd16 |
`define SHR 6'd17 |
`define ROL 6'd18 |
`define ROR 6'd19 |
`define JMP_RR 6'd20 |
`define JSR_RR 6'd21 |
`define MAX 6'd22 |
`define MIN 6'd23 |
`define MULU 6'd24 |
`define MULUH 6'd25 |
`define CROR 6'd32 |
`define CRAND 6'd33 |
`define CRXOR 6'd34 |
`define CRNOR 6'd35 |
`define CRNAND 6'd36 |
`define CRXNOR 6'd37 |
`define LWX 6'd48 |
`define LHX 6'd49 |
`define LBX 6'd50 |
`define LHUX 6'd51 |
`define LBUX 6'd52 |
`define SWX 6'd56 |
`define SHX 6'd57 |
`define SBX 6'd58 |
`define BCDADD 6'd60 |
`define BCDSUB 6'd61 |
`define RRR 6'd3 |
`define ADDI 6'd4 |
`define SUBI 6'd5 |
`define CMPI 6'd6 |
`define ANDI 6'd8 |
`define ORI 6'd9 |
`define EORI 6'd10 |
`define Bcc 6'd16 |
`define BRA 4'd0 |
`define BRN 4'd1 |
`define BHI 4'd2 |
`define BLS 4'd3 |
`define BHS 4'd4 |
`define BLO 4'd5 |
`define BNE 4'd6 |
`define BEQ 4'd7 |
`define BVC 4'd8 |
`define BVS 4'd9 |
`define BPL 4'd10 |
`define BMI 4'd11 |
`define BGE 4'd12 |
`define BLT 4'd13 |
`define BGT 4'd14 |
`define BLE 4'd15 |
`define TRAPcc 6'd17 |
`define TRAP 4'd0 |
`define TRN 4'd1 |
`define THI 4'd2 |
`define TLS 4'd3 |
`define THS 4'd4 |
`define TLO 4'd5 |
`define TNE 4'd6 |
`define TEQ 4'd7 |
`define TVC 4'd8 |
`define TVS 4'd9 |
`define TPL 4'd10 |
`define TMI 4'd11 |
`define TGE 4'd12 |
`define TLT 4'd13 |
`define TGT 4'd14 |
`define TLE 4'd15 |
`define SETcc 6'd18 |
`define SET 4'd0 |
`define STN 4'd1 |
`define SHI 4'd2 |
`define SLS 4'd3 |
`define SHS 4'd4 |
`define SLO 4'd5 |
`define SNE 4'd6 |
`define SEQ 4'd7 |
`define SVC 4'd8 |
`define SVS 4'd9 |
`define SPL 4'd10 |
`define SMI 4'd11 |
`define SGE 4'd12 |
`define SLT 4'd13 |
`define SGT 4'd14 |
`define SLE 4'd15 |
`define CRxx 6'd19 |
`define ANDI_CCR 5'd8 |
`define ORI_CCR 5'd9 |
`define EORI_CCR 5'd10 |
`define JMP 6'd20 |
`define JSR 6'd21 |
|
`define TAS 6'd46 |
`define UNLK 6'd47 |
`define LW 6'd48 |
`define LH 6'd49 |
`define LB 6'd50 |
`define LHU 6'd51 |
`define LBU 6'd52 |
`define POP 6'd53 |
`define LINK 6'd54 |
`define PEA 6'd55 |
`define SW 6'd56 |
`define SH 6'd57 |
`define SB 6'd58 |
`define PUSH 6'd59 |
`define NOP 6'd60 |
|
|
module KLC32(rst_i, clk_i, ipl_i, vpa_i, halt_i, inta_o, fc_o, rst_o, cyc_o, stb_o, ack_i, err_i, sel_o, we_o, adr_o, dat_i, dat_o); |
parameter IFETCH = 8'd1; |
parameter REGFETCHA = 8'd2; |
parameter REGFETCHB = 8'd3; |
parameter EXECUTE = 8'd4; |
parameter MEMORY1 = 8'd5; |
parameter MEMORY1_ACK = 8'd6; |
parameter WRITEBACK = 8'd7; |
parameter JSR1 = 8'd10; |
parameter JSR2 = 8'd11; |
parameter JSRShort = 8'd12; |
parameter RTS = 8'd13; |
parameter JMP = 8'd14; |
parameter LOAD_SP = 8'd15; |
parameter VECTOR = 8'd16; |
parameter INTA = 8'd20; |
parameter FETCH_VECTOR = 8'd21; |
parameter TRAP1 = 8'd22; |
parameter TRAP2 = 8'd23; |
parameter TRAP3 = 8'd24; |
parameter RTI1 = 8'd25; |
parameter RTI2 = 8'd26; |
parameter RTI3 = 8'd27; |
parameter TRAP = 8'd28; |
parameter RESET = 8'd29; |
parameter JSR32 = 8'd30; |
parameter JMP32 = 8'd31; |
parameter WRITE_FLAGS = 8'd32; |
parameter FETCH_IMM32 = 8'd33; |
parameter REGFETCHC = 8'd34; |
parameter PUSH1 = 8'd35; |
parameter PUSH2 = 8'd36; |
parameter PUSH3 = 8'd37; |
parameter POP1 = 8'd38; |
parameter POP2 = 8'd39; |
parameter POP3 = 8'd40; |
parameter LINK = 8'd41; |
parameter UNLK = 8'd42; |
parameter TAS = 8'd43; |
parameter TAS2 = 8'd44; |
parameter PEA = 8'd45; |
input rst_i; |
input clk_i; |
input [2:0] ipl_i; |
input vpa_i; |
input halt_i; |
output inta_o; |
reg inta_o; |
output [2:0] fc_o; |
reg [2:0] fc_o; |
output rst_o; |
reg rst_o; |
output cyc_o; |
reg cyc_o; |
output stb_o; |
reg stb_o; |
input ack_i; |
input err_i; |
output we_o; |
reg we_o; |
output [3:0] sel_o; |
reg [3:0] sel_o; |
output [31:0] adr_o; |
reg [31:0] adr_o; |
input [31:0] dat_i; |
output [31:0] dat_o; |
reg [31:0] dat_o; |
|
reg [7:0] state; |
reg [31:0] ir; |
reg tf,sf; |
reg [31:0] pc; |
reg [31:0] usp,ssp; |
reg [31:0] lc; |
wire [5:0] opcode=ir[31:26]; |
reg [5:0] mopcode; |
wire [5:0] func=ir[5:0]; |
wire [3:0] cond=ir[19:16]; |
wire [31:0] brdisp = {{16{ir[15]}},ir[15:2],2'b0}; |
reg [4:0] Rn; |
reg [31:0] regfile [31:0]; |
wire [31:0] rfo1 = regfile[Rn]; |
wire [31:0] rfo = (Rn==5'd0) ? 32'd0 : (Rn==5'd31) ? (sf ? ssp : usp) : rfo1; |
reg vf,nf,cf,zf; |
reg [2:0] im; |
reg [2:0] iplr; |
reg [7:0] vecnum; |
reg [31:0] vector; |
reg [31:0] ea; |
reg prev_nmi; |
reg nmi_edge; |
reg [31:0] sr1; |
reg [31:0] tgt; |
reg [31:0] a,b,c,imm; |
wire signed [31:0] as = a; |
wire signed [31:0] bs = b; |
wire [63:0] muluo = a * b; |
reg [31:0] res; |
reg [3:0] cr0,cr1,cr2,cr3,cr4,cr5,cr6,cr7; |
wire [31:0] cr = {cr7,cr6,cr5,cr4,cr3,cr2,cr1,cr0}; |
wire [31:0] sr = {tf,1'b0,sf,2'b00,im,16'd0}; |
reg [31:0] tick; |
wire IsSubi = opcode==`SUBI; |
wire IsCmpi = opcode==`CMPI; |
wire IsSub = opcode==`RR && func==`SUB; |
wire IsCmp = opcode==`RR && func==`CMP; |
wire IsNeg = opcode==`R && func==`NEG; |
|
wire hasConst16 = |
opcode==`ADDI || opcode==`SUBI || opcode==`CMPI || |
opcode==`ANDI || opcode==`ORI || opcode==`EORI || |
opcode==`LW || opcode==`LH || opcode==`LB || opcode==`LHU || opcode==`LBU || |
opcode==`SW || opcode==`SH || opcode==`SB || |
opcode==`PEA || opcode==`TAS || opcode==`LINK |
; |
wire isStop = |
opcode==`MISC && (func==`STOP) |
; |
wire isIllegalOpcode = |
(opcode >= 6'd22 && opcode <= 6'd45) || opcode==6'd7 || |
(opcode >= 6'd12 && opcode <= 6'd15) |
; |
|
wire c_ri,c_rr; |
wire v_ri,v_rr; |
carry u1 (.op(IsSubi|IsCmpi), .a(a[31]), .b(imm[31]), .s(res[31]), .c(c_ri)); |
carry u2 (.op(IsSub|IsCmp|IsNeg), .a(a[31]), .b(b[31]), .s(res[31]), .c(c_rr)); |
overflow u3 (.op(IsSubi|IsCmpi), .a(a[31]), .b(imm[31]), .s(res[31]), .v(v_ri)); |
overflow u4 (.op(IsSub|IsCmp|IsNeg), .a(a[31]), .b(b[31]), .s(res[31]), .v(v_rr)); |
|
wire [7:0] bcdaddo,bcdsubo; |
wire bcdaddc,bcdsubc; |
BCDAdd u5 (.ci(cr0[0]),.a(a[7:0]),.b(b[7:0]),.o(bcdaddo),.c(bcdaddc)); |
BCDSub u6 (.ci(cr0[0]),.a(a[7:0]),.b(b[7:0]),.o(bcdsubo),.c(bcdsubc)); |
|
wire [63:0] shlo = {32'd0,a} << b[4:0]; |
wire [63:0] shro = {a,32'd0} >> b[4:0]; |
|
function GetCrBit; |
input [4:0] Rn; |
begin |
case(Rn[4:2]) |
3'd0: GetCrBit = cr0[Rn[1:0]]; |
3'd1: GetCrBit = cr1[Rn[1:0]]; |
3'd2: GetCrBit = cr2[Rn[1:0]]; |
3'd3: GetCrBit = cr3[Rn[1:0]]; |
3'd4: GetCrBit = cr4[Rn[1:0]]; |
3'd5: GetCrBit = cr5[Rn[1:0]]; |
3'd6: GetCrBit = cr6[Rn[1:0]]; |
3'd7: GetCrBit = cr7[Rn[1:0]]; |
endcase |
end |
endfunction |
|
function [3:0] GetCr; |
input [2:0] Rn; |
begin |
case(Rn) |
3'd0: GetCr = cr0; |
3'd1: GetCr = cr1; |
3'd2: GetCr = cr2; |
3'd3: GetCr = cr3; |
3'd4: GetCr = cr4; |
3'd5: GetCr = cr5; |
3'd6: GetCr = cr6; |
3'd7: GetCr = cr7; |
endcase |
end |
endfunction |
|
wire [3:0] crc = GetCr(Rn); |
wire cr_zf = crc[2]; |
wire cr_nf = crc[3]; |
wire cr_cf = crc[0]; |
wire cr_vf = crc[1]; |
|
//----------------------------------------------------------------------------- |
// Clock control |
// - reset or NMI reenables the clock |
// - this circuit must be under the clk_i domain |
//----------------------------------------------------------------------------- |
// |
reg cpu_clk_en; |
reg clk_en; |
wire clk; |
BUFGCE u20 (.CE(cpu_clk_en), .I(clk_i), .O(clk) ); |
|
always @(posedge clk_i) |
if (rst_i) begin |
cpu_clk_en <= 1'b1; |
end |
else begin |
if (ipl_i==3'd7) |
cpu_clk_en <= 1'b1; |
else |
cpu_clk_en <= clk_en; |
end |
|
|
//----------------------------------------------------------------------------- |
//----------------------------------------------------------------------------- |
|
always @(posedge clk) |
if (rst_i) begin |
prev_nmi <= 1'b0; |
nmi_edge <= 1'b0; |
state <= RESET; |
im <= 3'b111; |
sf <= 1'b1; |
tf <= 1'b0; |
inta_o <= 1'b0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
we_o <= 1'b0; |
rst_o <= 1'b0; |
clk_en <= 1'b1; |
tick <= 32'd0; |
end |
else begin |
tick <= tick + 32'd1; |
clk_en <= 1'b1; |
rst_o <= 1'b0; |
prev_nmi <= ipl_i==3'd7; |
if (!prev_nmi && (ipl_i==3'd7)) |
nmi_edge <= 1'b1; |
|
case(state) |
`include "RESET.v" |
`include "VECTOR.v" |
`include "IFETCH.v" |
|
`include "REGFETCHA.v" |
`include "REGFETCHB.v" |
`include "REGFETCHC.v" |
`include "FETCH_IMM32.v" |
`include "EXECUTE.v" |
`include "MEMORY.v" |
`include "PUSH.v" |
`include "POP.v" |
`include "WRITEBACK.v" |
`include "WRITE_FLAGS.v" |
|
`include "JMP.v" |
`include "JSR.v" |
`include "RTS.v" |
`include "INTA.v" |
`include "TRAP.v" |
`include "RTI.v" |
|
endcase |
end |
|
endmodule |
/rtl/verilog/PUSH.v
0,0 → 1,127
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// PUSH.v - push type instructions |
// PUSH / PEA / LINK |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
PUSH1: |
if (ir[25:1]==25'd0) |
state <= IFETCH; |
else begin |
Rn <= ir[25:21]; |
ir[25:0] <= {ir[20:1],6'b0}; |
state <= PUSH2; |
end |
PUSH2: |
begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= sf ? ssp - 32'd4 : usp - 32'd4; |
dat_o <= rfo; |
state <= PUSH3; |
end |
PUSH3: |
if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
if (sf) |
ssp <= ssp - 32'd4; |
else |
usp <= usp - 32'd4; |
state <= PUSH1; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
|
PEA: |
if (!cyc_o) begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= sf ? ssp - 32'd4 : usp - 32'd4; |
dat_o <= ea; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
if (sf) |
ssp <= ssp - 32'd4; |
else |
usp <= usp - 32'd4; |
state <= IFETCH; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
|
LINK: |
if (!cyc_o) begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= sf ? ssp - 32'd4 : usp - 32'd4; |
dat_o <= a; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
if (sf) begin |
ssp <= ssp - 32'd4; |
res <= ssp - 32'd4; |
end |
else begin |
usp <= usp - 32'd4; |
res <= usp - 32'd4; |
end |
state <= WRITEBACK; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
/rtl/verilog/RESET.v
0,0 → 1,31
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// RESET.v |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
RESET: |
begin |
im <= 3'b111; |
sf <= 1'b1; |
tf <= 1'b0; |
vector <= `STACK_VECTOR; |
state <= LOAD_SP; |
end |
/rtl/verilog/JMP.v
0,0 → 1,44
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// JMP.v |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
JMP32: |
if (!cyc_o) begin |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= pc; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
pc <= dat_i; |
state <= IFETCH; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
/rtl/verilog/REGFETCHA.v
0,0 → 1,140
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// REGFETCHA.v - fetch register A / execute some instructions |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
REGFETCHA: |
begin |
a <= rfo; |
b <= 32'd0; |
Rn <= ir[20:16]; |
if (opcode==`RR || opcode==`RRR) begin |
state <= REGFETCHB; |
end |
else begin |
if ((hasConst16 && ir[15:0]==16'h8000) || (isStop)) |
state <= FETCH_IMM32; |
else begin |
imm <= {{16{ir[15]}},ir[15:0]}; |
state <= EXECUTE; |
end |
end |
case(opcode) |
`MISC: |
case(func) |
`TRACE_ON: |
if (!sf) begin |
vector <= `PRIVILEGE_VIOLATION; |
state <= TRAP; |
end |
else begin |
tf <= 1'b1; |
state <= IFETCH; |
end |
`TRACE_OFF: |
if (!sf) begin |
vector <= `PRIVILEGE_VIOLATION; |
state <= TRAP; |
end |
else begin |
tf <= 1'b0; |
state <= IFETCH; |
end |
`SET_IM: |
if (!sf) begin |
vector <= `PRIVILEGE_VIOLATION; |
state <= TRAP; |
end |
else begin |
im <= ir[2:0]; |
state <= IFETCH; |
end |
`USER_MODE: begin sf <= 1'b0; state <= IFETCH; end |
`JMP32: state <= JMP32; |
`JSR32: state <= JSR32; |
`RTS: state <= RTS; |
`RTI: |
if (!sf) begin |
vector <= `PRIVILEGE_VIOLATION; |
state <= TRAP; |
end |
else |
state <= RTI1; |
`RST: |
if (!sf) begin |
vector <= `PRIVILEGE_VIOLATION; |
state <= TRAP; |
end |
else begin |
rst_o <= 1'b1; |
state <= IFETCH; |
end |
endcase |
`NOP: state <= IFETCH; |
`JSR: begin tgt <= {pc[31:26],ir[25:2],2'b00}; state <= JSR1; end |
`JMP: begin pc[25:2] <= ir[25:2]; state <= IFETCH; end |
`Bcc: |
case(cond) |
`BRA: begin pc <= pc + brdisp; state <= IFETCH; end |
`BEQ: begin if ( cr_zf) pc <= pc + brdisp; state <= IFETCH; end |
`BNE: begin if (!cr_zf) pc <= pc + brdisp; state <= IFETCH; end |
`BMI: begin if ( cr_nf) pc <= pc + brdisp; state <= IFETCH; end |
`BPL: begin if (!cr_zf) pc <= pc + brdisp; state <= IFETCH; end |
`BHI: begin if (!cr_cf & !cr_zf) pc <= pc + brdisp; state <= IFETCH; end |
`BLS: begin if (cf |zf) pc <= pc + brdisp; state <= IFETCH; end |
`BHS: begin if (!cr_cf) pc <= pc + brdisp; state <= IFETCH; end |
`BLO: begin if ( cr_cf) pc <= pc + brdisp; state <= IFETCH; end |
`BGT: begin if ((cr_nf & cr_vf & !cr_zf)|(!cr_nf & !cr_vf & !cr_zf)) pc <= pc + brdisp; state <= IFETCH; end |
`BLE: begin if (cr_zf | (cr_nf & !cr_vf) | (!cr_nf & cr_vf)) pc <= pc + brdisp; state <= IFETCH; end |
`BGE: begin if ((cr_nf & cr_vf)|(!cr_nf & !cr_vf)) pc <= pc + brdisp; state <= IFETCH; end |
`BLT: begin if ((cr_nf & !cr_vf)|(!cr_nf & cr_vf)) pc <= pc + brdisp; state <= IFETCH; end |
`BVS: begin if ( cr_vf) pc <= pc + brdisp; state <= IFETCH; end |
`BVC: begin if (!cr_vf) pc <= pc + brdisp; state <= IFETCH; end |
endcase |
`TRAPcc: |
case(cond) |
`TRAP: begin vector <= `TRAP_VECTOR + {ir[3:0],2'b00}; state <= TRAP; end |
`TEQ: begin if ( cr_zf) begin vector <= `TRAP_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`TNE: begin if (!cr_zf) begin vector <= `TRAP_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`TMI: begin if ( cr_nf) begin vector <= `TRAP_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`TPL: begin if (!cr_zf) begin vector <= `TRAP_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`THI: begin if (!cr_cf & !cr_zf) begin vector <= `TRAP_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`TLS: begin if (cf |zf) begin vector <= `TRAP_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`THS: begin if (!cr_cf) begin vector <= `TRAP_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`TLO: begin if ( cr_cf) begin vector <= `TRAP_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`TGT: begin if ((cr_nf & cr_vf & !cr_zf)|(!cr_nf & !cr_vf & !cr_zf)) begin vector <= `TRAP_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`TLE: begin if (cr_zf | (cr_nf & !cr_vf) | (!cr_nf & cr_vf)) begin vector <= `TRAP_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`TGE: begin if ((cr_nf & cr_vf)|(!cr_nf & !cr_vf)) begin vector <= `TRAP_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`TLT: begin if ((cr_nf & !cr_vf)|(!cr_nf & cr_vf)) begin vector <= `TRAP_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`TVS: begin if ( cr_vf) begin vector <= `TRAPV_VECTOR; state <= TRAP; end else state <= IFETCH; end |
`TVC: begin if (!cr_vf) begin vector <= `TRAPV_VECTOR; state <= TRAP; end else state <= IFETCH; end |
endcase |
`SETcc: Rn <= ir[15:11]; |
`PUSH: state <= PUSH1; |
`POP: state <= POP1; |
`UNLK: state <= UNLK; |
endcase |
if (isIllegalOpcode) begin |
vector <= `ILLEGAL_INSN; |
state <= TRAP; |
end |
end |
|
/rtl/verilog/REGFETCHB.v
0,0 → 1,32
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// REGFETCHB.v - fetch the B side register |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
REGFETCHB: |
begin |
b <= rfo; |
Rn <= ir[15:11]; |
if (opcode==`RRR || (opcode==`RR && (func==`SWX||func==`SHX||func==`SBX))) |
state <= REGFETCHC; |
else |
state <= EXECUTE; |
end |
/rtl/verilog/REGFETCHC.v
0,0 → 1,29
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// REGFETCHC.v - fetch the C side register |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
REGFETCHC: |
begin |
c <= rfo; |
Rn <= ir[10:6]; |
state <= EXECUTE; |
end |
/rtl/verilog/INTA.v
0,0 → 1,74
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// INTA.v - interrupt acknowledge |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
INTA: |
if (!cyc_o) begin |
fc_o <= 3'b111; |
inta_o <= 1'b1; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b0001; |
adr_o <= {27'h7FFFFFF,iplr,2'b00}; |
end |
else if (vpa_i) begin |
inta_o <= 1'b0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vecnum <= 32'd24 + iplr; |
state <= FETCH_VECTOR; |
end |
else if (ack_i) begin |
inta_o <= 1'b0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vecnum <= dat_i[7:0]; |
state <= FETCH_VECTOR; |
end |
else if (err_i) begin |
inta_o <= 1'b0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vecnum <= 32'd24; // Spurious interrupt |
state <= FETCH_VECTOR; |
end |
FETCH_VECTOR: |
if (!cyc_o) begin |
fc_o <= 3'b101; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= {vecnum,2'b00}; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= dat_i; |
state <= TRAP1; |
end |
// I don't bother with bus error checking here because if the cpu can't read the |
// vector table, bus error processing won't help. |
|
/rtl/verilog/RTI.v
0,0 → 1,76
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// RTI.v - return from interrupt / trap |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
RTI1: |
if (!cyc_o) begin |
fc_o <= {3'b101}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= ssp; |
end |
else if (ack_i) begin |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
im <= dat_i[18:16]; |
sf <= dat_i[21]; |
tf <= dat_i[23]; |
ssp <= ssp + 32'd4; |
state <= RTI2; |
end |
RTI2: |
if (!stb_o) begin |
fc_o <= {3'b101}; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= ssp; |
end |
else if (ack_i) begin |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
cr0 <= dat_i[3:0]; |
cr1 <= dat_i[7:4]; |
cr2 <= dat_i[11:8]; |
cr3 <= dat_i[15:12]; |
cr4 <= dat_i[19:16]; |
cr5 <= dat_i[23:20]; |
cr6 <= dat_i[27:24]; |
cr7 <= dat_i[31:28]; |
ssp <= ssp + 32'd4; |
state <= RTI3; |
end |
RTI3: |
if (!stb_o) begin |
fc_o <= {3'b101}; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= ssp; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
pc <= dat_i; |
ssp <= ssp + 32'd4; |
state <= IFETCH; |
end |
/rtl/verilog/POP.v
0,0 → 1,92
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// POP type instructions |
// POP / UNLK |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
POP1: |
if (ir[25:1]==25'd0) |
state <= IFETCH; |
else begin |
Rn <= ir[25:21]; |
ir[25:0] <= {ir[20:1],6'b0}; |
state <= POP2; |
end |
POP2: |
begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= sf ? ssp : usp; |
state <= POP3; |
end |
POP3: |
if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
if (sf) |
ssp <= ssp + 32'd4; |
else |
usp <= usp + 32'd4; |
res <= dat_i; |
state <= WRITEBACK; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
|
UNLK: |
if (!cyc_o) begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= a; |
if (sf) |
ssp <= a; |
else |
usp <= a; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
if (sf) |
ssp <= ssp + 32'd4; |
else |
usp <= usp + 32'd4; |
res <= dat_i; |
state <= WRITEBACK; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
|
/rtl/verilog/JSR.v
0,0 → 1,79
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// JSR.v - jump to subroutine |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
JSR32: |
if (!cyc_o) begin |
fc_o <= {sf,2'b10}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= pc; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
pc <= pc + 32'd4; |
tgt <= dat_i; |
state <= JSR1; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
JSR1: |
if (!cyc_o) begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= 4'b1111; |
if (sf) |
adr_o <= ssp - 32'd4; |
else |
adr_o <= usp - 32'd4; |
dat_o <= pc; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
if (sf) |
ssp <= ssp - 32'd4; |
else |
usp <= usp - 32'd4; |
pc <= tgt; |
state <= IFETCH; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
/rtl/verilog/FETCH_IMM32.v
0,0 → 1,46
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// FETCH_IMM32.v |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
FETCH_IMM32: |
if (!cyc_o) begin |
fc_o <= {sf,2'b10}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= pc; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
imm <= dat_i; |
pc <= pc + 32'd4; |
state <= EXECUTE; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
/rtl/verilog/IFETCH.v
0,0 → 1,75
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// IFETCH.v - fetch instructions |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
IFETCH: |
if (!cyc_o) begin |
if (halt_i) begin |
// empty - do nothing until non-halted |
end |
else if (nmi_edge) begin |
sr1 <= sr; |
im <= ipl_i; |
tf <= 1'b0; |
sf <= 1'b1; |
iplr <= 3'd7; |
nmi_edge <= 1'b0; |
state <= INTA; |
end |
else if (ipl_i > im) begin |
sr1 <= sr; |
im <= ipl_i; |
tf <= 1'b0; |
sf <= 1'b1; |
iplr <= ipl_i; |
state <= INTA; |
end |
else if (tf) begin |
sr1 <= sr; |
tf <= 1'b0; |
sf <= 1'b1; |
vector <= `TRACE_VECTOR; |
state <= TRAP; |
end |
else begin |
fc_o <= {sf,2'b10}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= pc; |
end |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
pc <= pc + 32'd4; |
ir <= dat_i; |
Rn <= dat_i[25:21]; |
state <= REGFETCHA; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
/rtl/verilog/EXECUTE.v
0,0 → 1,329
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// EXECUTE.v |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
EXECUTE: |
begin |
state <= WRITEBACK; |
case(opcode) |
`MISC: |
case(func) |
`STOP: |
if (!sf) begin |
vector <= `PRIVILEGE_VIOLATION; |
state <= TRAP; |
end |
else begin |
im <= imm[18:16]; |
tf <= imm[23]; |
sf <= imm[21]; |
clk_en <= 1'b0; |
state <= IFETCH; |
end |
endcase |
`R: |
begin |
case(func) |
`ABS: res <= a[31] ? -a : a; |
`SGN: res <= a[31] ? 32'hFFFFFFFF : |a; |
`NEG: res <= -a; |
`NOT: res <= ~a; |
`EXTB: res <= {{24{a[7]}},a[7:0]}; |
`EXTH: res <= {{16{a[15]}},a[15:0]}; |
default: res <= 32'd0; |
endcase |
case(func) |
`EXEC: |
begin |
ir <= a; |
Rn <= a[25:21]; |
state <= REGFETCHA; |
end |
`MOV_CRn2CRn: |
begin |
state <= IFETCH; |
case(ir[18:16]) |
3'd0: cr0 <= GetCr(ir[23:21]); |
3'd1: cr1 <= GetCr(ir[23:21]); |
3'd2: cr2 <= GetCr(ir[23:21]); |
3'd3: cr3 <= GetCr(ir[23:21]); |
3'd4: cr4 <= GetCr(ir[23:21]); |
3'd5: cr5 <= GetCr(ir[23:21]); |
3'd6: cr6 <= GetCr(ir[23:21]); |
3'd7: cr7 <= GetCr(ir[23:21]); |
endcase |
end |
`MOV_REG2CRn: |
begin |
case(ir[18:16]) |
3'd0: cr0 <= a[3:0]; |
3'd1: cr1 <= a[3:0]; |
3'd2: cr2 <= a[3:0]; |
3'd3: cr3 <= a[3:0]; |
3'd4: cr4 <= a[3:0]; |
3'd5: cr5 <= a[3:0]; |
3'd6: cr6 <= a[3:0]; |
3'd7: cr7 <= a[3:0]; |
endcase |
end |
`MOV_CRn2REG: |
res <= GetCr(ir[23:21]); |
`MOV_CR2REG: |
res <= cr; |
`MOV_REG2CR: |
begin |
state <= IFETCH; |
cr0 <= a[3:0]; |
cr1 <= a[7:4]; |
cr2 <= a[11:8]; |
cr3 <= a[15:12]; |
cr4 <= a[19:16]; |
cr5 <= a[23:20]; |
cr6 <= a[27:24]; |
cr7 <= a[31:28]; |
end |
`MOV_REG2IM: if (!sf) begin |
vector <= `PRIVILEGE_VIOLATION; |
state <= TRAP; |
end |
else begin |
im <= a[2:0]; |
state <= IFETCH; |
end |
`MOV_IM2REG: if (!sf) begin |
vector <= `PRIVILEGE_VIOLATION; |
state <= TRAP; |
end |
else begin |
res <= im; |
end |
`MOV_USP2REG: |
res <= usp; |
`MOV_REG2USP: |
usp <= a; |
`MFTICK: |
res <= tick; |
endcase |
end |
`RR: |
begin |
case(func) |
`ADD: res <= a + b; |
`SUB: res <= a - b; |
`CMP: res <= a - b; |
`AND: res <= a & b; |
`OR: res <= a | b; |
`EOR: res <= a ^ b; |
`NAND: res <= ~(a & b); |
`NOR: res <= ~(a | b); |
`ENOR: res <= ~(a ^ b); |
`SHL: res <= shlo[31: 0]; |
`SHR: res <= shro[63:32]; |
`ROL: res <= shlo[31:0]|shlo[63:32]; |
`ROR: res <= shro[31:0]|shro[63:32]; |
`MIN: res <= as < bs ? as : bs; |
`MAX: res <= as < bs ? bs : as; |
`BCDADD: res <= bcdaddo; |
`BCDSUB: res <= bcdsubo; |
default: res <= 32'd0; |
endcase |
if (func==`JMP_RR) begin |
pc <= a + b; |
pc[1:0] <= 2'b00; |
state <= IFETCH; |
end |
else if (func==`JSR_RR) begin |
tgt <= a + b; |
tgt[1:0] <= 2'b00; |
state <= JSR1; |
end |
else if (func==`CROR) begin |
state <= IFETCH; |
case(ir[15:13]) |
3'd0: cr0[ir[12:11]] <= GetCrBit(ir[25:21])| GetCrBit(ir[20:16]); |
3'd1: cr1[ir[12:11]] <= GetCrBit(ir[25:21])| GetCrBit(ir[20:16]); |
3'd2: cr2[ir[12:11]] <= GetCrBit(ir[25:21])| GetCrBit(ir[20:16]); |
3'd3: cr3[ir[12:11]] <= GetCrBit(ir[25:21])| GetCrBit(ir[20:16]); |
3'd4: cr4[ir[12:11]] <= GetCrBit(ir[25:21])| GetCrBit(ir[20:16]); |
3'd5: cr5[ir[12:11]] <= GetCrBit(ir[25:21])| GetCrBit(ir[20:16]); |
3'd6: cr6[ir[12:11]] <= GetCrBit(ir[25:21])| GetCrBit(ir[20:16]); |
3'd7: cr7[ir[12:11]] <= GetCrBit(ir[25:21])| GetCrBit(ir[20:16]); |
endcase |
end |
else if (func==`CRAND) begin |
state <= IFETCH; |
case(ir[15:13]) |
3'd0: cr0[ir[12:11]] <= GetCrBit(ir[25:21])& GetCrBit(ir[20:16]); |
3'd1: cr1[ir[12:11]] <= GetCrBit(ir[25:21])& GetCrBit(ir[20:16]); |
3'd2: cr2[ir[12:11]] <= GetCrBit(ir[25:21])& GetCrBit(ir[20:16]); |
3'd3: cr3[ir[12:11]] <= GetCrBit(ir[25:21])& GetCrBit(ir[20:16]); |
3'd4: cr4[ir[12:11]] <= GetCrBit(ir[25:21])& GetCrBit(ir[20:16]); |
3'd5: cr5[ir[12:11]] <= GetCrBit(ir[25:21])& GetCrBit(ir[20:16]); |
3'd6: cr6[ir[12:11]] <= GetCrBit(ir[25:21])& GetCrBit(ir[20:16]); |
3'd7: cr7[ir[12:11]] <= GetCrBit(ir[25:21])& GetCrBit(ir[20:16]); |
endcase |
end |
else if (func==`CRXOR) begin |
state <= IFETCH; |
case(ir[15:13]) |
3'd0: cr0[ir[12:11]] <= GetCrBit(ir[25:21])^ GetCrBit(ir[20:16]); |
3'd1: cr1[ir[12:11]] <= GetCrBit(ir[25:21])^ GetCrBit(ir[20:16]); |
3'd2: cr2[ir[12:11]] <= GetCrBit(ir[25:21])^ GetCrBit(ir[20:16]); |
3'd3: cr3[ir[12:11]] <= GetCrBit(ir[25:21])^ GetCrBit(ir[20:16]); |
3'd4: cr4[ir[12:11]] <= GetCrBit(ir[25:21])^ GetCrBit(ir[20:16]); |
3'd5: cr5[ir[12:11]] <= GetCrBit(ir[25:21])^ GetCrBit(ir[20:16]); |
3'd6: cr6[ir[12:11]] <= GetCrBit(ir[25:21])^ GetCrBit(ir[20:16]); |
3'd7: cr7[ir[12:11]] <= GetCrBit(ir[25:21])^ GetCrBit(ir[20:16]); |
endcase |
end |
else if (func==`CRNOR) begin |
state <= IFETCH; |
case(ir[15:13]) |
3'd0: cr0[ir[12:11]] <= ~(GetCrBit(ir[25:21])| GetCrBit(ir[20:16])); |
3'd1: cr1[ir[12:11]] <= ~(GetCrBit(ir[25:21])| GetCrBit(ir[20:16])); |
3'd2: cr2[ir[12:11]] <= ~(GetCrBit(ir[25:21])| GetCrBit(ir[20:16])); |
3'd3: cr3[ir[12:11]] <= ~(GetCrBit(ir[25:21])| GetCrBit(ir[20:16])); |
3'd4: cr4[ir[12:11]] <= ~(GetCrBit(ir[25:21])| GetCrBit(ir[20:16])); |
3'd5: cr5[ir[12:11]] <= ~(GetCrBit(ir[25:21])| GetCrBit(ir[20:16])); |
3'd6: cr6[ir[12:11]] <= ~(GetCrBit(ir[25:21])| GetCrBit(ir[20:16])); |
3'd7: cr7[ir[12:11]] <= ~(GetCrBit(ir[25:21])| GetCrBit(ir[20:16])); |
endcase |
end |
else if (func==`CRNAND) begin |
state <= IFETCH; |
case(ir[15:13]) |
3'd0: cr0[ir[12:11]] <= ~(GetCrBit(ir[25:21])& GetCrBit(ir[20:16])); |
3'd1: cr1[ir[12:11]] <= ~(GetCrBit(ir[25:21])& GetCrBit(ir[20:16])); |
3'd2: cr2[ir[12:11]] <= ~(GetCrBit(ir[25:21])& GetCrBit(ir[20:16])); |
3'd3: cr3[ir[12:11]] <= ~(GetCrBit(ir[25:21])& GetCrBit(ir[20:16])); |
3'd4: cr4[ir[12:11]] <= ~(GetCrBit(ir[25:21])& GetCrBit(ir[20:16])); |
3'd5: cr5[ir[12:11]] <= ~(GetCrBit(ir[25:21])& GetCrBit(ir[20:16])); |
3'd6: cr6[ir[12:11]] <= ~(GetCrBit(ir[25:21])& GetCrBit(ir[20:16])); |
3'd7: cr7[ir[12:11]] <= ~(GetCrBit(ir[25:21])& GetCrBit(ir[20:16])); |
endcase |
end |
else if (func==`CRXNOR) begin |
state <= IFETCH; |
case(ir[15:13]) |
3'd0: cr0[ir[12:11]] <= ~(GetCrBit(ir[25:21])^ GetCrBit(ir[20:16])); |
3'd1: cr1[ir[12:11]] <= ~(GetCrBit(ir[25:21])^ GetCrBit(ir[20:16])); |
3'd2: cr2[ir[12:11]] <= ~(GetCrBit(ir[25:21])^ GetCrBit(ir[20:16])); |
3'd3: cr3[ir[12:11]] <= ~(GetCrBit(ir[25:21])^ GetCrBit(ir[20:16])); |
3'd4: cr4[ir[12:11]] <= ~(GetCrBit(ir[25:21])^ GetCrBit(ir[20:16])); |
3'd5: cr5[ir[12:11]] <= ~(GetCrBit(ir[25:21])^ GetCrBit(ir[20:16])); |
3'd6: cr6[ir[12:11]] <= ~(GetCrBit(ir[25:21])^ GetCrBit(ir[20:16])); |
3'd7: cr7[ir[12:11]] <= ~(GetCrBit(ir[25:21])^ GetCrBit(ir[20:16])); |
endcase |
end |
case(func) |
`LWX: begin ea <= a + b; mopcode <= `LW; state <= MEMORY1; end |
`LHX: begin ea <= a + b; mopcode <= `LH; state <= MEMORY1; end |
`LHUX: begin ea <= a + b; mopcode <= `LHU; state <= MEMORY1; end |
`LBX: begin ea <= a + b; mopcode <= `LB; state <= MEMORY1; end |
`LBUX: begin ea <= a + b; mopcode <= `LBU; state <= MEMORY1; end |
`SBX: begin ea <= a + b; mopcode <= `SB; b <= c; state <= MEMORY1; end |
`SHX: begin ea <= a + b; mopcode <= `SH; b <= c; state <= MEMORY1; end |
`SWX: begin ea <= a + b; mopcode <= `SW; b <= c; state <= MEMORY1; end |
endcase |
end |
`SETcc: |
begin |
case(cond) |
`SET: res <= 32'd1; |
`SEQ: res <= cr_zf; |
`SNE: res <= !cr_zf; |
`SMI: res <= ( cr_nf); |
`SPL: res <= (!cr_zf); |
`SHI: res <= (!cr_cf & !cr_zf); |
`SLS: res <= (cf |zf); |
`SHS: res <= (!cr_cf); |
`SLO: res <= ( cr_cf); |
`SGT: res <= ((cr_nf & cr_vf & !cr_zf)|(!cr_nf & !cr_vf & !cr_zf)); |
`SLE: res <= (cr_zf | (cr_nf & !cr_vf) | (!cr_nf & cr_vf)); |
`SGE: res <= ((cr_nf & cr_vf)|(!cr_nf & !cr_vf)); |
`SLT: res <= ((cr_nf & !cr_vf)|(!cr_nf & cr_vf)); |
`SVS: res <= ( cr_vf); |
`SVC: res <= (!cr_vf); |
endcase |
end |
`ADDI: res <= a + imm; |
`SUBI: res <= a - imm; |
`CMPI: res <= a - imm; |
`ANDI: res <= a & imm; |
`ORI: res <= a | imm; |
`EORI: res <= a ^ imm; |
`CRxx: |
case(ir[20:16]) |
`ORI_CCR: |
begin |
state <= IFETCH; |
cr0 <= cr0 | imm[3:0]; |
cr1 <= cr1 | imm[7:4]; |
cr2 <= cr2 | imm[11:8]; |
cr3 <= cr3 | imm[15:12]; |
cr4 <= cr4 | imm[19:16]; |
cr5 <= cr5 | imm[23:20]; |
cr6 <= cr6 | imm[27:24]; |
cr7 <= cr7 | imm[31:28]; |
end |
`ANDI_CCR: |
begin |
state <= IFETCH; |
cr0 <= cr0 & imm[3:0]; |
cr1 <= cr1 & imm[7:4]; |
cr2 <= cr2 & imm[11:8]; |
cr3 <= cr3 & imm[15:12]; |
cr4 <= cr4 & imm[19:16]; |
cr5 <= cr5 & imm[23:20]; |
cr6 <= cr6 & imm[27:24]; |
cr7 <= cr7 & imm[31:28]; |
end |
`EORI_CCR: |
begin |
state <= IFETCH; |
cr0 <= cr0 ^ imm[3:0]; |
cr1 <= cr1 ^ imm[7:4]; |
cr2 <= cr2 ^ imm[11:8]; |
cr3 <= cr3 ^ imm[15:12]; |
cr4 <= cr4 ^ imm[19:16]; |
cr5 <= cr5 ^ imm[23:20]; |
cr6 <= cr6 ^ imm[27:24]; |
cr7 <= cr7 ^ imm[31:28]; |
end |
endcase |
`LINK: state <= LINK; |
default: res <= 32'd0; |
endcase |
case(opcode) |
`TAS: begin ea <= a + imm; mopcode <= opcode; state <= TAS; end |
`LW: begin ea <= a + imm; mopcode <= opcode; state <= MEMORY1; end |
`LH: begin ea <= a + imm; mopcode <= opcode; state <= MEMORY1; end |
`LB: begin ea <= a + imm; mopcode <= opcode; state <= MEMORY1; end |
`LHU: begin ea <= a + imm; mopcode <= opcode; state <= MEMORY1; end |
`LBU: begin ea <= a + imm; mopcode <= opcode; state <= MEMORY1; end |
`SW: begin ea <= a + imm; mopcode <= opcode; state <= MEMORY1; end |
`SH: begin ea <= a + imm; mopcode <= opcode; state <= MEMORY1; end |
`SB: begin ea <= a + imm; mopcode <= opcode; state <= MEMORY1; end |
`PEA: begin ea <= a + imm; mopcode <= opcode; state <= PEA; end |
default: ea <= 32'd0; |
endcase |
end |
/rtl/verilog/VECTOR.v
0,0 → 1,57
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// VECTOR.v |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
LOAD_SP: |
if (!cyc_o) begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= vector; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
ssp[31:2] <= dat_i[31:2]; |
ssp[1:0] <= 2'b00; |
vector <= `RESET_VECTOR; |
state <= VECTOR; |
end |
// Pointless to check for bus error here |
VECTOR: |
if (!cyc_o) begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= vector; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
pc[31:2] <= dat_i[31:2]; |
pc[1:0] <= 2'b00; |
state <= IFETCH; |
end |
/rtl/verilog/TRAP.v
0,0 → 1,98
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// TRAP.v |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
TRAP1: |
if (!cyc_o) begin |
fc_o <= {3'b101}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= ssp - 32'd4; |
dat_o <= pc; |
end |
else if (ack_i) begin |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
sr1 <= sr; |
sf <= 1'b1; |
tf <= 1'b0; |
ssp <= ssp - 32'd4; |
state <= TRAP2; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
TRAP2: |
if (!stb_o) begin |
fc_o <= {3'b101}; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= ssp - 32'd4; |
dat_o <= cr; |
end |
else if (ack_i) begin |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
ssp <= ssp - 32'd4; |
state <= TRAP3; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
TRAP3: |
if (!stb_o) begin |
fc_o <= {3'b101}; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= ssp - 32'd4; |
dat_o <= sr1; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
ssp <= ssp - 32'd4; |
state <= VECTOR; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
|
/rtl/verilog/WRITE_FLAGS.v
0,0 → 1,63
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// WRITE_FLAGS.v - update the CR registers |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
WRITE_FLAGS: |
begin |
state <= IFETCH; |
if (opcode==`CMPI || (opcode==`RR && func==`CMP)) begin |
case(Rn[2:0]) |
3'd0: cr0 <= {nf,zf,vf,cf}; |
3'd1: cr1 <= {nf,zf,vf,cf}; |
3'd2: cr2 <= {nf,zf,vf,cf}; |
3'd3: cr3 <= {nf,zf,vf,cf}; |
3'd4: cr4 <= {nf,zf,vf,cf}; |
3'd5: cr5 <= {nf,zf,vf,cf}; |
3'd6: cr6 <= {nf,zf,vf,cf}; |
3'd7: cr7 <= {nf,zf,vf,cf}; |
endcase |
end |
else begin |
case(opcode) |
`R: |
case(func) |
`ABS,`SGN,`NEG,`NOT,`EXTB,`EXTH: |
cr0 <= {nf,zf,vf,cf}; |
default: ; |
endcase |
`RR: |
case(func) |
`ADD,`SUB,`AND,`OR,`EOR,`NAND,`NOR,`ENOR, |
`MIN,`MAX, |
`BCDADD,`BCDSUB, |
`SHL,`SHR,`ROL,`ROR, |
`LWX,`LHX,`LBX,`LHUX,`LBUX: |
cr0 <= {nf,zf,vf,cf}; |
default: ; |
endcase |
`ADDI,`SUBI,`ANDI,`ORI,`EORI,`LW,`LH,`LB,`LHU,`LBU,`TAS: |
cr0 <= {nf,zf,vf,cf}; |
default: ; |
endcase |
end |
end |
|
/rtl/verilog/RTS.v
0,0 → 1,50
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// RTS.v - return from subroutine |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
RTS: |
if (!cyc_o) begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= sf ? ssp : usp; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
if (sf) |
ssp <= ssp + 32'd4 + ir[21:6]; |
else |
usp <= usp + 32'd4 + ir[21:6]; |
pc <= {dat_i[31:2],2'b00}+{ir[25:22],2'b00}; |
state <= IFETCH; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
|
/rtl/verilog/MEMORY.v
0,0 → 1,221
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// MEMORY.v - memory operate instructions |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
MEMORY1: |
begin |
case(mopcode) |
`LW: begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= ea; |
state <= MEMORY1_ACK; |
end |
`LH,`LHU: |
begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= ea[1] ? 4'b1100 : 4'b0011; |
adr_o <= ea; |
state <= MEMORY1_ACK; |
end |
`LB,`LBU: |
begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
case(ea[1:0]) |
2'd0: sel_o <= 4'b0001; |
2'd1: sel_o <= 4'b0010; |
2'd2: sel_o <= 4'b0100; |
2'd3: sel_o <= 4'b1000; |
endcase |
adr_o <= ea; |
state <= MEMORY1_ACK; |
end |
`SW: begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= ea; |
dat_o <= b; |
state <= MEMORY1_ACK; |
end |
`SH: begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= ea[1] ? 4'b1100 : 4'b0011; |
adr_o <= ea; |
dat_o <= {2{b[15:0]}}; |
state <= MEMORY1_ACK; |
end |
`SB: begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
case(ea[1:0]) |
2'd0: sel_o <= 4'b0001; |
2'd1: sel_o <= 4'b0010; |
2'd2: sel_o <= 4'b0100; |
2'd3: sel_o <= 4'b1000; |
endcase |
adr_o <= ea; |
dat_o <= {4{b[7:0]}}; |
state <= MEMORY1_ACK; |
end |
endcase |
end |
MEMORY1_ACK: |
if (ack_i) begin |
case(mopcode) |
`LW: begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
res <= dat_i; |
state <= WRITEBACK; |
end |
`LH: begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
if (sel_o==4'b0011) |
res <= {{16{dat_i[15]}},dat_i[15:0]}; |
else |
res <= {{16{dat_i[31]}},dat_i[31:16]}; |
state <= WRITEBACK; |
end |
`LHU: begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
if (sel_o==4'b0011) |
res <= {16'd0,dat_i[15:0]}; |
else |
res <= {16'd0,dat_i[31:16]}; |
state <= WRITEBACK; |
end |
`LB: begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
case(sel_o) |
4'b0001: res <= {{24{dat_i[7]}},dat_i[7:0]}; |
4'b0010: res <= {{24{dat_i[15]}},dat_i[15:8]}; |
4'b0100: res <= {{24{dat_i[23]}},dat_i[23:16]}; |
4'b1000: res <= {{24{dat_i[31]}},dat_i[31:24]}; |
endcase |
state <= WRITEBACK; |
end |
`LBU: begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
case(sel_o) |
4'b0001: res <= {24'd0,dat_i[7:0]}; |
4'b0010: res <= {24'd0,dat_i[15:8]}; |
4'b0100: res <= {24'd0,dat_i[23:16]}; |
4'b1000: res <= {24'd0,dat_i[31:24]}; |
endcase |
state <= WRITEBACK; |
end |
`SW,`SH,`SB: |
begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
state <= IFETCH; |
end |
endcase |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
|
TAS: |
if (!cyc_o) begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= ea; |
end |
else if (ack_i) begin |
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
res <= dat_i; |
state <= TAS2; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
TAS2: |
if (!res[31]) begin |
if (!stb_o) begin |
fc_o <= {sf,2'b01}; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= ea; |
dat_o <= {1'b1,res[30:0]}; |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
state <= WRITEBACK; |
end |
else if (err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'b0000; |
vector <= `BUS_ERR_VECTOR; |
state <= TRAP; |
end |
end |
else begin |
cyc_o <= 1'b0; |
state <= WRITEBACK; |
end |
|