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 9 to Rev 10
- ↔ Reverse comparison
Rev 9 → Rev 10
/rtl/verilog/WRITEBACK.v
23,10 → 23,7
// |
WRITEBACK: |
begin |
if (opcode==`POP) |
state <= POP1; |
else |
state <= WRITE_FLAGS; |
state <= WRITE_FLAGS; |
if (opcode!=`CMPI && !(opcode==`RR && func==`CMP)) begin |
regfile[Rn] <= res; |
if (Rn==5'd31) begin |
39,6 → 36,7
case(func) |
`ABS: |
begin |
if (!Rcbit) state <= IFETCH; |
vf <= res[31]; |
cf <= 1'b0; |
nf <= res[31]; |
46,6 → 44,7
end |
`SGN,`NOT,`EXTB,`EXTH: |
begin |
if (!Rcbit) state <= IFETCH; |
vf <= 1'b0; |
cf <= 1'b0; |
nf <= res[31]; |
53,6 → 52,7
end |
`NEG: |
begin |
if (!Rcbit) state <= IFETCH; |
vf <= v_rr; |
cf <= c_rr; |
nf <= res[31]; |
63,6 → 63,7
case(func) |
`ADD,`SUB: |
begin |
if (!Rcbit) state <= IFETCH; |
vf <= v_rr; |
cf <= c_rr; |
nf <= res[31]; |
70,6 → 71,7
end |
`CMP: |
begin |
state <= WRITE_FLAGS; |
vf <= 1'b0; |
cf <= c_rr; |
nf <= res[31]; |
78,6 → 80,7
`AND,`OR,`EOR,`NAND,`NOR,`ENOR,`MIN,`MAX, |
`LWX,`LHX,`LBX,`LHUX,`LBUX: |
begin |
if (!Rcbit) state <= IFETCH; |
vf <= 1'b0; |
cf <= 1'b0; |
nf <= res[31]; |
85,6 → 88,7
end |
`SHL,`ROL: |
begin |
if (!Rcbit) state <= IFETCH; |
vf <= 1'b0; |
cf <= shlo[32]; |
nf <= res[31]; |
92,6 → 96,7
end |
`SHR,`ROR: |
begin |
if (!Rcbit) state <= IFETCH; |
vf <= 1'b0; |
cf <= shro[31]; |
nf <= res[31]; |
99,6 → 104,7
end |
`BCDADD: |
begin |
if (!Rcbit) state <= IFETCH; |
vf <= 1'b0; |
cf <= bcdaddc; |
nf <= res[7]; |
106,11 → 112,27
end |
`BCDSUB: |
begin |
if (!Rcbit) state <= IFETCH; |
vf <= 1'b0; |
cf <= bcdsubc; |
nf <= res[7]; |
zf <= res[7:0]==8'd0; |
end |
`DIVU,`DIVS,`MODU,`MODS: |
begin |
if (!Rcbit) state <= IFETCH; |
vf <= divByZero; |
cf <= divByZero; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`MULU,`MULS,`MULUH,`MULSH: |
begin |
if (!Rcbit) state <= IFETCH; |
cf <= vf; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
endcase |
`ADDI,`SUBI: |
begin |
133,13 → 155,27
nf <= res[31]; |
zf <= res==32'd0; |
end |
`DIVSI,`DIVUI: |
begin |
vf <= divByZero; |
cf <= divByZero; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`MULSI,`MULUI: |
begin |
cf <= vf; |
nf <= res[31]; |
zf <= res==32'd0; |
end |
`POP: state <= POP1; |
`LINK: |
begin |
state <= IFETCH; |
if (sf) |
ssp <= ssp + imm; |
ssp <= ssp - imm; |
else |
usp <= usp + imm; |
usp <= usp - imm; |
end |
endcase |
end |
/rtl/verilog/KLC32.v
44,24 → 44,18
`define RST 6'd52 |
`define STOP 6'd53 |
`define R 6'd1 |
`define ABS 6'd4 |
`define ABS 6'd1 |
`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 UNLK 6'd24 |
`define MTSPR 6'd32 |
`define MFSPR 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 |
70,9 → 64,11
`define AND 6'd8 |
`define OR 6'd9 |
`define EOR 6'd10 |
`define ANDC 6'd11 |
`define NAND 6'd12 |
`define NOR 6'd13 |
`define ENOR 6'd14 |
`define ORC 6'd15 |
`define SHL 6'd16 |
`define SHR 6'd17 |
`define ROL 6'd18 |
83,12 → 79,12
`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 MULS 6'd26 |
`define MULSH 6'd27 |
`define DIVU 6'd28 |
`define DIVS 6'd29 |
`define MODU 6'd30 |
`define MODS 6'd31 |
`define LWX 6'd48 |
`define LHX 6'd49 |
`define LBX 6'd50 |
106,6 → 102,10
`define ANDI 6'd8 |
`define ORI 6'd9 |
`define EORI 6'd10 |
`define MULUI 6'd12 |
`define MULSI 6'd13 |
`define DIVUI 6'd14 |
`define DIVSI 6'd15 |
`define Bcc 6'd16 |
`define BRA 4'd0 |
`define BRN 4'd1 |
161,11 → 161,18
`define ANDI_CCR 5'd8 |
`define ORI_CCR 5'd9 |
`define EORI_CCR 5'd10 |
`define CROR 10'd449 |
`define CRORC 10'd417 |
`define CRAND 10'd257 |
`define CRANDC 10'd129 |
`define CRXOR 10'd193 |
`define CRNOR 10'd33 |
`define CRNAND 10'd225 |
`define CRXNOR 10'd289 |
`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 |
180,7 → 187,6
`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; |
222,6 → 228,17
parameter TAS = 8'd43; |
parameter TAS2 = 8'd44; |
parameter PEA = 8'd45; |
parameter MULTDIV1 = 8'd49; |
parameter MULTDIV2 = 8'd50; |
parameter MULT1 = 8'd51; |
parameter MULT2 = 8'd52; |
parameter MULT3 = 8'd53; |
parameter MULT4 = 8'd54; |
parameter MULT5 = 8'd55; |
parameter MULT6 = 8'd56; |
parameter MULT7 = 8'd57; |
parameter DIV1 = 8'd61; |
parameter DIV2 = 8'd62; |
input rst_i; |
input clk_i; |
input [2:0] ipl_i; |
232,7 → 249,6
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; |
249,15 → 265,21
output [31:0] dat_o; |
reg [31:0] dat_o; |
|
reg cpu_clk_en; |
reg clk_en; |
wire clk; |
|
reg [7:0] state; |
reg [31:0] ir; |
reg tf,sf; |
reg [31:0] pc; |
reg [31:0] usp,ssp; |
reg [31:0] lc; |
reg [31:0] ctr; |
wire [5:0] opcode=ir[31:26]; |
reg Rcbit; |
reg [5:0] mopcode; |
wire [5:0] func=ir[5:0]; |
wire [9:0] func1=ir[10:1]; |
wire [3:0] cond=ir[19:16]; |
wire [31:0] brdisp = {{16{ir[15]}},ir[15:2],2'b0}; |
reg [4:0] Rn; |
265,29 → 287,42
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 xer_ov,xer_ca,xer_so; |
reg [2:0] im; |
reg [2:0] iplr; |
reg [7:0] vecnum; |
reg [31:0] vector; |
reg [31:0] ea; |
reg [15:0] rstsh; |
assign rst_o = rstsh[15]; |
reg prev_nmi; |
reg nmi_edge; |
reg [31:0] sr1; |
reg [31:0] tgt; |
reg [31:0] a,b,c,imm; |
reg [31:0] a,b,c,imm,aa,bb; |
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; |
|
reg [5:0] cnt; |
reg [31:0] div_r0; |
reg [31:0] div_q0; |
reg [31:0] div_q,div_r; |
wire [32:0] div_dif = div_r0 - bb; |
|
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 IsDivi = opcode==`DIVUI || opcode==`DIVSI; |
wire IsDivu = opcode==`DIVUI || (opcode==`RR && (func==`DIVU || func==`MODU)); |
wire IsMult = opcode==`MULUI || opcode==`MULSI || (opcode==`RR && (func==`MULU || func==`MULS || func==`MULUH || func==`MULSH)); |
wire IsDiv = opcode==`DIVUI || opcode==`DIVSI || (opcode==`RR && (func==`DIVU || func==`DIVS || func==`MODU || func==`MODS)); |
|
wire hasConst16 = |
opcode==`ADDI || opcode==`SUBI || opcode==`CMPI || |
299,10 → 334,6
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; |
319,6 → 350,14
wire [63:0] shlo = {32'd0,a} << b[4:0]; |
wire [63:0] shro = {a,32'd0} >> b[4:0]; |
|
reg res_sgn; |
wire [31:0] mp0 = aa[15:0] * bb[15:0]; |
wire [31:0] mp1 = aa[15:0] * bb[31:16]; |
wire [31:0] mp2 = aa[31:16] * bb[15:0]; |
wire [31:0] mp3 = aa[31:16] * bb[31:16]; |
reg [63:0] prod; |
wire divByZero; |
|
function GetCrBit; |
input [4:0] Rn; |
begin |
351,7 → 390,7
end |
endfunction |
|
wire [3:0] crc = GetCr(Rn); |
wire [3:0] crc = GetCr(Rn[4:2]); |
wire cr_zf = crc[2]; |
wire cr_nf = crc[3]; |
wire cr_cf = crc[0]; |
363,9 → 402,6
// - 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) |
396,14 → 432,14
stb_o <= 1'b0; |
sel_o <= 4'b0000; |
we_o <= 1'b0; |
rst_o <= 1'b0; |
clk_en <= 1'b1; |
tick <= 32'd0; |
rstsh <= 16'hFFFF; |
end |
else begin |
tick <= tick + 32'd1; |
clk_en <= 1'b1; |
rst_o <= 1'b0; |
rstsh <= {rstsh,1'b0}; |
prev_nmi <= ipl_i==3'd7; |
if (!prev_nmi && (ipl_i==3'd7)) |
nmi_edge <= 1'b1; |
431,6 → 467,8
`include "TRAP.v" |
`include "RTI.v" |
|
`include "MULTDIV.v" |
|
endcase |
end |
|
/rtl/verilog/PUSH.v
28,7 → 28,8
else begin |
Rn <= ir[25:21]; |
ir[25:0] <= {ir[20:1],6'b0}; |
state <= PUSH2; |
if (ir[25:21]!=5'd0) |
state <= PUSH2; |
end |
PUSH2: |
begin |
/rtl/verilog/MULTDIV.v
0,0 → 1,114
// ============================================================================ |
// (C) 2011 Robert Finch |
// All Rights Reserved. |
// robfinch<remove>@opencores.org |
// |
// KLC32 - 32 bit CPU |
// MULTDIV.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/>. |
// |
// ============================================================================ |
// |
MULTDIV1: |
begin |
state <= IsMult ? MULT1 : DIV1; |
cnt <= 6'd0; |
case(opcode) |
`RR: // RR |
case(func) |
`MULS,`MULSH,`DIVS,`MODS: |
begin |
aa <= a[31] ? -a : a; |
bb <= b[31] ? -b : b; |
res_sgn <= a[31] ^ b[31]; |
end |
`MULU,`MULUH,`DIVU,`MODU: |
begin |
aa <= a; |
bb <= b; |
res_sgn <= 1'b0; |
end |
endcase |
`MULSI,`DIVSI: |
begin |
aa <= a[31] ? -a : a; |
bb <= imm[31] ? -imm : imm; |
res_sgn <= a[31] ^ imm[31]; |
end |
`MULUI,`DIVUI: |
begin |
aa <= a; |
bb <= imm; |
res_sgn <= 1'b0; |
end |
endcase |
end |
|
MULT1: begin prod <= {mp3,mp0} + {mp1,16'd0}; state <= MULT2; end |
MULT2: begin prod <= prod + {mp2,16'd0}; state <= res_sgn ? MULT6 : MULTDIV2; end |
MULT6: |
begin |
state <= MULTDIV2; |
prod <= -prod; |
end |
|
// Non-restoring divide |
DIV1: |
if (cnt <= 32) begin |
cnt <= cnt + 8'd1; |
aa[0] <= ~div_dif[31]; // get test result |
aa[31:1] <= aa[30:0]; // shift quotient |
div_r0[0] <= aa[31]; // shift bit into test area (remainder) |
if (~div_dif[31]) |
div_r0[31:1] <= div_dif[31:0]; |
else |
div_r0[31:1] <= div_r0[30:0]; |
end |
else |
state <= DIV2; |
DIV2: |
begin |
state <= MULTDIV2; |
if (res_sgn) begin |
div_q <= -aa; |
div_r <= -div_r0; |
end |
else begin |
div_q <= aa; |
div_r <= div_r0; |
end |
end |
|
MULTDIV2: |
begin |
state <= WRITEBACK; |
case(opcode) |
`RR: |
case(func) |
`MULU: begin res <= prod[31:0]; vf <= |prod[63:32]; end |
`MULS: begin res <= prod[31:0]; vf <= prod[31] ? ~&prod[63:32] : |prod[63:32]; end |
`MULUH: begin res <= prod[63:32]; end |
`MULSH: begin res <= prod[63:32]; end |
`DIVS: res <= div_q; |
`DIVU: res <= div_q; |
`MODS: res <= div_r; |
`MODU: res <= div_r; |
endcase |
`MULSI: begin res <= prod[31:0]; vf <= prod[31] ? ~&prod[63:32] : |prod[63:32]; end |
`MULUI: begin res <= prod[31:0]; vf <= |prod[63:32]; end |
`DIVUI: res <= div_q; |
`DIVSI: res <= div_q; |
endcase |
end |
/rtl/verilog/REGFETCHA.v
23,20 → 23,21
// |
REGFETCHA: |
begin |
Rcbit <= 1'b0; |
a <= rfo; |
b <= 32'd0; |
Rn <= ir[20:16]; |
if (opcode==`RR || opcode==`RRR || opcode==`SW || opcode==`SH || opcode==`SB) begin |
state <= REGFETCHB; |
end |
// RIX format ? |
if (hasConst16 && ir[15:0]==16'h8000) |
state <= FETCH_IMM32; |
else begin |
// RIX format ? |
if ((hasConst16 && ir[15:0]==16'h8000) || (isStop)) |
state <= FETCH_IMM32; |
else begin |
imm <= {{16{ir[15]}},ir[15:0]}; |
state <= EXECUTE; |
end |
case(opcode) |
`ANDI: imm <= {16'hFFFF,ir[15:0]}; |
`ORI: imm <= {16'h0000,ir[15:0]}; |
`EORI: imm <= {16'h0000,ir[15:0]}; |
default: imm <= {{16{ir[15]}},ir[15:0]}; |
endcase |
state <= EXECUTE; |
end |
case(opcode) |
`MISC: |
85,14 → 86,47
state <= TRAP; |
end |
else begin |
rst_o <= 1'b1; |
rstsh <= 16'hFFFF; |
state <= IFETCH; |
end |
`STOP: |
if (!sf) begin |
vector <= `PRIVILEGE_VIOLATION; |
state <= TRAP; |
end |
else begin |
im <= ir[8:6]; |
tf <= ir[9]; |
sf <= ir[10]; |
clk_en <= 1'b0; |
state <= IFETCH; |
end |
default: |
begin |
vector <= `ILLEGAL_INSN; |
state <= TRAP; |
end |
endcase |
|
`R: |
case(func) |
`UNLK: state <= UNLK; |
endcase |
begin |
Rcbit <= ir[6]; |
case(func) |
`UNLK: state <= UNLK; |
`ABS,`SGN,`NEG,`NOT, |
`EXTB,`EXTH, |
`MFSPR,`MTSPR, |
`MOV_CRn2CRn, |
`EXEC: |
; |
default: |
begin |
vector <= `ILLEGAL_INSN; |
state <= TRAP; |
end |
endcase |
end |
|
`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 |
99,6 → 133,7
`Bcc: |
case(cond) |
`BRA: begin pc <= pc + brdisp; state <= IFETCH; end |
`BRN: begin 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 |
135,10 → 170,165
`SETcc: Rn <= ir[15:11]; |
`PUSH: state <= PUSH1; |
`POP: state <= POP1; |
endcase |
if (isIllegalOpcode) begin |
|
`RR: |
begin |
state <= REGFETCHB; |
Rcbit <= ir[6]; |
case(func) |
`JSR_RR,`JMP_RR, |
`ADD,`SUB,`CMP, |
`BCDADD,`BCDSUB, |
`AND,`OR,`EOR,`NAND,`NOR,`ENOR, |
`SHL,`SHR,`ROL,`ROR, |
`MULU,`MULS,`MULUH,`MULSH,`DIVU,`DIVS,`MODU,`MODS, |
`LWX,`LHX,`LBX,`LHUX,`LBUX,`SWX,`SHX,`SBX, |
`MIN,`MAX: |
; |
default: |
begin |
vector <= `ILLEGAL_INSN; |
state <= TRAP; |
end |
endcase |
end |
|
`RRR: |
state <= REGFETCHB; |
|
`CRxx: |
case(func1) |
`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 |
`CRORC: |
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 |
`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 |
`CRANDC: |
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 |
`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 |
`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 |
`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 |
`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 |
default: |
begin |
vector <= `ILLEGAL_INSN; |
state <= TRAP; |
end |
endcase |
`ADDI,`SUBI,`CMPI, |
`ANDI,`ORI,`EORI, |
`MULUI,`MULSI,`DIVUI,`DIVSI, |
`PEA,`LINK,`TAS, |
`LB,`LH,`LW,`LBU,`LHU: |
; /* do nothing at this point */ |
`SB,`SH,`SW: |
state <= REGFETCHB; |
default: |
begin |
vector <= `ILLEGAL_INSN; |
state <= TRAP; |
end |
end |
endcase |
end |
|
/rtl/verilog/REGFETCHB.v
29,10 → 29,15
state <= REGFETCHC; |
else begin |
// RIX format ? |
if ((hasConst16 && ir[15:0]==16'h8000) || (isStop)) |
if (hasConst16 && ir[15:0]==16'h8000) |
state <= FETCH_IMM32; |
else begin |
imm <= {{16{ir[15]}},ir[15:0]}; |
case(opcode) |
`ANDI: imm <= {16'hFFFF,ir[15:0]}; |
`ORI: imm <= {16'h0000,ir[15:0]}; |
`EORI: imm <= {16'h0000,ir[15:0]}; |
default: imm <= {{16{ir[15]}},ir[15:0]}; |
endcase |
state <= EXECUTE; |
end |
end |
/rtl/verilog/POP.v
28,7 → 28,8
else begin |
Rn <= ir[25:21]; |
ir[25:0] <= {ir[20:1],6'b0}; |
state <= POP2; |
if (ir[25:21]!=5'd0) |
state <= POP2; |
end |
POP2: |
begin |
/rtl/verilog/IFETCH.v
18,7 → 18,10
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// |
// |
// Check for halted state and interrupts, then fetch instruction if no |
// halt or interrupt. |
// ============================================================================ |
// |
IFETCH: |
31,9 → 34,9
im <= ipl_i; |
tf <= 1'b0; |
sf <= 1'b1; |
iplr <= 3'd7; |
iplr <= ipl_i; |
state <= INTA; |
nmi_edge <= 1'b0; |
state <= INTA; |
end |
else if (ipl_i > im) begin |
sr1 <= sr; |
/rtl/verilog/EXECUTE.v
25,21 → 25,6
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) |
49,9 → 34,60
`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) |
`MFSPR: |
casex(ir[25:21]) |
5'b00xxx: res <= GetCr(ir[23:21]); |
5'b01000: res <= cr; |
5'b01001: res <= usp; |
5'b01010: |
if (!sf) begin |
vector <= `PRIVILEGE_VIOLATION; |
state <= TRAP; |
end |
else begin |
res <= im; |
end |
5'b01111: res <= tick; |
endcase |
`MTSPR: |
casex(ir[20:16]) |
5'b00xxx: // MTSPR CRn,Rn |
begin |
state <= IFETCH; |
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 |
5'b01000: // MTSPR CR,Rn |
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 |
5'b01001: usp <= a; // MTSPR USP,Rn |
5'b01010: |
if (!sf) begin |
vector <= `PRIVILEGE_VIOLATION; |
state <= TRAP; |
end |
else begin |
im <= a[2:0]; |
state <= IFETCH; |
end |
endcase |
`EXEC: |
begin |
ir <= a; |
72,66 → 108,17
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; |
default: res <= 32'd0; |
endcase |
end |
`RR: |
begin |
case(func) |
`ADD: res <= a + b; |
`SUB: res <= a - b; |
`CMP: res <= a - b; |
`AND: res <= a & b; |
`ANDC: res <= a & ~b; |
`OR: res <= a | b; |
`ORC: res <= a | ~b; |
`EOR: res <= a ^ b; |
`NAND: res <= ~(a & b); |
`NOR: res <= ~(a | b); |
156,84 → 143,6
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 |
243,6 → 152,15
`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 |
|
`MULU: state <= MULTDIV1; |
`MULS: state <= MULTDIV1; |
`MULUH: state <= MULTDIV1; |
`MULSH: state <= MULTDIV1; |
`DIVU: state <= MULTDIV1; |
`DIVS: state <= MULTDIV1; |
`MODU: state <= MULTDIV1; |
`MODS: state <= MULTDIV1; |
endcase |
end |
`SETcc: |
271,7 → 189,7
`ANDI: res <= a & imm; |
`ORI: res <= a | imm; |
`EORI: res <= a ^ imm; |
`CRxx: |
/* |
case(ir[20:16]) |
`ORI_CCR: |
begin |
310,7 → 228,12
cr7 <= cr7 ^ imm[31:28]; |
end |
endcase |
*/ |
`LINK: state <= LINK; |
`MULUI: state <= MULTDIV1; |
`MULSI: state <= MULTDIV1; |
`DIVUI: state <= MULTDIV1; |
`DIVSI: state <= MULTDIV1; |
default: res <= 32'd0; |
endcase |
case(opcode) |
/rtl/verilog/WRITE_FLAGS.v
25,7 → 25,7
begin |
state <= IFETCH; |
if (opcode==`CMPI || (opcode==`RR && func==`CMP)) begin |
case(Rn[2:0]) |
case(Rn[4:2]) |
3'd0: cr0 <= {nf,zf,vf,cf}; |
3'd1: cr1 <= {nf,zf,vf,cf}; |
3'd2: cr2 <= {nf,zf,vf,cf}; |
41,19 → 41,21
`R: |
case(func) |
`ABS,`SGN,`NEG,`NOT,`EXTB,`EXTH: |
cr0 <= {nf,zf,vf,cf}; |
if (Rcbit) cr0 <= {nf,zf,vf,cf}; |
default: ; |
endcase |
`RR: |
case(func) |
`ADD,`SUB,`AND,`OR,`EOR,`NAND,`NOR,`ENOR, |
`MULU,`MULS,`MULUH,`MULSH,`DIVU,`DIVS,`MODU,`MODS, |
`ADD,`SUB,`AND,`ANDC,`OR,`ORC,`EOR,`NAND,`NOR,`ENOR, |
`MIN,`MAX, |
`BCDADD,`BCDSUB, |
`SHL,`SHR,`ROL,`ROR, |
`LWX,`LHX,`LBX,`LHUX,`LBUX: |
cr0 <= {nf,zf,vf,cf}; |
if (Rcbit) cr0 <= {nf,zf,vf,cf}; |
default: ; |
endcase |
endcase |
`MULUI,`MULSI,`DIVUI,`DIVSI, |
`ADDI,`SUBI,`ANDI,`ORI,`EORI,`LW,`LH,`LB,`LHU,`LBU,`TAS: |
cr0 <= {nf,zf,vf,cf}; |
default: ; |