OpenCores
URL https://opencores.org/ocsvn/klc32/klc32/trunk

Subversion Repositories klc32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /klc32
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/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
 
/trunk/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
/trunk/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
/trunk/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
/trunk/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
/trunk/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
 
/trunk/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
/trunk/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
/trunk/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.
 
/trunk/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
/trunk/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
 
/trunk/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
/trunk/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
/trunk/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
/trunk/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
/trunk/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
/trunk/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
 
/trunk/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
 
/trunk/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
 
/trunk/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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.