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

Subversion Repositories thor

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /thor/trunk
    from Rev 36 to Rev 37
    Reverse comparison

Rev 36 → Rev 37

/rtl/verilog/Thor.v
56,7 → 56,7
//
// ============================================================================
// __
// \\__/ o\ (C) 2013,2015 Robert Finch, Stratford
// \\__/ o\ (C) 2013-2016 Robert Finch, Stratford
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
161,6 → 161,7
output reg [DBW-1:0] dat_o;
 
integer n,i;
reg [1:0] mode;
reg [DBW/8-1:0] rsel;
reg [3:0] cstate;
reg [ABW:0] pc; // program counter (virtual)
648,6 → 649,16
 
reg [11:0] spr_bir;
 
always @(StatusHWI or StatusDBG or StatusEXL)
if (StatusHWI)
mode = 2'd1;
else if (StatusDBG)
mode = 2'd3;
else if (StatusEXL)
mode = 2'd2;
else
mode = 2'd0;
 
//
// BRANCH-MISS LOGIC: livetarget
//
955,6 → 966,8
wire [3:0] Pn1 = fetchbuf1_instr[7:4];
wire [3:0] Pt1 = fetchbuf1_instr[11:8];
 
wire [6:0] r27 = 7'd27 + mode;
 
function [6:0] fnRa;
input [63:0] isn;
case(isn[15:8])
967,12 → 980,20
`TLB: fnRa = {1'b0,isn[29:24]};
`P: fnRa = 7'h70;
`LOOP: fnRa = 7'h73;
`PUSH: fnRa = km ? 7'd31 : 7'd27;
`PUSH: fnRa = r27;
`ifdef STACKOPS
`PEA,`POP,`LINK: fnRa = km ? 7'd31 : 7'd27;
`PEA,`POP,`LINK: fnRa = r27;
`endif
`MFSPR,`MOVS: fnRa = {1'b1,isn[`INSTRUCTION_RA]};
default: fnRa = {1'b0,isn[`INSTRUCTION_RA]};
`MFSPR,`MOVS:
if (isn[`INSTRUCTION_RA]==`USP)
fnRa = 7'd27;
else
fnRa = {1'b1,isn[`INSTRUCTION_RA]};
default:
if (isn[`INSTRUCTION_RA]==6'd27)
fnRa = r27;
else
fnRa = {1'b0,isn[`INSTRUCTION_RA]};
endcase
endfunction
 
983,19 → 1004,29
// `RTS,`STP,`TLB,`POP: fnRb = 7'd0;
`JSR,`JSRS,`JSRZ,`SYS,`INT:
fnRb = {3'h5,isn[23:20]};
`SWS: fnRb = {1'b1,isn[27:22]};
`SWS: if (isn[27:22]==`USP)
fnRb = {1'b0,6'd27};
else
fnRb = {1'b1,isn[27:22]};
`PUSH: fnRb = isn[22:16];
`ifdef STACKOPS
`LINK: fnRb = {1'b0,isn[27:22]};
`PEA: fnRb = {1'b0,isn[21:16]};
`endif
default: fnRb = {1'b0,isn[`INSTRUCTION_RB]};
default:
if (isn[`INSTRUCTION_RB]==6'd27)
fnRb = r27;
else
fnRb = {1'b0,isn[`INSTRUCTION_RB]};
endcase
endfunction
 
function [6:0] fnRc;
input [63:0] isn;
fnRc = {1'b0,isn[`INSTRUCTION_RC]};
if (isn[`INSTRUCTION_RC]==6'd27)
fnRc = r27;
else
fnRc = {1'b0,isn[`INSTRUCTION_RC]};
endfunction
 
function [3:0] fnCar;
1074,6 → 1105,7
`ABS,`SGN,`ZXB,`ZXC,`ZXH,`SXB,`SXC,`SXH: fnIsAlu0Op = `TRUE;
default: fnIsAlu0Op = `FALSE;
endcase
`R2: fnIsAlu0Op = `TRUE;
`RR:
case(func)
`DIV,`DIVU: fnIsAlu0Op = `TRUE;
1229,7 → 1261,7
fnSource2_v = `TRUE;
else
fnSource2_v = `FALSE;
`CACHE,`LCL,`TLB,`LLA,`LEA,
`CACHE,`LCL,`TLB,`LLA,
`LVB,`LVC,`LVH,`LVW,`LVWAR,
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWS,`STI,`INC:
fnSource2_v = 1'b1;
1255,7 → 1287,13
// 0 if we need a RF value
function fnSource3_v;
input [7:0] opcode;
input [5:0] func;
case(opcode)
`RR:
case(func)
`CHK: fnSource3_v = 1'b0;
default: fnSource3_v = 1'b1;
endcase
`SBX,`SCX,`SHX,`SWX,`CAS,`STMV,`STCMP,`STFND: fnSource3_v = 1'b0;
`MUX: fnSource3_v = 1'b0;
default: fnSource3_v = 1'b1;
1264,7 → 1302,13
 
function fnSourceT_v;
input [7:0] opcode;
input [5:0] func;
case(opcode)
`RR:
case(func)
`CHK: fnSourceT_v = 1'b1;
default: fnSourceT_v = 1'b0;
endcase
// BR
8'h30,8'h31,8'h32,8'h33,
8'h34,8'h35,8'h36,8'h37,
1271,7 → 1315,7
8'h38,8'h39,8'h3A,8'h3B,
8'h3C,8'h3D,8'h3E,8'h3F,
`SB,`SC,`SH,`SW,`SBX,`SCX,`SHX,`SWX,`SWS,
`CACHE,
`CACHE,`CHKI,
`SEI,`CLI,`NOP,`STP,`RTI,`RTD,`RTE,
`MEMSB,`MEMDB,`SYNC:
fnSourceT_v = 1'b1;
1302,7 → 1346,7
fnNumReadPorts = 3'd1;
else
fnNumReadPorts = 3'd2;
`CACHE,`LCL,`TLB,`LLA,`LEA,
`CACHE,`LCL,`TLB,`LLA,
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,`LWS,`INC:
fnNumReadPorts = 3'd1;
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`RTS2,`BR:
1312,6 → 1356,11
fnNumReadPorts = 3'd3;
`MTSPR,`MFSPR,`POP,`UNLINK: fnNumReadPorts = 3'd1;
`STFND: fnNumReadPorts = 3'd2; // *** TLB reads on Rb we say 2 for simplicity
`RR:
case(ins[39:34])
`CHK: fnNumReadPorts = 3'd3;
default: fnNumReadPorts = 3'd2;
endcase
`BITFIELD:
case(ins[43:40])
`BFSET,`BFCLR,`BFCHG,`BFEXT,`BFEXTU,`BFINSI:
1452,13 → 1501,13
);
`endif
 
Thor_icachemem #(.DBW(DBW),.ABW(ABW)) uicm1
Thor_icachemem #(.DBW(DBW),.ABW(ABW),.ECC(1'b0)) uicm1
(
.wclk(clk),
.wce(cstate==ICACHE1),
.wr(ack_i|err_i),
.wa(adr_o),
.wd({err_i,dat_i}),
.wd(dat_i),
.rclk(~clk),
.pc(ppc),
.insn(insn)
1498,7 → 1547,7
.wr(ack_i|err_i),
.sel(whit ? sel_o : 8'hFF),
.wa(adr_o),
.wd(whit ? dat_o : dat_i),
.wd(whit ? dat_o : dat_i[DBW-1:0]),
.rclk(~clk),
.rce(1'b1),
.ra(pea),
1587,36 → 1636,40
case(fnOpcode(ir))
`POP: fnTargetReg = ir[22:16];
`LDI,`ADDUIS,`STS,`LINK,`UNLINK:
fnTargetReg = {1'b0,ir[21:16]};
if (ir[21:16]==6'd27)
fnTargetReg = r27;
else
fnTargetReg = {1'b0,ir[21:16]};
`LDIS:
fnTargetReg = {1'b1,ir[21:16]};
`RR:
fnTargetReg = {1'b0,ir[33:28]};
`RR,
`SHIFT,
`BCD,
`LOGIC,`FLOAT,
`LWX,`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`STMV,`STCMP,`STFND:
fnTargetReg = {1'b0,ir[33:28]};
`SHIFT:
fnTargetReg = {1'b0,ir[33:28]};
`LOGIC,`FLOAT,
`LWX,`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`STMV,`STCMP,`STFND:
if (ir[33:28]==6'd27)
fnTargetReg = r27;
else
fnTargetReg = {1'b0,ir[33:28]};
`R,`R2,`DOUBLE_R,`SINGLE_R,
`ADDI,`ADDUI,`SUBI,`SUBUI,
`MULI,`MULUI,`DIVI,`DIVUI,`MODI,`MODUI,
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
`ANDI,`ORI,`EORI,`LLA,`LEA,
`ANDI,`ORI,`EORI,`LLA,
`LVB,`LVC,`LVH,`LVW,`LVWAR,
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LINK:
fnTargetReg = {1'b0,ir[27:22]};
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LINK,
`BITFIELD,`MFSPR:
if (ir[27:22]==6'd27)
fnTargetReg = r27;
else
fnTargetReg = {1'b0,ir[27:22]};
`CAS:
fnTargetReg = {1'b0,ir[39:34]};
`BITFIELD:
fnTargetReg = {1'b0,ir[27:22]};
`TLB:
if (ir[19:16]==`TLB_RDREG)
fnTargetReg = {1'b0,ir[29:24]};
else
fnTargetReg = 7'h00;
`MFSPR:
fnTargetReg = {1'b0,ir[27:22]};
`BITI:
fnTargetReg = {3'h4,ir[25:22]};
// TST
1645,7 → 1698,10
`JMPIX:
fnTargetReg = {3'h5,ir[31:28]};
`MTSPR,`MOVS,`LWS:
fnTargetReg = {1'b1,ir[27:22]};
if (ir[27:22]==`USP)
fnTargetReg = {1'b0,6'd27};
else
fnTargetReg = {1'b1,ir[27:22]};
/*
if (ir[27:26]==2'h1) // Move to code address register
fnTargetReg = {3'h5,ir[25:22]};
1656,7 → 1712,7
else
fnTargetReg = 7'h00;
*/
`PUSH: fnTargetReg = km ? 7'd31 : 7'd27;
`PUSH: fnTargetReg = r27;
`LOOP: fnTargetReg = 7'h73;
`STP: fnTargetReg = 7'h7F;
`P: fnTargetReg = 7'h70;
1735,7 → 1791,7
`BFCLR,`BFSET,`BFCHG,`BFEXT,`BFEXTU,`BFINS,
`LDI,`LDIS,`ADDUIS,
`ADDI,`SUBI,`ADDUI,`SUBUI,`MULI,`MULUI,`DIVI,`DIVUI,`MODI,`MODUI,
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,`CHKI,
// CMPI
8'h20,8'h21,8'h22,8'h23,
8'h24,8'h25,8'h26,8'h27,
1803,10 → 1859,10
`SINGLE_R:
if (func==`FTX) fnCanException = `TRUE;
else fnCanException = `FALSE;
`ADDI,`SUBI,`DIVI,`MODI,`MULI:
`ADDI,`SUBI,`DIVI,`MODI,`MULI,`CHKI:
fnCanException = `TRUE;
`RR:
if (func==`ADD || func==`SUB || func==`MUL || func==`DIV || func==`MOD)
if (func==`ADD || func==`SUB || func==`MUL || func==`DIV || func==`MOD || func==`CHK)
fnCanException = `TRUE;
else
fnCanException = `FALSE;
1951,7 → 2007,7
opcode==`LB || opcode==`LBU || opcode==`LC || opcode==`LCU || opcode==`LH || opcode==`LHU || opcode==`LW ||
opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
opcode==`LVB || opcode==`LVH || opcode==`LVC || opcode==`LVW || opcode==`LVWAR || opcode==`SWCR ||
opcode==`STP || opcode==`LLA || opcode==`LLAX || opcode==`LEA ||
opcode==`STP || opcode==`LLA || opcode==`LLAX ||
opcode==`CAS || opcode==`LWS || opcode==`STMV || opcode==`STCMP || opcode==`STFND ||
opcode==`STS || opcode==`PUSH || opcode==`POP || opcode==`LINK || opcode==`UNLINK ||
opcode==`JMPI || opcode==`JMPIX ||
2020,7 → 2076,7
8'h40:
if (fn > 6'h17)
fnIsIllegal = `TRUE;
else if (fn==6'hC || fn==6'hD || fn==6'hE || fn==6'hF || fn==6'h12 || fn==6'h14 || fn==6'h15 || fn==6'h16)
else if (fn==6'hC || fn==6'hD || fn==6'hE || fn==6'hF || fn==6'h12 || fn==6'h15 || fn==6'h16)
fnIsIllegal = `TRUE;
else fnIsIllegal = `FALSE;
8'h41:
2063,7 → 2119,7
else
fnIsIllegal = `FALSE;
8'h43,8'h44,8'h45: fnIsIllegal = `TRUE;
8'h52,8'h56,8'h57,8'h59,8'h5A,8'h5D,8'h5E:
8'h52,8'h56,8'h57,8'h59,8'h5A,8'h5C,8'h5E:
fnIsIllegal = `TRUE;
8'h60,8'h61,8'h62,8'h63,8'h64,8'h65,8'h66,8'h67,8'h68,8'h69:
fnIsIllegal = `TRUE;
2585,7 → 2641,7
`STI: fnImm = {{58{insn[33]}},insn[33:28]};
`PUSH: fnImm = 64'hFFFFFFFFFFFFFFF8; //-8
//`LINK: fnImm = {insn[39:28],3'b000};
`JMPI,`LLA,`LEA,
`JMPI,`LLA,
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,
`SB,`SC,`SH,`SW,`SWCR,`LWS,`SWS,`INC,`LCL,`PEA:
fnImm = {{55{insn[36]}},insn[36:28]};
2619,7 → 2675,7
`ifdef STACKOPS
`LINK: fnImm8 = {insn[32:28],3'b000};
`endif
`JMPI,`LLA,`LEA,
`JMPI,`LLA,
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,
`SB,`SC,`SH,`SW,`SWCR,`LWS,`SWS,`INC,`LCL,`PEA:
fnImm8 = insn[35:28];
2655,7 → 2711,7
`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`LWX,
`SBX,`SCX,`SHX,`SWX:
fnImmMSB = insn[47];
`JMPI,`LLA,`LEA,
`JMPI,`LLA,
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,
`SB,`SC,`SH,`SW,`SWCR,`STI,`LWS,`SWS,`INC,`LCL,`PEA:
fnImmMSB = insn[36];
2747,8 → 2803,8
input [6:0] regx;
`ifdef PRIVCHKS
fnIsKMOnlyReg = regx==7'd28 || regx==7'd29 || regx==7'd30 || regx==7'd31 ||
regx==7'h5B || regx==7'h5C || regx==7'h5D || regx==7'h5E ||
regx==7'h60 || regx==7'h68;
regx==7'h5B || regx==7'h5C || regx==7'h5D || regx==7'h5E
;
`else
fnIsKMOnlyReg = `FALSE;
`endif
3819,7 → 3875,10
 
if (alu0_v) begin
if (|alu0_exc)
set_exception(alu0_id, alu0_exc==`EXC_DBZ ? 8'd241 : 8'h00);
set_exception(alu0_id,
alu0_exc==`EXC_PRIV ? 8'd245 :
alu0_exc==`EXC_DBZ ? 8'd241 :
alu0_exc==`EXC_CHK ? 8'd239 : 8'h00);
else begin
if (iqentry_op[alu0_id[2:0]]!=`IMM)
iqentry_done[ alu0_id[2:0] ] <= (!iqentry_mem[ alu0_id[2:0] ] || !alu0_cmt);
3848,7 → 3907,10
 
if (alu1_v) begin
if (|alu1_exc)
set_exception(alu1_id, alu1_exc==`EXC_DBZ ? 8'd241 : 8'h00);
set_exception(alu1_id,
alu1_exc==`EXC_PRIV ? 8'd245 :
alu1_exc==`EXC_DBZ ? 8'd241 :
alu1_exc==`EXC_CHK ? 8'd239 : 8'h00);
else begin
if (iqentry_op[alu1_id[2:0]]!=`IMM)
iqentry_done[ alu1_id[2:0] ] <= (!iqentry_mem[ alu1_id[2:0] ] || !alu1_cmt);
4691,7 → 4753,7
if (dram0_op==`SWCR)
dram_bus <= {63'd0,resv_i};
else
dram_bus <= fnDatai(dram0_op,dram0_fn,dat_i,rsel);
dram_bus <= fnDatai(dram0_op,dram0_fn,dat_i[DBW-1:0],rsel);
dram0_owns_bus <= `FALSE;
wb_nack();
dram0 <= 3'd7;
4718,7 → 4780,7
if (stmv_flag) begin
dram0_addr <= src_addr + index;
if (dram0_op==`STCMP) begin
if (dram0_data != fnDatai(dram0_op,dram0_fn,dat_i,rsel)) begin
if (dram0_data != fnDatai(dram0_op,dram0_fn,dat_i[DBW-1:0],rsel)) begin
lc <= 64'd0;
dram0 <= 3'd7;
dram_v <= `VAL;
4727,7 → 4789,7
end
else begin
dram0_addr <= dst_addr + index;
dram0_data <= fnDatai(dram0_op,dram0_fn,dat_i,rsel);
dram0_data <= fnDatai(dram0_op,dram0_fn,dat_i[DBW-1:0],rsel);
end
if (!stmv_flag)
inc_index(dram0_fn);
4742,7 → 4804,7
if (lc != 0 && !int_pending) begin
dram0_addr <= src_addr + index;
inc_index(dram0_fn);
if (dram0_data == fnDatai(dram0_op,dram0_fn,dat_i,rsel)) begin
if (dram0_data == fnDatai(dram0_op,dram0_fn,dat_i[DBW-1:0],rsel)) begin
lc <= 64'd0;
dram_v <= `VAL;
dram_bus <= index;
4757,7 → 4819,7
end
`endif
`CAS:
if (dram0_datacmp == dat_i) begin
if (dram0_datacmp == dat_i[DBW-1:0]) begin
$display("CAS match");
dram0_owns_bus <= `TRUE;
cyc_o <= 1'b1; // hold onto cyc_o
4774,7 → 4836,7
dram0 <= 3'd0;
end
else begin
dram0_data <= fnDatai(dram0_op,dram0_fn,dat_i,rsel);
dram0_data <= fnDatai(dram0_op,dram0_fn,dat_i[DBW-1:0],rsel);
stmv_flag <= ~stmv_flag;
dram0 <= 3'd1;
end
5695,7 → 5757,7
$stop;
if (fetchbuf0_pc==32'hF44)
$stop;
if (fetchbuf0_pc==32'hFFFC2F71)
if (fetchbuf0_pc==32'hFFFC275A)
$stop;
`ifdef SEGMENTATION
`ifdef SEGLIMITS
5929,7 → 5991,7
$stop;
if (fetchbuf1_pc==32'hF44)
$stop;
if (fetchbuf1_pc==32'hFFFC2F71)
if (fetchbuf1_pc==32'hFFFC275A)
$stop;
`ifdef SEGMENTATION
`ifdef SEGLIMITS
6099,8 → 6161,8
iqentry_p_v [tail] <= rf_v [{1'b1,2'h0,Pn0}] || cond0 < 4'h2;
iqentry_a1_v [tail] <= fnSource1_v( opcode0 ) | rf_v[ Ra0 ];
iqentry_a2_v [tail] <= fnSource2_v( opcode0, fnFunc(fetchbuf0_instr)) | rf_v[Rb0];
iqentry_a3_v [tail] <= fnSource3_v( opcode0 ) | rf_v[ Rc0 ];
iqentry_T_v [tail] <= fnSourceT_v( opcode0 ) | rf_v[ Rt0 ];
iqentry_a3_v [tail] <= fnSource3_v( opcode0, fnFunc(fetchbuf0_instr)) | rf_v[ Rc0 ];
iqentry_T_v [tail] <= fnSourceT_v( opcode0, fnFunc(fetchbuf0_instr)) | rf_v[ Rt0 ];
if (fetchbuf0_rfw|fetchbuf0_pfw) begin
$display("regv[%d] = %d", Rt0,rf_v[ Rt0 ]);
rf_v[ Rt0 ] = fnRegIsAutoValid(Rt0);
6118,9 → 6180,9
// The predicate is automatically valid for condiitions 0 and 1 (always false or always true).
iqentry_p_v [tail] <= rf_v [{1'b1,2'h0,Pn1}] || cond1 < 4'h2;
iqentry_a1_v [tail] <= fnSource1_v( opcode1 ) | rf_v[ Ra1 ];
iqentry_a2_v [tail] <= fnSource2_v( opcode1, fnFunc(fetchbuf1_instr) ) | rf_v[ Rb1 ];
iqentry_a3_v [tail] <= fnSource3_v( opcode1 ) | rf_v[ Rc1 ];
iqentry_T_v [tail] <= fnSourceT_v( opcode1 ) | rf_v[ Rt1 ];
iqentry_a2_v [tail] <= fnSource2_v( opcode1, fnFunc(fetchbuf1_instr)) | rf_v[ Rb1 ];
iqentry_a3_v [tail] <= fnSource3_v( opcode1, fnFunc(fetchbuf1_instr)) | rf_v[ Rc1 ];
iqentry_T_v [tail] <= fnSourceT_v( opcode1, fnFunc(fetchbuf1_instr)) | rf_v[ Rt1 ];
if (fetchbuf1_rfw|fetchbuf1_pfw) begin
$display("1:regv[%d] = %d", Rt1,rf_v[ Rt1 ]);
rf_v[ Rt1 ] = fnRegIsAutoValid(Rt1);
6210,7 → 6272,7
// that have a source (i.e. every instruction but LUI) read from RC
//
// if the argument is an immediate or not needed, we're done
if (fnSource3_v( opcode1 ) == `VAL) begin
if (fnSource3_v( opcode1,fnFunc(fetchbuf1_instr) ) == `VAL) begin
iqentry_a3_v [tail1] <= `VAL;
iqentry_a3_v [tail1] <= 4'hF;
// iqentry_a1_s [tail1] <= 4'd0;
6238,7 → 6300,7
// that have a source (i.e. every instruction but LUI) read from RC
//
// if the argument is an immediate or not needed, we're done
if (fnSourceT_v( opcode1 ) == `VAL) begin
if (fnSourceT_v( opcode1,fnFunc(fetchbuf1_instr) ) == `VAL) begin
iqentry_T_v [tail1] <= `VAL;
iqentry_T_v [tail1] <= 4'hF;
end
6415,22 → 6477,22
input mem;
begin
if (Rt==7'h70) begin
rf_v[7'h40] <= `INV;
rf_v[7'h41] <= `INV;
rf_v[7'h42] <= `INV;
rf_v[7'h43] <= `INV;
rf_v[7'h44] <= `INV;
rf_v[7'h45] <= `INV;
rf_v[7'h46] <= `INV;
rf_v[7'h47] <= `INV;
rf_v[7'h48] <= `INV;
rf_v[7'h49] <= `INV;
rf_v[7'h4A] <= `INV;
rf_v[7'h4B] <= `INV;
rf_v[7'h4C] <= `INV;
rf_v[7'h4D] <= `INV;
rf_v[7'h4E] <= `INV;
rf_v[7'h4F] <= `INV;
rf_v[7'h40] = `INV;
rf_v[7'h41] = `INV;
rf_v[7'h42] = `INV;
rf_v[7'h43] = `INV;
rf_v[7'h44] = `INV;
rf_v[7'h45] = `INV;
rf_v[7'h46] = `INV;
rf_v[7'h47] = `INV;
rf_v[7'h48] = `INV;
rf_v[7'h49] = `INV;
rf_v[7'h4A] = `INV;
rf_v[7'h4B] = `INV;
rf_v[7'h4C] = `INV;
rf_v[7'h4D] = `INV;
rf_v[7'h4E] = `INV;
rf_v[7'h4F] = `INV;
rf_source[7'h40] <= { mem, tail };
rf_source[7'h41] <= { mem, tail };
rf_source[7'h42] <= { mem, tail };
/rtl/verilog/Thor_alu.v
1,6 → 1,6
// ============================================================================
// __
// \\__/ o\ (C) 2013,2015 Robert Finch, Stratford
// \\__/ o\ (C) 2013-2016 Robert Finch, Stratford
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
178,7 → 178,7
wire feq = (faz & fbz) || (alu_argA==alu_argB); // special test for zero
wire fgt1 = alu_argA[DBW-2:0] > alu_argB[DBW-2:0];
wire flt1 = alu_argA[DBW-2:0] < alu_argB[DBW-2:0];
wire flt = alu_argA[DBW] ^ alu_argB[DBW] ? alu_argA[DBW] & !(faz & fbz): alu_argA[DBW] ? fgt1 : flt1;
wire flt = alu_argA[DBW-1] ^ alu_argB[DBW-1] ? alu_argA[DBW-1] & !(faz & fbz): alu_argA[DBW-1] ? fgt1 : flt1;
wire nanA = DBW==32 ? alu_argA[30:23]==8'hFF && (alu_argA[22:0]!=23'd0) : alu_argA[62:52]==11'h7FF && (alu_argA[51:0]!=52'd0);
wire nanB = DBW==32 ? alu_argB[30:23]==8'hFF && (alu_argB[22:0]!=23'd0) : alu_argB[62:52]==11'h7FF && (alu_argB[51:0]!=52'd0);
 
208,6 → 208,7
`MUL,`MULU: o <= BIG ? alu_prod[63:0] : 64'hDEADDEADDEADDEAD;
`DIV,`DIVU: o <= BIG ? alu_divq : 64'hDEADDEADDEADDEAD;
`MOD,`MODU: o <= BIG ? alu_rem : 64'hDEADDEADDEADDEAD;
`CHK: o <= ($signed(alu_argC) >= $signed(alu_argA)) && ($signed(alu_argC) < $signed(alu_argB));
default: o <= 64'hDEADDEADDEADDEAD;
endcase
`MULI,`MULUI: o <= BIG ? alu_prod[63:0] : 64'hDEADDEADDEADDEAD;
222,8 → 223,8
`MOV: o <= alu_argA;
`NEG: o <= -alu_argA;
`NOT: o <= |alu_argA ? 64'd0 : 64'd1;
`ABS: o <= BIG ? (alu_argA[DBW] ? -alu_argA : alu_argA) : 64'hDEADDEADDEADDEAD;
`SGN: o <= BIG ? (alu_argA[DBW] ? 64'hFFFFFFFFFFFFFFFF : alu_argA==64'd0 ? 64'd0 : 64'd1) : 64'hDEADDEADDEADDEAD;
`ABS: o <= BIG ? (alu_argA[DBW-1] ? -alu_argA : alu_argA) : 64'hDEADDEADDEADDEAD;
`SGN: o <= BIG ? (alu_argA[DBW-1] ? 64'hFFFFFFFFFFFFFFFF : alu_argA==64'd0 ? 64'd0 : 64'd1) : 64'hDEADDEADDEADDEAD;
`CNTLZ: o <= BIG ? cntlzo : 64'hDEADDEADDEADDEAD;
`CNTLO: o <= BIG ? cntloo : 64'hDEADDEADDEADDEAD;
`CNTPOP: o <= BIG ? cntpopo : 64'hDEADDEADDEADDEAD;
288,7 → 289,7
o <= 64'hDEADDEADDEADDEAD;
*/
 
`ADDI,`ADDUI,`ADDUIS,`LEA:
`ADDI,`ADDUI,`ADDUIS:
o <= alu_argA + alu_argI;
`SUBI,`SUBUI:
o <= alu_argA - alu_argI;
437,6 → 438,7
`BITFIELD: o <= BIG ? bf_out : 64'hDEADDEADDEADDEAD;
`endif
`LOOP: o <= alu_argA > 0 ? alu_argA - 64'd1 : alu_argA;
`CHKI: o <= ($signed(alu_argB) >= $signed(alu_argA)) && ($signed(alu_argB) < $signed(alu_argI));
default: o <= 64'hDEADDEADDEADDEAD;
endcase
end
/rtl/verilog/Thor_execute_combo.v
1,6 → 1,6
// ============================================================================
// __
// \\__/ o\ (C) 2013,2015 Robert Finch, Stratford
// \\__/ o\ (C) 2013-2016 Robert Finch, Stratford
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
114,7 → 114,7
assign alu0_abort = !alu0_cmt;
assign alu1_abort = !alu1_cmt;
 
// Special flag nybble is used for INT and SYS instructions in order to turn off
// Special flag bit is used for INT and SYS instructions in order to turn off
// segmentation while the vector jump is taking place.
 
always @(alu0_op or alu0_fn or alu0_argA or alu0_argI or alu0_insnsz or alu0_pc or alu0_bt)
152,44 → 152,17
2'd3: jmpi_misspc <= dram_bus[DBW-1:0];
default: jmpi_misspc <= 32'h00000FA0; // unimplemented instruction vector
endcase
/*
assign alu0_misspc = (alu0_op == `JSR || alu0_op==`JSRS || alu0_op==`JSRZ ||
alu0_op==`RTS || alu0_op==`RTS2 || alu0_op == `RTE || alu0_op==`RTI || alu0_op==`LOOP) ? alu0_argA + alu0_argI :
(alu0_op == `SYS || alu0_op==`INT) ? alu0_argA + {alu0_argI[DBW-5:0],4'b0} :
(alu0_bt ? alu0_pc + alu0_insnsz : alu0_pc + alu0_insnsz + alu0_argI),
alu1_misspc = (alu1_op == `JSR || alu1_op==`JSRS || alu1_op==`JSRZ ||
alu1_op==`RTS || alu1_op == `RTE || alu1_op==`RTI || alu1_op==`LOOP) ? alu1_argA + alu1_argI :
(alu1_op == `SYS || alu1_op==`INT) ? alu1_argA + {alu1_argI[DBW-5:0],4'b0} :
(alu1_bt ? alu1_pc + alu1_insnsz : alu1_pc + alu1_insnsz + alu1_argI);
*/
assign alu0_exc = (fnIsKMOnly(alu0_op) && !km) ? `EXC_PRIV :
(alu0_done && alu0_divByZero) ? `EXC_DBZ : `EXC_NONE;
 
// ? `EXC_NONE
// : (alu0_argB[`INSTRUCTION_S1] == `SYS_NONE) ? `EXC_NONE
// : (alu0_argB[`INSTRUCTION_S1] == `SYS_CALL) ? alu0_argB[`INSTRUCTION_S2]
// : (alu0_argB[`INSTRUCTION_S1] == `SYS_MFSR) ? `EXC_NONE
// : (alu0_argB[`INSTRUCTION_S1] == `SYS_MTSR) ? `EXC_NONE
// : (alu0_argB[`INSTRUCTION_S1] == `SYS_RFU1) ? `EXC_INVALID
// : (alu0_argB[`INSTRUCTION_S1] == `SYS_RFU2) ? `EXC_INVALID
// : (alu0_argB[`INSTRUCTION_S1] == `SYS_RFU3) ? `EXC_INVALID
// : (alu0_argB[`INSTRUCTION_S1] == `SYS_EXC) ? alu0_argB[`INSTRUCTION_S2]
// : `EXC_INVALID;
assign alu0_exc = (fnIsKMOnly(alu0_op) && !km && alu0_cmt) ? `EXC_PRIV :
(alu0_done && alu0_divByZero && alu0_cmt) ? `EXC_DBZ :
((alu0_op==`CHKI||(alu0_op==`RR && alu0_fn==`CHK)) && !alu0_out && alu0_cmt) ? `EXC_CHK :
`EXC_NONE;
 
assign alu1_exc = (fnIsKMOnly(alu1_op) && !km) ? `EXC_PRIV :
(alu1_done && alu1_divByZero) ? `EXC_DBZ : `EXC_NONE;
assign alu1_exc = (fnIsKMOnly(alu1_op) && !km && alu1_cmt) ? `EXC_PRIV :
(alu1_done && alu1_divByZero && alu1_cmt) ? `EXC_DBZ :
((alu1_op==`CHKI ||(alu1_op==`RR && alu1_fn==`CHK)) && !alu1_out && alu1_cmt) ? `EXC_CHK :
`EXC_NONE;
 
// ? `EXC_NONE
// : (alu1_argB[`INSTRUCTION_S1] == `SYS_NONE) ? `EXC_NONE
// : (alu1_argB[`INSTRUCTION_S1] == `SYS_CALL) ? alu1_argB[`INSTRUCTION_S2]
// : (alu1_argB[`INSTRUCTION_S1] == `SYS_MFSR) ? `EXC_NONE
// : (alu1_argB[`INSTRUCTION_S1] == `SYS_MTSR) ? `EXC_NONE
// : (alu1_argB[`INSTRUCTION_S1] == `SYS_RFU1) ? `EXC_INVALID
// : (alu1_argB[`INSTRUCTION_S1] == `SYS_RFU2) ? `EXC_INVALID
// : (alu1_argB[`INSTRUCTION_S1] == `SYS_RFU3) ? `EXC_INVALID
// : (alu1_argB[`INSTRUCTION_S1] == `SYS_EXC) ? alu1_argB[`INSTRUCTION_S2]
// : `EXC_INVALID;
 
assign alu0_branchmiss = alu0_dataready &&
((fnIsBranch(alu0_op)) ? ((alu0_cmt && !alu0_bt) || (!alu0_cmt && alu0_bt))
: !alu0_cmt ? (alu0_op==`LOOP)
/rtl/verilog/Thor_icachemem.v
26,11 → 26,12
module Thor_icachemem(wclk, wce, wr, wa, wd, rclk, pc, insn);
parameter DBW=64;
parameter ABW=32;
parameter ECC=1'b0;
input wclk;
input wce;
input wr;
input [ABW-1:0] wa;
input [DBW-1:0] wd;
input [(ECC?((DBW==64)?DBW+13:DBW+6):DBW-1):0] wd;
input rclk;
input [ABW-1:0] pc;
output reg [127:0] insn;
37,11 → 38,15
 
wire [127:0] insn0;
wire [127:0] insn1;
wire [(ECC?155:127):0] insn0a;
wire [(ECC?155:127):0] insn1a;
 
generate
begin : cache_mem
if (DBW==32) begin
blk_mem_gen_0 uicm1 (
if (ECC) begin
/*
blk_mem_gen_2 uicm1 (
.clka(wclk), // input wire clka
.ena(wce), // input wire ena
.wea(wr), // input wire [0 : 0] wea
50,32 → 55,114
.clkb(rclk), // input wire clkb
.enb(1'b1),
.addrb(pc[14:4]), // input wire [12 : 0] addrb
.doutb(insn0) // output wire [127 : 0] doutb
.doutb(insn0a) // output wire [127 : 0] doutb
);
 
blk_mem_gen_2 uicm2 (
.clka(wclk), // input wire clka
.ena(wce), // input wire ena
.wea(wr), // input wire [0 : 0] wea
.addra(wa[14:2]), // input wire [14 : 0] addra
.dina(wd), // input wire [31 : 0] dina
.clkb(rclk), // input wire clkb
.enb(1'b1),
.addrb(pc[14:4]+11'd1), // input wire [12 : 0] addrb
.doutb(insn1a) // output wire [127 : 0] doutb
);
*/
end
else begin
icache_ram uicm1 (
.wclk(wclk),
.wce(wce),
.wr(wr),
.wa(wa[14:2]),
.d(wd[31:0]),
.rclk(rclk),
.rce(1'b1),
.ra(pc[14:4]),
.q(insn0a)
);
 
icache_ram uicm2 (
.wclk(wclk),
.wce(wce),
.wr(wr),
.wa(wa[14:2]),
.d(wd[31:0]),
.rclk(rclk),
.rce(1'b1),
.ra(pc[14:4]+11'd1),
.q(insn1a)
);
/*
blk_mem_gen_0 uicm1 (
.clka(wclk), // input wire clka
.ena(wce), // input wire ena
.wea(wr), // input wire [0 : 0] wea
.addra(wa[14:2]), // input wire [14 : 0] addra
.dina(wd[31:0]), // input wire [31 : 0] dina
.clkb(rclk), // input wire clkb
.enb(1'b1),
.addrb(pc[14:4]), // input wire [12 : 0] addrb
.doutb(insn0a) // output wire [127 : 0] doutb
);
 
blk_mem_gen_0 uicm2 (
.clka(wclk), // input wire clka
.ena(wce), // input wire ena
.wea(wr), // input wire [0 : 0] wea
.addra(wa[14:2]), // input wire [14 : 0] addra
.dina(wd[31:0]), // input wire [31 : 0] dina
.clkb(rclk), // input wire clkb
.enb(1'b1),
.addrb(pc[14:4]+11'd1), // input wire [12 : 0] addrb
.doutb(insn1a) // output wire [127 : 0] doutb
);
*/
end
 
end
else begin
if (ECC) begin
/*
blk_mem_gen_3 uicm1 (
.clka(wclk), // input wire clka
.ena(wce), // input wire ena
.wea(wr), // input wire [0 : 0] wea
.addra(wa[14:3]), // input wire [14 : 0] addra
.dina(wd), // input wire [31 : 0] dina
.clkb(rclk), // input wire clkb
.enb(1'b1),
.addrb(pc[14:4]), // input wire [12 : 0] addrb
.doutb(insn0a) // output wire [127 : 0] doutb
);
 
blk_mem_gen_3 uicm2 (
.clka(wclk), // input wire clka
.ena(wce), // input wire ena
.wea(wr), // input wire [0 : 0] wea
.addra(wa[14:3]), // input wire [14 : 0] addra
.dina(wd), // input wire [31 : 0] dina
.clkb(rclk), // input wire clkb
.enb(1'b1),
.addrb(pc[14:4]+11'd1), // input wire [12 : 0] addrb
.doutb(insn1) // output wire [127 : 0] doutb
.doutb(insn1a) // output wire [127 : 0] doutb
);
*/
end
else begin
/*
blk_mem_gen_1 uicm1 (
.clka(wclk), // input wire clka
.ena(wce), // input wire ena
.wea(wr), // input wire [0 : 0] wea
.addra(wa[14:3]), // input wire [14 : 0] addra
.dina(wd), // input wire [31 : 0] dina
.dina(wd[63:0]), // input wire [31 : 0] dina
.clkb(rclk), // input wire clkb
.enb(1'b1),
.addrb(pc[14:4]), // input wire [12 : 0] addrb
.doutb(insn0) // output wire [127 : 0] doutb
.doutb(insn0a) // output wire [127 : 0] doutb
);
 
blk_mem_gen_1 uicm2 (
83,17 → 170,96
.ena(wce), // input wire ena
.wea(wr), // input wire [0 : 0] wea
.addra(wa[14:3]), // input wire [14 : 0] addra
.dina(wd), // input wire [31 : 0] dina
.dina(wd[63:0]), // input wire [31 : 0] dina
.clkb(rclk), // input wire clkb
.enb(1'b1),
.addrb(pc[14:4]+11'd1), // input wire [12 : 0] addrb
.doutb(insn1) // output wire [127 : 0] doutb
.doutb(insn1a) // output wire [127 : 0] doutb
);
*/
end
end
 
end
endgenerate
 
generate
begin : ECCx
if (ECC) begin
/*
ecc_0 uecc1a (
.ecc_correct_n(1'b0), // input wire ecc_correct_n
.ecc_data_in(insn0a[31:0]), // input wire [31 : 0] ecc_data_in
.ecc_data_out(insn0[31:0]), // output wire [31 : 0] ecc_data_out
.ecc_chkbits_in({insn0a[37:32],insn0a[38]}), // input wire [6 : 0] ecc_chkbits_in
.ecc_sbit_err(), // output wire ecc_sbit_err
.ecc_dbit_err() // output wire ecc_dbit_err
);
ecc_0 uecc1b (
.ecc_correct_n(1'b0), // input wire ecc_correct_n
.ecc_data_in(insn0a[70:39]), // input wire [31 : 0] ecc_data_in
.ecc_data_out(insn0[63:32]), // output wire [31 : 0] ecc_data_out
.ecc_chkbits_in({insn0a[76:71],insn0a[77]}), // input wire [6 : 0] ecc_chkbits_in
.ecc_sbit_err(), // output wire ecc_sbit_err
.ecc_dbit_err() // output wire ecc_dbit_err
);
ecc_0 uecc1c (
.ecc_correct_n(1'b0), // input wire ecc_correct_n
.ecc_data_in(insn0a[109:78]), // input wire [31 : 0] ecc_data_in
.ecc_data_out(insn0[95:64]), // output wire [31 : 0] ecc_data_out
.ecc_chkbits_in({insn0a[115:110],insn0a[116]}), // input wire [6 : 0] ecc_chkbits_in
.ecc_sbit_err(), // output wire ecc_sbit_err
.ecc_dbit_err() // output wire ecc_dbit_err
);
ecc_0 uecc1d (
.ecc_correct_n(1'b0), // input wire ecc_correct_n
.ecc_data_in(insn0a[148:117]), // input wire [31 : 0] ecc_data_in
.ecc_data_out(insn0[127:96]), // output wire [31 : 0] ecc_data_out
.ecc_chkbits_in({insn0a[154:149],insn0a[155]}), // input wire [6 : 0] ecc_chkbits_in
.ecc_sbit_err(), // output wire ecc_sbit_err
.ecc_dbit_err() // output wire ecc_dbit_err
);
ecc_0 uecc2a (
.ecc_correct_n(1'b0), // input wire ecc_correct_n
.ecc_data_in(insn1a[31:0]), // input wire [31 : 0] ecc_data_in
.ecc_data_out(insn1[31:0]), // output wire [31 : 0] ecc_data_out
.ecc_chkbits_in({insn1a[37:32],insn1a[38]}), // input wire [6 : 0] ecc_chkbits_in
.ecc_sbit_err(), // output wire ecc_sbit_err
.ecc_dbit_err() // output wire ecc_dbit_err
);
ecc_0 uecc2b (
.ecc_correct_n(1'b0), // input wire ecc_correct_n
.ecc_data_in(insn1a[70:39]), // input wire [31 : 0] ecc_data_in
.ecc_data_out(insn1[63:32]), // output wire [31 : 0] ecc_data_out
.ecc_chkbits_in({insn1a[76:71],insn1a[77]}), // input wire [6 : 0] ecc_chkbits_in
.ecc_sbit_err(), // output wire ecc_sbit_err
.ecc_dbit_err() // output wire ecc_dbit_err
);
ecc_0 uecc2c (
.ecc_correct_n(1'b0), // input wire ecc_correct_n
.ecc_data_in(insn1a[109:78]), // input wire [31 : 0] ecc_data_in
.ecc_data_out(insn1[95:64]), // output wire [31 : 0] ecc_data_out
.ecc_chkbits_in({insn1a[115:110],insn1a[116]}), // input wire [6 : 0] ecc_chkbits_in
.ecc_sbit_err(), // output wire ecc_sbit_err
.ecc_dbit_err() // output wire ecc_dbit_err
);
ecc_0 uecc2d (
.ecc_correct_n(1'b0), // input wire ecc_correct_n
.ecc_data_in(insn1a[148:117]), // input wire [31 : 0] ecc_data_in
.ecc_data_out(insn1[127:96]), // output wire [31 : 0] ecc_data_out
.ecc_chkbits_in({insn1a[154:149],insn1a[155]}), // input wire [6 : 0] ecc_chkbits_in
.ecc_sbit_err(), // output wire ecc_sbit_err
.ecc_dbit_err() // output wire ecc_dbit_err
);
*/
end
else begin
assign insn0 = insn0a;//{insn0a[148:117],insn0a[109:78],insn0a[70:39],insn0a[31:0]};
assign insn1 = insn1a;//{insn1a[148:117],insn1a[109:78],insn1a[70:39],insn1a[31:0]};
end
end
endgenerate
 
always @(pc or insn0 or insn1)
case(pc[3:0])
4'd0: insn <= insn0;
/rtl/verilog/Thor_defines.v
68,6 → 68,7
`define MIN 6'h10
`define MAX 6'h11
`define MOD 6'h13
`define CHK 6'h14
`define MODU 6'h17
`define R2 8'h41
`define CPUID 4'h0
121,7 → 122,7
`define ROLI 6'h14
`define RORI 6'h15
`define MODI 8'h5B
`define LEA 8'h5C
`define CHKI 8'h5D
`define MODUI 8'h5F
 
`define LLA 8'h6A // compute linear address
350,6 → 351,7
`define EXC_FLT 4'd10 // floating point exception
`define EXC_DBG 4'd11
`define EXC_PRIV 4'd12
`define EXC_CHK 4'd13
//
// define PANIC types
//

powered by: WebSVN 2.1.0

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