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

Subversion Repositories klc32

[/] [klc32/] [trunk/] [rtl/] [verilog/] [KLC32.v] - Rev 10

Go to most recent revision | Compare with Previous | Blame | View Log

// ============================================================================
// (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'd1
`define SGN			6'd2
`define NEG			6'd3
`define NOT			6'd4
`define EXTB		6'd5
`define EXTH		6'd6
`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 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 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
`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 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
`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 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
`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 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 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;
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;
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;
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 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] 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;
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 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,aa,bb;
wire signed [31:0] as = a;
wire signed [31:0] bs = 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 ||
	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 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];
 
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
	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[4:2]);
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
//-----------------------------------------------------------------------------
//
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;
	clk_en <= 1'b1;
	tick <= 32'd0;
	rstsh <= 16'hFFFF;
end
else begin
tick <= tick + 32'd1;
clk_en <= 1'b1;
rstsh <= {rstsh,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"
 
`include "MULTDIV.v"
 
endcase
end
 
endmodule
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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