Line 42... |
Line 42... |
`define USER_MODE 6'd50
|
`define USER_MODE 6'd50
|
`define SET_IM 6'd51
|
`define SET_IM 6'd51
|
`define RST 6'd52
|
`define RST 6'd52
|
`define STOP 6'd53
|
`define STOP 6'd53
|
`define R 6'd1
|
`define R 6'd1
|
`define ABS 6'd4
|
`define ABS 6'd1
|
`define SGN 6'd2
|
`define SGN 6'd2
|
`define NEG 6'd3
|
`define NEG 6'd3
|
`define NOT 6'd4
|
`define NOT 6'd4
|
`define EXTB 6'd5
|
`define EXTB 6'd5
|
`define EXTH 6'd6
|
`define EXTH 6'd6
|
`define MOV_REG2USP 6'd32
|
`define UNLK 6'd24
|
`define MOV_USP2REG 6'd33
|
`define MTSPR 6'd32
|
|
`define MFSPR 6'd33
|
`define MOV_CRn2CRn 6'd48
|
`define MOV_CRn2CRn 6'd48
|
`define MOV_CRn2REG 6'd49
|
`define MOV_CRn2REG 6'd49
|
`define MOV_REG2CRn 6'd50
|
`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 EXEC 6'd63
|
`define RR 6'd2
|
`define RR 6'd2
|
`define ADD 6'd4
|
`define ADD 6'd4
|
`define SUB 6'd5
|
`define SUB 6'd5
|
`define CMP 6'd6
|
`define CMP 6'd6
|
`define AND 6'd8
|
`define AND 6'd8
|
`define OR 6'd9
|
`define OR 6'd9
|
`define EOR 6'd10
|
`define EOR 6'd10
|
|
`define ANDC 6'd11
|
`define NAND 6'd12
|
`define NAND 6'd12
|
`define NOR 6'd13
|
`define NOR 6'd13
|
`define ENOR 6'd14
|
`define ENOR 6'd14
|
|
`define ORC 6'd15
|
`define SHL 6'd16
|
`define SHL 6'd16
|
`define SHR 6'd17
|
`define SHR 6'd17
|
`define ROL 6'd18
|
`define ROL 6'd18
|
`define ROR 6'd19
|
`define ROR 6'd19
|
`define JMP_RR 6'd20
|
`define JMP_RR 6'd20
|
`define JSR_RR 6'd21
|
`define JSR_RR 6'd21
|
`define MAX 6'd22
|
`define MAX 6'd22
|
`define MIN 6'd23
|
`define MIN 6'd23
|
`define MULU 6'd24
|
`define MULU 6'd24
|
`define MULUH 6'd25
|
`define MULUH 6'd25
|
`define CROR 6'd32
|
`define MULS 6'd26
|
`define CRAND 6'd33
|
`define MULSH 6'd27
|
`define CRXOR 6'd34
|
`define DIVU 6'd28
|
`define CRNOR 6'd35
|
`define DIVS 6'd29
|
`define CRNAND 6'd36
|
`define MODU 6'd30
|
`define CRXNOR 6'd37
|
`define MODS 6'd31
|
`define LWX 6'd48
|
`define LWX 6'd48
|
`define LHX 6'd49
|
`define LHX 6'd49
|
`define LBX 6'd50
|
`define LBX 6'd50
|
`define LHUX 6'd51
|
`define LHUX 6'd51
|
`define LBUX 6'd52
|
`define LBUX 6'd52
|
Line 104... |
Line 100... |
`define SUBI 6'd5
|
`define SUBI 6'd5
|
`define CMPI 6'd6
|
`define CMPI 6'd6
|
`define ANDI 6'd8
|
`define ANDI 6'd8
|
`define ORI 6'd9
|
`define ORI 6'd9
|
`define EORI 6'd10
|
`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 Bcc 6'd16
|
`define BRA 4'd0
|
`define BRA 4'd0
|
`define BRN 4'd1
|
`define BRN 4'd1
|
`define BHI 4'd2
|
`define BHI 4'd2
|
`define BLS 4'd3
|
`define BLS 4'd3
|
Line 159... |
Line 159... |
`define SLE 4'd15
|
`define SLE 4'd15
|
`define CRxx 6'd19
|
`define CRxx 6'd19
|
`define ANDI_CCR 5'd8
|
`define ANDI_CCR 5'd8
|
`define ORI_CCR 5'd9
|
`define ORI_CCR 5'd9
|
`define EORI_CCR 5'd10
|
`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 JMP 6'd20
|
`define JSR 6'd21
|
`define JSR 6'd21
|
|
|
`define TAS 6'd46
|
`define TAS 6'd46
|
`define UNLK 6'd47
|
|
`define LW 6'd48
|
`define LW 6'd48
|
`define LH 6'd49
|
`define LH 6'd49
|
`define LB 6'd50
|
`define LB 6'd50
|
`define LHU 6'd51
|
`define LHU 6'd51
|
`define LBU 6'd52
|
`define LBU 6'd52
|
Line 178... |
Line 185... |
`define SH 6'd57
|
`define SH 6'd57
|
`define SB 6'd58
|
`define SB 6'd58
|
`define PUSH 6'd59
|
`define PUSH 6'd59
|
`define NOP 6'd60
|
`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);
|
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 IFETCH = 8'd1;
|
parameter REGFETCHA = 8'd2;
|
parameter REGFETCHA = 8'd2;
|
parameter REGFETCHB = 8'd3;
|
parameter REGFETCHB = 8'd3;
|
parameter EXECUTE = 8'd4;
|
parameter EXECUTE = 8'd4;
|
Line 220... |
Line 226... |
parameter LINK = 8'd41;
|
parameter LINK = 8'd41;
|
parameter UNLK = 8'd42;
|
parameter UNLK = 8'd42;
|
parameter TAS = 8'd43;
|
parameter TAS = 8'd43;
|
parameter TAS2 = 8'd44;
|
parameter TAS2 = 8'd44;
|
parameter PEA = 8'd45;
|
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 rst_i;
|
input clk_i;
|
input clk_i;
|
input [2:0] ipl_i;
|
input [2:0] ipl_i;
|
input vpa_i;
|
input vpa_i;
|
input halt_i;
|
input halt_i;
|
output inta_o;
|
output inta_o;
|
reg inta_o;
|
reg inta_o;
|
output [2:0] fc_o;
|
output [2:0] fc_o;
|
reg [2:0] fc_o;
|
reg [2:0] fc_o;
|
output rst_o;
|
output rst_o;
|
reg rst_o;
|
|
output cyc_o;
|
output cyc_o;
|
reg cyc_o;
|
reg cyc_o;
|
output stb_o;
|
output stb_o;
|
reg stb_o;
|
reg stb_o;
|
input ack_i;
|
input ack_i;
|
Line 247... |
Line 263... |
reg [31:0] adr_o;
|
reg [31:0] adr_o;
|
input [31:0] dat_i;
|
input [31:0] dat_i;
|
output [31:0] dat_o;
|
output [31:0] dat_o;
|
reg [31:0] dat_o;
|
reg [31:0] dat_o;
|
|
|
|
reg cpu_clk_en;
|
|
reg clk_en;
|
|
wire clk;
|
|
|
reg [7:0] state;
|
reg [7:0] state;
|
reg [31:0] ir;
|
reg [31:0] ir;
|
reg tf,sf;
|
reg tf,sf;
|
reg [31:0] pc;
|
reg [31:0] pc;
|
reg [31:0] usp,ssp;
|
reg [31:0] usp,ssp;
|
reg [31:0] lc;
|
reg [31:0] ctr;
|
wire [5:0] opcode=ir[31:26];
|
wire [5:0] opcode=ir[31:26];
|
|
reg Rcbit;
|
reg [5:0] mopcode;
|
reg [5:0] mopcode;
|
wire [5:0] func=ir[5:0];
|
wire [5:0] func=ir[5:0];
|
|
wire [9:0] func1=ir[10:1];
|
wire [3:0] cond=ir[19:16];
|
wire [3:0] cond=ir[19:16];
|
wire [31:0] brdisp = {{16{ir[15]}},ir[15:2],2'b0};
|
wire [31:0] brdisp = {{16{ir[15]}},ir[15:2],2'b0};
|
reg [4:0] Rn;
|
reg [4:0] Rn;
|
reg [31:0] regfile [31:0];
|
reg [31:0] regfile [31:0];
|
wire [31:0] rfo1 = regfile[Rn];
|
wire [31:0] rfo1 = regfile[Rn];
|
wire [31:0] rfo = (Rn==5'd0) ? 32'd0 : (Rn==5'd31) ? (sf ? ssp : usp) : rfo1;
|
wire [31:0] rfo = (Rn==5'd0) ? 32'd0 : (Rn==5'd31) ? (sf ? ssp : usp) : rfo1;
|
reg vf,nf,cf,zf;
|
reg vf,nf,cf,zf;
|
|
reg xer_ov,xer_ca,xer_so;
|
reg [2:0] im;
|
reg [2:0] im;
|
reg [2:0] iplr;
|
reg [2:0] iplr;
|
reg [7:0] vecnum;
|
reg [7:0] vecnum;
|
reg [31:0] vector;
|
reg [31:0] vector;
|
reg [31:0] ea;
|
reg [31:0] ea;
|
|
reg [15:0] rstsh;
|
|
assign rst_o = rstsh[15];
|
reg prev_nmi;
|
reg prev_nmi;
|
reg nmi_edge;
|
reg nmi_edge;
|
reg [31:0] sr1;
|
reg [31:0] sr1;
|
reg [31:0] tgt;
|
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] as = a;
|
wire signed [31:0] bs = b;
|
wire signed [31:0] bs = b;
|
wire [63:0] muluo = a * b;
|
|
reg [31:0] res;
|
reg [31:0] res;
|
reg [3:0] cr0,cr1,cr2,cr3,cr4,cr5,cr6,cr7;
|
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] cr = {cr7,cr6,cr5,cr4,cr3,cr2,cr1,cr0};
|
wire [31:0] sr = {tf,1'b0,sf,2'b00,im,16'd0};
|
wire [31:0] sr = {tf,1'b0,sf,2'b00,im,16'd0};
|
reg [31:0] tick;
|
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 IsSubi = opcode==`SUBI;
|
wire IsCmpi = opcode==`CMPI;
|
wire IsCmpi = opcode==`CMPI;
|
wire IsSub = opcode==`RR && func==`SUB;
|
wire IsSub = opcode==`RR && func==`SUB;
|
wire IsCmp = opcode==`RR && func==`CMP;
|
wire IsCmp = opcode==`RR && func==`CMP;
|
wire IsNeg = opcode==`R && func==`NEG;
|
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 =
|
wire hasConst16 =
|
opcode==`ADDI || opcode==`SUBI || opcode==`CMPI ||
|
opcode==`ADDI || opcode==`SUBI || opcode==`CMPI ||
|
opcode==`ANDI || opcode==`ORI || opcode==`EORI ||
|
opcode==`ANDI || opcode==`ORI || opcode==`EORI ||
|
opcode==`LW || opcode==`LH || opcode==`LB || opcode==`LHU || opcode==`LBU ||
|
opcode==`LW || opcode==`LH || opcode==`LB || opcode==`LHU || opcode==`LBU ||
|
Line 297... |
Line 332... |
opcode==`PEA || opcode==`TAS || opcode==`LINK
|
opcode==`PEA || opcode==`TAS || opcode==`LINK
|
;
|
;
|
wire isStop =
|
wire isStop =
|
opcode==`MISC && (func==`STOP)
|
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 c_ri,c_rr;
|
wire v_ri,v_rr;
|
wire v_ri,v_rr;
|
carry u1 (.op(IsSubi|IsCmpi), .a(a[31]), .b(imm[31]), .s(res[31]), .c(c_ri));
|
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));
|
carry u2 (.op(IsSub|IsCmp|IsNeg), .a(a[31]), .b(b[31]), .s(res[31]), .c(c_rr));
|
Line 317... |
Line 348... |
BCDSub u6 (.ci(cr0[0]),.a(a[7:0]),.b(b[7:0]),.o(bcdsubo),.c(bcdsubc));
|
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] shlo = {32'd0,a} << b[4:0];
|
wire [63:0] shro = {a,32'd0} >> 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;
|
function GetCrBit;
|
input [4:0] Rn;
|
input [4:0] Rn;
|
begin
|
begin
|
case(Rn[4:2])
|
case(Rn[4:2])
|
3'd0: GetCrBit = cr0[Rn[1:0]];
|
3'd0: GetCrBit = cr0[Rn[1:0]];
|
Line 349... |
Line 388... |
3'd7: GetCr = cr7;
|
3'd7: GetCr = cr7;
|
endcase
|
endcase
|
end
|
end
|
endfunction
|
endfunction
|
|
|
wire [3:0] crc = GetCr(Rn);
|
wire [3:0] crc = GetCr(Rn[4:2]);
|
wire cr_zf = crc[2];
|
wire cr_zf = crc[2];
|
wire cr_nf = crc[3];
|
wire cr_nf = crc[3];
|
wire cr_cf = crc[0];
|
wire cr_cf = crc[0];
|
wire cr_vf = crc[1];
|
wire cr_vf = crc[1];
|
|
|
Line 361... |
Line 400... |
// Clock control
|
// Clock control
|
// - reset or NMI reenables the clock
|
// - reset or NMI reenables the clock
|
// - this circuit must be under the clk_i domain
|
// - 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) );
|
BUFGCE u20 (.CE(cpu_clk_en), .I(clk_i), .O(clk) );
|
|
|
always @(posedge clk_i)
|
always @(posedge clk_i)
|
if (rst_i) begin
|
if (rst_i) begin
|
cpu_clk_en <= 1'b1;
|
cpu_clk_en <= 1'b1;
|
Line 394... |
Line 430... |
inta_o <= 1'b0;
|
inta_o <= 1'b0;
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'b0000;
|
sel_o <= 4'b0000;
|
we_o <= 1'b0;
|
we_o <= 1'b0;
|
rst_o <= 1'b0;
|
|
clk_en <= 1'b1;
|
clk_en <= 1'b1;
|
tick <= 32'd0;
|
tick <= 32'd0;
|
|
rstsh <= 16'hFFFF;
|
end
|
end
|
else begin
|
else begin
|
tick <= tick + 32'd1;
|
tick <= tick + 32'd1;
|
clk_en <= 1'b1;
|
clk_en <= 1'b1;
|
rst_o <= 1'b0;
|
rstsh <= {rstsh,1'b0};
|
prev_nmi <= ipl_i==3'd7;
|
prev_nmi <= ipl_i==3'd7;
|
if (!prev_nmi && (ipl_i==3'd7))
|
if (!prev_nmi && (ipl_i==3'd7))
|
nmi_edge <= 1'b1;
|
nmi_edge <= 1'b1;
|
|
|
case(state)
|
case(state)
|
Line 429... |
Line 465... |
`include "RTS.v"
|
`include "RTS.v"
|
`include "INTA.v"
|
`include "INTA.v"
|
`include "TRAP.v"
|
`include "TRAP.v"
|
`include "RTI.v"
|
`include "RTI.v"
|
|
|
|
`include "MULTDIV.v"
|
|
|
endcase
|
endcase
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|