URL
https://opencores.org/ocsvn/rf6809/rf6809/trunk
Subversion Repositories rf6809
Compare Revisions
- This comparison shows the changes necessary to convert path
/rf6809/trunk/rtl
- from Rev 21 to Rev 22
- ↔ Reverse comparison
Rev 21 → Rev 22
/cpu/rf6809.sv
55,6 → 55,10
parameter STORE2 = 6'd11; |
parameter OUTER_INDEXING = 6'd12; |
parameter OUTER_INDEXING2 = 6'd13; |
parameter DIV1 = 6'd16; |
parameter DIV2 = 6'd17; |
parameter DIV3 = 6'd18; |
parameter MUL2 = 6'd20; |
parameter ICACHE1 = 6'd31; |
parameter ICACHE2 = 6'd32; |
parameter ICACHE3 = 6'd33; |
108,7 → 112,7
reg [`TRPBYTE] ibufadr, icwa; |
reg [191:0] ibuf; |
wire ibufhit = ibufadr==pc; |
reg natMd,firqMd; |
reg natMd,firqMd,iplMd,dbz,iop; |
reg md32; |
wire [`DBLBYTE] mask = 24'hFFFFFF; |
reg [1:0] ipg; |
123,13 → 127,18
`endif |
reg [`LOBYTE] dpr; // direct page register |
reg [`DBLBYTE] usppg; // user stack pointer page |
|
Address [3:0] brkad; // breakpoint addresses |
brkCtrl [3:0] brkctrl; |
|
wire [`LOBYTE] ndxbyte; |
reg cf,vf,zf,nf,hf,ef; |
wire [`LOBYTE] cfx8 = cf; |
wire [`DBLBYTE] cfx24 = {23'b0,cf}; |
reg im,firqim; |
reg im,im1,firqim; |
reg dm; // decimal mode |
reg sync_state,wait_state; |
wire [`LOBYTE] ccr = {ef,firqim,hf,im,nf,zf,vf,cf}; |
wire [`LOBYTE] ccr = bitsPerByte==12 ? {2'b00,im1,dm,ef,firqim,hf,im,nf,zf,vf,cf} : {ef,firqim,hf,im,nf,zf,vf,cf}; |
reg [`LOBYTE] acca,accb; |
`ifdef SUPPORT_6309 |
reg [`LOBYTE] acce,accf; |
197,6 → 206,8
always_comb |
dati = dat_i; |
|
genvar g; |
|
// Evaluate the branch conditional |
reg takb; |
always_comb |
371,6 → 382,11
13'b01???00000100: NdxAddr <= ndxreg; |
13'b01???00000101: NdxAddr <= ndxreg + {{BPB*2{accb[BPBM1]}},accb}; |
13'b01???00000110: NdxAddr <= ndxreg + {{BPB*2{acca[BPBM1]}},acca}; |
`ifdef SUPPORT_6309 |
13'b01???00010101: NdxAddr <= ndxreg + {{BPB*2{accf[BPBM1]}},accf}; |
13'b01???00010110: NdxAddr <= ndxreg + {{BPB*2{acce[BPBM1]}},acce}; |
13'b01???00011011: NdxAddr <= ndxreg + {acce,accf}; |
`endif |
13'b01???00001000: NdxAddr <= ndxreg + offset12; |
13'b01???00001001: NdxAddr <= ndxreg + offset24; |
13'b01???00001010: NdxAddr <= ndxreg + offset36; |
387,6 → 403,11
13'b01???10000100: NdxAddr <= 24'd0; |
13'b01???10000101: NdxAddr <= {{BPB*2{accb[BPBM1]}},accb}; |
13'b01???10000110: NdxAddr <= {{BPB*2{acca[BPBM1]}},acca}; |
`ifdef SUPPORT_6309 |
13'b01???10010101: NdxAddr <= {{BPB*2{accf[BPBM1]}},accf}; |
13'b01???10010110: NdxAddr <= {{BPB*2{acce[BPBM1]}},acce}; |
13'b01???10011011: NdxAddr <= {acce,accf}; |
`endif |
13'b01???10001000: NdxAddr <= offset12; |
13'b01???10001001: NdxAddr <= offset24; |
13'b01???10001010: NdxAddr <= offset36; |
448,12 → 469,12
12'b1???00000010: insnsz <= 4'h2; |
12'b1???00000011: insnsz <= 4'h2; |
12'b1???00000100: insnsz <= 4'h2; |
12'b1???00000101: insnsz <= 4'h2; |
12'b1???00000110: insnsz <= 4'h2; |
12'b1???000?0101: insnsz <= 4'h2; |
12'b1???000?0110: insnsz <= 4'h2; |
12'b1???00001000: insnsz <= 4'h3; |
12'b1???00001001: insnsz <= 4'h4; |
12'b1???00001010: insnsz <= 4'h5; |
12'b1???00001011: insnsz <= 4'h2; |
12'b1???000?1011: insnsz <= 4'h2; |
12'b1???00001100: insnsz <= 4'h3; |
12'b1???00001101: insnsz <= 4'h4; |
12'b1???00001110: insnsz <= 4'h5; |
472,16 → 493,16
4'b0011: src1 <= usp; |
4'b0100: src1 <= ssp; |
4'b0101: src1 <= pcp2; |
4'b1000: src1 <= acca[`LOBYTE]; |
4'b1001: src1 <= accb[`LOBYTE]; |
4'b1010: src1 <= ccr; |
4'b1011: src1 <= dpr; |
4'b1000: src1 <= {12'hFFF,acca[`LOBYTE]}; |
4'b1001: src1 <= {12'hFFF,accb[`LOBYTE]}; |
4'b1010: src1 <= {ccr,ccr}; |
4'b1011: src1 <= {dpr,dpr}; |
4'b1100: src1 <= usppg; |
4'b1101: src1 <= 24'h0000; |
`ifdef SUPPORT_6309 |
4'b0110: src1 <= {acce[`LOBYTE],accf[`LOBYTE]}; |
4'b1110: src1 <= acce; |
4'b1111: src1 <= accf; |
4'b1110: src1 <= {12'hFFF,acce}; |
4'b1111: src1 <= {12'hFFF,accf}; |
`else |
4'b1110: src1 <= 24'h0000; |
4'b1111: src1 <= 24'h0000; |
532,6 → 553,12
ir12==`SUBA_EXT || ir12==`CMPA_EXT || ir12==`SBCA_EXT || ir12==`ANDA_EXT || ir12==`BITA_EXT || |
ir12==`LDA_EXT || ir12==`EORA_EXT || ir12==`ADCA_EXT || ir12==`ORA_EXT || ir12==`ADDA_EXT |
; |
wire isAdc = ir12==`ADCA_IMM || ir12==`ADCA_DP || ir12==`ADCA_NDX || ir12==`ADCA_EXT || |
ir12==`ADCB_IMM || ir12==`ADCB_DP || ir12==`ADCB_NDX || ir12==`ADCB_EXT || |
ir12==`ADCD_IMM || ir12==`ADCD_DP || ir12==`ADCD_NDX || ir12==`ADCD_EXT ; |
wire isSbc = ir12==`SBCA_IMM || ir12==`SBCA_DP || ir12==`SBCA_NDX || ir12==`SBCA_EXT || |
ir12==`SBCB_IMM || ir12==`SBCB_DP || ir12==`SBCB_NDX || ir12==`SBCB_EXT || |
ir12==`SBCD_IMM || ir12==`SBCD_DP || ir12==`SBCD_NDX || ir12==`SBCD_EXT ; |
|
`ifdef SUPPORT_6309 |
wire isAcce = ir12 == `ADDE_IMM || ir12==`ADDE_DP || ir12==`ADDE_NDX || ir12==`ADDE_EXT || ir12==`CLRE || ir12==`COME || |
576,7 → 603,7
|
assign lic_o = (state==CALC && !isRMW) || |
(state==DECODE && ( |
ir12==`NOP || ir12==`ORCC || ir12==`ANDCC || ir12==`DAA || ir12==`LDMD || ir12==`TFR || ir12==`EXG || |
ir12==`NOP || ir12==`ORCC || ir12==`ANDCC || ir12==`DAA || ir12==`LDMD || ir12==`BITMD || ir12==`TFR || ir12==`EXG || |
ir12==`NEGA || ir12==`COMA || ir12==`LSRA || ir12==`RORA || ir12==`ASRA || ir12==`ROLA || ir12==`DECA || ir12==`INCA || ir12==`TSTA || ir12==`CLRA || |
ir12==`DECE || ir12==`DECF || ir12==`DECD || ir12==`DECW || ir12==`INCE || ir12==`INCF || ir12==`INCD || ir12==`INCW || |
ir12==`NEGB || ir12==`COMB || ir12==`LSRB || ir12==`RORB || ir12==`ASRB || ir12==`ROLB || ir12==`DECB || ir12==`INCB || ir12==`TSTB || ir12==`CLRB || |
678,17 → 705,184
.hit1(hit1) |
); |
|
/* Need to account for signed division |
reg [35:0] divtbl [0:4095]; |
genvar g; |
wire bcdaddbcf, bcdsuubbcf,bcdaddcf,bcdsubcf,bcdnegcf,bcdnegbcf; |
wire [bitsPerByte-1:0] bcdaddbo, bcdsubbo, bcdnegbo; |
wire [bitsPerByte*2-1:0] bcdaddo, bcdsubo, bcdnego; |
wire [31:0] bcdmulo; |
|
`ifdef SUPPORT_BCD |
BCDAddN #(.N(3)) ubcda1 ( |
.ci(isAdc ? cf : 1'b0), |
.a(acc), |
.b(b12), |
.o(bcdaddbo), |
.co(bcdaddbcf) |
); |
|
BCDAddN #(.N(6)) ubcda2 ( |
.ci(isAdc ? cf : 1'b0), |
.a({acca,accb}), |
.b(b), |
.o(bcdaddo), |
.co(bcdaddcf) |
); |
|
BCDSubN #(.N(3)) ubcds1 ( |
.ci(isSbc ? cf : 1'b0), |
.a(acc), |
.b(b12), |
.o(bcdsubbo), |
.co(bcdsubbcf) |
); |
|
BCDSubN #(.N(6)) ubcds2 ( |
.ci(isSbc ? cf : 1'b0), |
.a({acca,accb}), |
.b(b), |
.o(bcdsubo), |
.co(bcdsubcf) |
); |
|
BCDSubN #(.N(3)) ubcds3 ( |
.ci(1'b0), |
.a(12'h0), |
.b(acc), |
.o(bcdnegbo), |
.co(bcdnegbcf) |
); |
|
BCDSubN #(.N(6)) ubcds4 ( |
.ci(1'b0), |
.a(12'h0), |
.b({acca,accb}), |
.o(bcdnego), |
.co(bcdnegcf) |
); |
|
BCDMul4 ubcdmul1 |
( |
.a({4'h0,acca}), |
.b({4'h0,accb}), |
.o(bcdmulo) |
); |
`endif |
|
reg [bitsPerByte*2-1:0] bcdmul_res [0:15]; |
reg [bitsPerByte*2-1:0] bcdmul_res16; |
genvar g5; |
generate begin : gBCDMulPipe |
always_ff @(posedge clk_i) |
bcdmul_res[0] <= bcdmulo[23:0]; |
always_ff @(posedge clk_i) |
bcdmul_res16 <= muld_res[15]; |
for (g5 = 1; g5 < 16; g5 = g5 + 1) |
always_ff @(posedge clk_i) |
bcdmul_res[g5] = bcdmul_res[g5-1]; |
end |
endgenerate |
|
// Multiplier logic |
wire signed [`QUADBYTE] muld_prod = $signed({acca,accb}) * $signed(b[`DBLBYTE]); |
reg [`QUADBYTE] muld_res [0:15]; |
reg [`QUADBYTE] muld_res6; |
genvar g4; |
generate begin : gMulPipe |
always_ff @(posedge clk_i) |
muld_res[0] <= muld_prod; |
always_ff @(posedge clk_i) |
muld_res6 <= muld_res[5]; |
for (g4 = 1; g4 < 6; g4 = g4 + 1) |
always_ff @(posedge clk_i) |
muld_res[g4] = muld_res[g4-1]; |
end |
endgenerate |
|
// Divider logic |
reg [5:0] divcnt; |
/* |
reg divsign; |
reg [`DBLBYTE] dividend; |
// Table of positive constants 1/0 to 1/2047, accurate to 35 bits |
reg [26:0] divtbl [0:2047]; |
genvar g2; |
generate begin: gDivtbl |
for (g = 0; g < 4096; g = g + 1) |
divtbl[g] = 36'h800000000 / g; |
for (g2 = 0; g2 < 2048; g2 = g2 + 1) |
initial begin |
divtbl[g2] = 27'h4000000 / g2; |
end |
end |
endgenerate |
wire [`DBLBYTE] divres = ({acca,accb} * divtbl[b12]) >> 36; |
wire [11:0] divrem = {acca,accb} - divres * b12; |
reg [49:0] divres; |
always_comb |
divres = ({36'd0,dividend} * divtbl[b12]); |
reg [11:0] divrem; |
always_comb |
divrem = dividend - divres[49:26] * b12; |
// Now create an 12-stage divider pipeline. Hopefully the synthesizer |
// will backfill along this pipeline. Each multiplier requires only |
// about 5 stages for best performance. |
genvar g1; |
reg [49:0] divrespipe [0:31]; |
reg [11:0] divrempipe [0:31]; |
reg [49:0] divres12; |
reg [11:0] divrem12; |
generate begin : gDivPipe |
always_ff @(posedge clk_i) |
divrespipe[0] <= divres; |
always_ff @(posedge clk_i) |
divrempipe[0] <= divrem; |
always_ff @(posedge clk_i) |
divres12 <= divrespipe[12]; |
always_ff @(posedge clk_i) |
divrem12 <= divrempipe[12]; |
for (g1 = 1; g1 < 13; g1 = g1 + 1) |
always_ff @(posedge clk_i) begin |
divrespipe[g1] <= divrespipe[g1-1]; |
divrempipe[g1] <= divrempipe[g1-1]; |
end |
end |
endgenerate |
*/ |
wire [23:0] divres24; |
wire [15:0] divrem12; |
wire [47:0] divres48; |
wire [23:0] divrem24; |
wire [15:0] divres16; |
wire [7:0] divrem8; |
wire [31:0] divres32; |
wire [15:0] divrem16; |
|
`ifdef SUPPORT_6309 |
`ifdef SUPPORT_DIVIDE |
generate begin : gDividers |
if (bitsPerByte==12) begin |
div24by12 udiv24by12 ( |
.aclk(clk_i), // input wire aclk |
.s_axis_divisor_tvalid(1'b1), // input wire s_axis_divisor_tvalid |
.s_axis_divisor_tdata({4'h0,b12}), // input wire [15 : 0] s_axis_divisor_tdata |
.s_axis_dividend_tvalid(1'b1), // input wire s_axis_dividend_tvalid |
.s_axis_dividend_tdata({acca,accb}), // input wire [23 : 0] s_axis_dividend_tdata |
.m_axis_dout_tvalid(), // output wire m_axis_dout_tvalid |
.m_axis_dout_tuser(), // output wire [0 : 0] m_axis_dout_tuser |
.m_axis_dout_tdata({divres24,divrem12}) // output wire [39 : 0] m_axis_dout_tdata |
); |
|
div48by24 udiv48by24 ( |
.aclk(clk_i), // input wire aclk |
.s_axis_divisor_tvalid(1'b1), // input wire s_axis_divisor_tvalid |
.s_axis_divisor_tdata(b), // input wire [23 : 0] s_axis_divisor_tdata |
.s_axis_dividend_tvalid(1'b1), // input wire s_axis_dividend_tvalid |
.s_axis_dividend_tdata({acca,accb,acce,accf}), // input wire [47 : 0] s_axis_dividend_tdata |
.m_axis_dout_tvalid(), // output wire m_axis_dout_tvalid |
.m_axis_dout_tuser(), // output wire [0 : 0] m_axis_dout_tuser |
.m_axis_dout_tdata({divres48,divrem24}) // output wire [71 : 0] m_axis_dout_tdata |
); |
end |
end |
endgenerate |
`endif |
`endif |
|
// For asynchronous reads, |
// The read response might come back in any order (the packets could loop |
// around in the network. |
717,11 → 911,11
`endif |
end |
|
genvar g; |
genvar g3; |
generate begin : gIcin |
for (g = 0; g < 16; g = g + 1) |
for (g3 = 0; g3 < 16; g3 = g3 + 1) |
always_comb |
icbuf2[(g+1)*bitsPerByte-1:g*bitsPerByte] <= icbuf[g]; |
icbuf2[(g3+1)*bitsPerByte-1:g3*bitsPerByte] <= icbuf[g3]; |
end |
endgenerate |
|
776,7 → 970,7
tsc_latched <= tsc_i; |
|
always_ff @(posedge clk_i) |
nmi1 <= nmi_i; |
nmi1 <= iplMd ? &{nmi_i,firq_i,irq_i} : nmi_i; |
always_ff @(posedge clk_i) |
`ifdef SUPPORT_CHECKPOINT |
if (ms_count[9:0]==10'h3FF && chkpoint!=12'h000) |
783,7 → 977,7
nmi_edge <= 1'b1; |
else |
`endif |
if (nmi_i & !nmi1) |
if ((iplMd ? &{nmi_i,firq_i,irq_i} : nmi_i) & !nmi1) |
nmi_edge <= 1'b1; |
else if (state==DECODE && ir12==`INT) |
nmi_edge <= 1'b0; |
793,6 → 987,9
always @(posedge clk_i) |
if (rst_i) begin |
wb_nack(); |
natMd <= 1'b0; |
firqMd <= 1'b0; |
iplMd <= 1'b0; |
rty <= `FALSE; |
rst_cnt <= {id,4'd0}; |
next_state(RESET); |
810,6 → 1007,7
pc <= {{BPB*3-1{1'b1}},1'b0}; // FF...FE |
ir <= {4{`NOP}}; |
ibuf <= {4{`NOP}}; |
dm <= 1'b0; |
im <= 1'b1; |
firqim <= 1'b1; |
nmi_armed <= `FALSE; |
818,6 → 1016,9
acca <= 12'h0; |
accb <= 12'h0; |
accd <= 24'h0; |
`ifdef SUPPORT_6309 |
accw <= 24'h0; |
`endif |
xr <= 24'h0; |
yr <= 24'h0; |
usppg <= 16'h0; |
833,6 → 1034,9
end |
outstanding <= 16'h0; |
iccnt <= 4'h0; |
//dividend <= 'b0; |
divcnt <= 'b0; |
//divsign <= 'b0; |
end |
else begin |
|
869,6 → 1073,45
|
// ============================================================================ |
// ============================================================================ |
MUL2: |
if (divcnt != 6'd0) |
divcnt <= divcnt - 2'd1; |
else |
next_state(IFETCH); |
DIV1: |
begin |
/* |
divsign <= acca[bitsPerByte-1] ^ b12[bitsPerByte-1]; |
if (acca[bitsPerByte-1]) |
dividend <= -{acca,accb}; |
else |
dividend <= {acca,accb}; |
if (b12[bitsPerByte-1]) |
b <= -b; |
*/ |
case(ir12) |
`DIVD_IMM,`DIVD_DP,`DIVD_NDX,`DIVD_EXT: |
divcnt <= 6'd28; |
`DIVQ_IMM,`DIVQ_DP,`DIVQ_NDX,`DIVQ_EXT: |
divcnt <= 6'd52; |
endcase |
next_state(DIV2); |
end |
DIV2: |
if (divcnt != 6'd0) |
divcnt <= divcnt - 2'd1; |
else |
next_state(DIV3); |
DIV3: |
begin |
res[`LOBYTE] <= divres24[11:0]; |
res[`HIBYTE] <= divrem12; |
vf <= divres24[23:12] != {12{divres24[11]}}; |
next_state(IFETCH); |
end |
|
// ============================================================================ |
// ============================================================================ |
PUSH1: |
begin |
next_state(PUSH2); |
931,6 → 1174,7
end |
else begin |
if (isINT) begin |
dm <= 1'b0; |
radr <= vect; |
if (vec_i != 24'h0) begin |
$display("vector: %h", vec_i); |
1063,12 → 1307,12
12'b1????0000010: radr <= radr + ndxreg; |
12'b1????0000011: radr <= radr + ndxreg; |
12'b1????0000100: radr <= radr + ndxreg; |
12'b1????0000101: radr <= radr + ndxreg; |
12'b1????0000110: radr <= radr + ndxreg; |
12'b1????00?0101: radr <= radr + ndxreg; |
12'b1????00?0110: radr <= radr + ndxreg; |
12'b1????0001000: radr <= radr + ndxreg; |
12'b1????0001001: radr <= radr + ndxreg; |
12'b1????0001010: radr <= radr + ndxreg; |
12'b1????0001011: radr <= radr + ndxreg; |
12'b1????00?1011: radr <= radr + ndxreg; |
default: radr <= radr; |
endcase |
end |
1326,6 → 1570,16
ipg <= 2'b11; |
vect <= `NMI_VECT; |
end |
else if ({nmi_i,firq_i,irq_i} > {im1,firqim,im} && !sync_state && iplMd) begin |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
case({nmi_i,firq_i,irq_i}) |
3'd1: vect <= `IRQ_VECT; |
3'd2: vect <= `FIRQ_VECT; |
default: vect <= `DBG_VECT | {nmi_i,firq_i,irq_i,1'b0}; |
endcase |
end |
else if (firq_i & !firqim & !sync_state) begin |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
1341,6 → 1595,37
ipg <= 2'b11; |
vect <= `IRQ_VECT; |
end |
`ifdef SUPPORT_DEBUG_REG |
// Check for instruction breakpoint hit. |
else if (brkctrl[0].en && brkctrl[0].match_type==BMT_IA && (pc & {{20{1'b1}},brkctrl[0].amask})==brkad[0]) begin |
brkctrl[0].hit <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `DBG_VECT; |
end |
else if (brkctrl[1].en && brkctrl[1].match_type==BMT_IA && (pc & {{20{1'b1}},brkctrl[1].amask})==brkad[1]) begin |
brkctrl[1].hit <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `DBG_VECT; |
end |
else if (brkctrl[2].en && brkctrl[2].match_type==BMT_IA && (pc & {{20{1'b1}},brkctrl[2].amask})==brkad[2]) begin |
brkctrl[2].hit <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `DBG_VECT; |
end |
else if (brkctrl[3].en && brkctrl[3].match_type==BMT_IA && (pc & {{20{1'b1}},brkctrl[3].amask})==brkad[3]) begin |
brkctrl[3].hit <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `DBG_VECT; |
end |
`endif |
else begin |
if (sync_state) begin |
ba_o <= 1'b1; |
1475,6 → 1760,7
hf <= hf | ir[bitsPerByte+5]; |
firqim <= firqim | ir[bitsPerByte+6]; |
ef <= ef | ir[bitsPerByte+7]; |
dm <= dm | ir[bitsPerByte+8]; |
pc <= pcp2; |
end |
`ANDCC: |
1487,6 → 1773,7
hf <= hf & ir[bitsPerByte+5]; |
firqim <= firqim & ir[bitsPerByte+6]; |
ef <= ef & ir[bitsPerByte+7]; |
dm <= dm & ir[bitsPerByte+8]; |
pc <= pcp2; |
end |
`DAA: |
1505,6 → 1792,7
im <= im & ir[bitsPerByte+4]; |
hf <= hf & ir[bitsPerByte+5]; |
firqim <= firqim & ir[bitsPerByte+6]; |
dm <= dm & ir[bitsPerByte+8]; |
ef <= 1'b1; |
pc <= pc + 2'd2; |
ir[`HIBYTE] <= -1; |
1515,8 → 1803,18
`LDMD: begin |
natMd <= ir[bitsPerByte]; |
firqMd <= ir[bitsPerByte+1]; |
iplMd <= ir[bitsPerByte+2]; |
pc <= pc + 2'd2; |
end |
`BITMD: |
begin |
res <= {dbz,iop,3'd0,iplMd,firqMd,natMd} & ir[`BYTE2]; |
if (ir[bitsPerByte+7]) |
dbz <= 1'b0; |
if (ir[bitsPerByte+6]) |
iop <= 1'b0; |
pc <= pc + 2'd2; |
end |
`TFR: pc <= pc + 2'd2; |
`EXG: pc <= pc + 2'd2; |
`ABX: res <= xr + accb; |
1527,7 → 1825,12
`ifdef EIGHTBIT |
`OUTER: begin isOuterIndexed <= `TRUE; ir <= ir[bitsPerByte*5-1:bitsPerByte]; next_state(DECODE); end |
`endif |
`NEGA,`NEGB: begin res12 <= -acc[`LOBYTE]; a <= 24'h00; b <= acc; end |
`NEGA,`NEGB: |
if (dm) begin |
a <= 'b0; b <= acc; |
next_state(CALC); |
end |
else begin res12 <= -acc[`LOBYTE]; a <= 24'h00; b <= acc; end |
`COMA,`COMB: begin res12 <= ~acc[`LOBYTE]; end |
`LSRA,`LSRB: begin res12 <= {acc[0],1'b0,acc[BPBM1:1]}; end |
`RORA,`RORB: begin res12 <= {acc[0],cf,acc[BPBM1:1]}; end |
1538,12 → 1841,18
`INCA,`INCB: begin res12 <= acc[`LOBYTE] + 2'd1; end |
`TSTA,`TSTB: begin res12 <= acc[`LOBYTE]; end |
`CLRA,`CLRB: begin res12 <= 13'h000; end |
`MUL: if (dm) begin divcnt <= 6'd17; next_state(MUL2); end |
`ifdef SUPPORT_6309 |
`TSTD: res <= {acca,accb}; |
`TSTW: res <= {acce,accf}; |
`TSTE: res12 <= acce; |
`TSTF: res12 <= accf; |
`NEGD: begin res <= -{acca,accb}; a <= 'd0; b <= {acca,accb}; end |
`NEGD: |
if (dm) begin |
a <= 'd0; b <= {acca,accb}; |
next_state(CALC); |
end |
else begin res <= -{acca,accb}; a <= 'd0; b <= {acca,accb}; end |
`INCE,`INCF: begin res12 <= acc[`LOBYTE] + 2'd1; end |
`INCD: res <= {acca,accb} + 2'd1; |
`INCW: res <= {acce,accf} + 2'd1; |
1594,6 → 1903,7
hf <= sum12[5]; |
firqim <= sum12[6]; |
ef <= sum12[7]; |
dm <= sum12[8]; |
end |
4'b1011: begin dpr <= sum12; nf <= sum12[bitsPerByte-1]; zf <= sum12[`LOBYTE]=='b0; cf <= sum12[bitsPerByte]; vf <= fnAddOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],sum12[bitsPerByte-1]); end |
endcase |
1619,6 → 1929,7
hf <= sum12c[5]; |
firqim <= sum12c[6]; |
ef <= sum12c[7]; |
dm <= sum12c[8]; |
end |
4'b1011: begin dpr <= sum12c; nf <= sum12c[bitsPerByte-1]; zf <= sum12c[`LOBYTE]=='b0; cf <= sum12c[bitsPerByte]; vf <= fnAddOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],sum12c[bitsPerByte-1]); end |
endcase |
1644,6 → 1955,7
hf <= and12[5]; |
firqim <= and12[6]; |
ef <= and12[7]; |
dm <= and12[8]; |
end |
4'b1011: begin dpr <= and12; nf <= and12[bitsPerByte-1]; zf <= and12[`LOBYTE]=='b0; vf <= 1'b0; end |
endcase |
1669,6 → 1981,7
hf <= eor12[5]; |
firqim <= eor12[6]; |
ef <= eor12[7]; |
dm <= eor12[8]; |
end |
4'b1011: begin dpr <= eor12; nf <= eor12[bitsPerByte-1]; zf <= eor12[`LOBYTE]=='b0; vf <= 1'b0; end |
endcase |
1694,6 → 2007,7
hf <= or12[5]; |
firqim <= or12[6]; |
ef <= or12[7]; |
dm <= or12[8]; |
end |
4'b1011: begin dpr <= or12; nf <= or12[bitsPerByte-1]; zf <= or12[`LOBYTE]=='b0; vf <= 1'b0; end |
endcase |
1734,6 → 2048,7
hf <= dif12c[5]; |
firqim <= dif12c[6]; |
ef <= dif12c[7]; |
dm <= dif12c[8]; |
end |
4'b1011: begin dpr <= dif12c; nf <= dif12c[bitsPerByte-1]; zf <= dif12c[`LOBYTE]=='b0; cf <= dif12c[bitsPerByte]; vf <= fnSubOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],dif12c[bitsPerByte-1]); end |
endcase |
1759,6 → 2074,7
hf <= dif12[5]; |
firqim <= dif12[6]; |
ef <= dif12[7]; |
dm <= dif12[8]; |
end |
4'b1011: begin dpr <= dif12; nf <= dif12[bitsPerByte-1]; zf <= dif12[`LOBYTE]=='b0; cf <= dif12[bitsPerByte]; vf <= fnSubOverflow(src1[bitsPerByte-1],src2[bitsPerByte-1],dif12[bitsPerByte-1]); end |
endcase |
1772,9 → 2088,11
`endif |
// Immediate mode instructions |
`SUBA_IMM,`SUBB_IMM,`CMPA_IMM,`CMPB_IMM: |
begin res12 <= acc[`LOBYTE] - ir[`HIBYTE]; pc <= pc + 4'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end |
if (dm) begin pc <= pc + 4'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; next_state(CALC); end |
else begin res12 <= acc[`LOBYTE] - ir[`HIBYTE]; pc <= pc + 4'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end |
`SBCA_IMM,`SBCB_IMM: |
begin res12 <= acc[`LOBYTE] - ir[`HIBYTE] - cf; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end |
if (dm) begin pc <= pc + 4'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; next_state(CALC); end |
else begin res12 <= acc[`LOBYTE] - ir[`HIBYTE] - cf; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end |
`ANDA_IMM,`ANDB_IMM,`BITA_IMM,`BITB_IMM: |
begin res12 <= acc[`LOBYTE] & ir[`HIBYTE]; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end |
`LDA_IMM,`LDB_IMM: |
1782,11 → 2100,13
`EORA_IMM,`EORB_IMM: |
begin res12 <= acc[`LOBYTE] ^ ir[`HIBYTE]; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end |
`ADCA_IMM,`ADCB_IMM: |
begin res12 <= acc[`LOBYTE] + ir[`HIBYTE] + cf; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end |
if (dm) begin pc <= pc + 4'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; next_state(CALC); end |
else begin res12 <= acc[`LOBYTE] + ir[`HIBYTE] + cf; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end |
`ORA_IMM,`ORB_IMM: |
begin res12 <= acc[`LOBYTE] | ir[`HIBYTE]; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end |
`ADDA_IMM,`ADDB_IMM: |
begin res12 <= acc[`LOBYTE] + ir[`HIBYTE]; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end |
if (dm) begin pc <= pc + 4'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; next_state(CALC); end |
else begin res12 <= acc[`LOBYTE] + ir[`HIBYTE]; pc <= pc + 2'd2; a <= acc[`LOBYTE]; b <= ir[`HIBYTE]; end |
`ifdef SUPPORT_6309 |
`BITD_IMM, |
`ANDD_IMM: |
1806,7 → 2126,13
end |
`endif |
`ADDD_IMM: |
begin |
if (dm) begin |
a <= {acca,accb}; |
b <= {ir[`BYTE2],ir[`BYTE3]}; |
pc <= pc + 2'd3; |
next_state(CALC); |
end |
else begin |
res <= {acca[`LOBYTE],accb[`LOBYTE]} + {ir[`HIBYTE],ir[`BYTE3]}; |
pc <= pc + 2'd3; |
end |
1817,16 → 2143,28
pc <= pc + 2'd3; |
end |
`ADCD_IMM: |
begin |
if (dm) begin |
a <= {acca,accb}; |
b <= {ir[`BYTE2],ir[`BYTE3]}; |
pc <= pc + 32'd3; |
next_state(CALC); |
end |
else begin |
res <= {acca[`LOBYTE],accb[`LOBYTE]} + {ir[`BYTE2],ir[`BYTE3]} + {23'b0,cf}; |
pc <= pc + 32'd3; |
end |
`endif |
`SUBD_IMM: |
begin |
res <= {acca[`LOBYTE],accb[`LOBYTE]} - {ir[`HIBYTE],ir[`BYTE3]}; |
pc <= pc + 2'd3; |
end |
if (dm) begin |
a <= {acca,accb}; |
b <= {ir[`BYTE2],ir[`BYTE3]}; |
pc <= pc + 32'd3; |
next_state(CALC); |
end |
else begin |
res <= {acca[`LOBYTE],accb[`LOBYTE]} - {ir[`HIBYTE],ir[`BYTE3]}; |
pc <= pc + 2'd3; |
end |
`ifdef SUPPORT_6309 |
`SUBW_IMM: |
begin |
1834,7 → 2172,13
pc <= pc + 2'd3; |
end |
`SBCD_IMM: |
begin |
if (dm) begin |
a <= {acca,accb}; |
b <= {ir[`BYTE2],ir[`BYTE3]}; |
pc <= pc + 32'd3; |
next_state(CALC); |
end |
else begin |
res <= {acca[`LOBYTE],accb[`LOBYTE]} - {ir[`BYTE2],ir[`BYTE3]} - {23'b0,cf}; |
pc <= pc + 32'd3; |
end |
1856,12 → 2200,18
end |
|
`CMPD_IMM: |
begin |
res <= {acca[`LOBYTE],accb[`LOBYTE]} - {ir[`HIBYTE],ir[`BYTE3]}; |
pc <= pc + 2'd3; |
a <= {acca[`LOBYTE],accb[`LOBYTE]}; |
b <= {ir[`HIBYTE],ir[`BYTE3]}; |
end |
if (dm) begin |
a <= {acca,accb}; |
b <= {ir[`BYTE2],ir[`BYTE3]}; |
pc <= pc + 32'd3; |
next_state(CALC); |
end |
else begin |
res <= {acca[`LOBYTE],accb[`LOBYTE]} - {ir[`HIBYTE],ir[`BYTE3]}; |
pc <= pc + 2'd3; |
a <= {acca[`LOBYTE],accb[`LOBYTE]}; |
b <= {ir[`HIBYTE],ir[`BYTE3]}; |
end |
`ifdef SUPPORT_6309 |
`CMPW_IMM: |
begin |
1909,6 → 2259,27
next_state(LOAD1); |
end |
`ifdef SUPPORT_6309 |
`DIVD_IMM: |
begin |
b <= {ir[`BYTE3],ir[`BYTE2]}; |
pc <= pc + 2'd2; |
next_state(DIV1); |
end |
`DIVQ_IMM: |
begin |
b <= {ir[`BYTE3],ir[`BYTE2]}; |
pc <= pc + 2'd3; |
next_state(DIV1); |
end |
`MULD_IMM: |
begin |
b <= {ir[`BYTE3],ir[`BYTE2]}; |
pc <= pc + 2'd3; |
divcnt <= 6'd7; |
next_state(MUL2); |
end |
`endif |
`ifdef SUPPORT_6309 |
`CMPE_DP,`CMPF_DP, |
`LDE_DP,`LDF_DP, |
`SUBE_DP,`SUBF_DP, |
1925,6 → 2296,8
`BITD_DP, |
`ANDD_DP, |
`ORD_DP, |
`DIVD_DP, |
`DIVQ_DP, |
`EORD_DP: |
begin |
load_what <= `LW_BL; |
1934,6 → 2307,7
end |
`endif |
`ifdef SUPPORT_6309 |
`MULD_DP, |
`ADDW_DP,`CMPW_DP,`LDW_DP,`SUBW_DP, |
`endif |
`SUBD_DP,`ADDD_DP,`LDD_DP,`CMPD_DP,`ADCD_DP,`SBCD_DP: |
2011,6 → 2385,8
`BITD_NDX, |
`ANDD_NDX, |
`ORD_NDX, |
`DIVD_NDX, |
`DIVQ_NDX, |
`EORD_NDX: |
begin |
pc <= pc + insnsz; |
2027,6 → 2403,22
next_state(LOAD1); |
end |
end |
`MULD_NDX: |
begin |
pc <= pc + insnsz; |
if (isIndirect) begin |
load_what <= isFar ? `LW_IA2316 : `LW_IAH; |
load_what2 <= `LW_BH; |
radr <= NdxAddr; |
next_state(LOAD1); |
end |
else begin |
b <= 24'd0; |
load_what <= `LW_BH; |
radr <= NdxAddr; |
next_state(LOAD1); |
end |
end |
`endif |
`ifdef SUPPORT_6309 |
`ADDW_NDX,`CMPW_NDX,`LDW_NDX,`SUBW_NDX, |
2130,6 → 2522,8
`BITD_EXT, |
`ANDD_EXT, |
`ORD_EXT, |
`DIVD_EXT, |
`DIVQ_EXT, |
`EORD_EXT: |
begin |
load_what <= `LW_BL; |
2139,6 → 2533,7
end |
`endif |
`ifdef SUPPORT_6309 |
`MULD_EXT, |
`ADDW_EXT,`CMPW_EXT,`LDW_EXT,`SUBW_EXT, |
`endif |
`SUBD_EXT,`ADDD_EXT,`LDD_EXT,`CMPD_EXT,`ADCD_EXT,`SBCD_EXT: |
2336,28 → 2731,28
if (wait_state) begin |
wait_state <= `FALSE; |
if (vec_i != 24'h0) begin |
pc <= vec_i; |
next_state(IFETCH); |
pc <= vec_i; |
next_state(IFETCH); |
end |
else begin |
radr <= vect; |
load_what <= `LW_PCH; |
pc <= 32'hFFFFFFFE; |
next_state(LOAD1); |
radr <= vect; |
load_what <= `LW_PCH; |
pc <= 32'hFFFFFFFE; |
next_state(LOAD1); |
end |
end |
else begin |
if (isNMI | isIRQ | isSWI | isSWI2 | isSWI3) begin |
ir[`HIBYTE] <= 16'hFFFF; |
ir[`HIBYTE] <= natMd ? 12'hFFF : 12'h0FF; |
ef <= 1'b1; |
end |
else if (isFIRQ) begin |
if (natMd) begin |
ef <= firqMd; |
ir[`HIBYTE] <= firqMd ? 16'hFFFF : 12'h81; |
ir[`HIBYTE] <= firqMd ? 12'hFFF : 12'h081; |
end |
else begin |
ir[`HIBYTE] <= 12'h81; |
ir[`HIBYTE] <= 12'h081; |
ef <= 1'b0; |
end |
end |
2366,7 → 2761,15
next_state(PUSH1); |
end |
end |
default: ; |
default: |
if (natMd) begin |
iop <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `IOP_VECT; |
next_state(DECODE); |
end |
endcase |
end |
endtask |
2380,13 → 2783,62
if (unCachedData) |
`endif |
case(radr) |
{{BPB*3-8{1'b1}},8'hE0}: load_tsk({2'b0,id}); |
{{BPB*3-8{1'b1}},8'hE1}: load_tsk(chkpoint); |
{{BPB*3-8{1'b1}},8'hE4}: load_tsk(12'h0); |
{{BPB*3-8{1'b1}},8'hE5}: load_tsk(ms_count[35:24]); |
{{BPB*3-8{1'b1}},8'hE6}: load_tsk(ms_count[23:12]); |
{{BPB*3-8{1'b1}},8'hE7}: load_tsk(ms_count[11: 0]); |
`CORENO: load_tsk({2'b0,id}); |
`CHKPOINT: load_tsk(chkpoint); |
`MSCOUNT+0: load_tsk(12'h0); |
`MSCOUNT+1: load_tsk(ms_count[35:24]); |
`MSCOUNT+2: load_tsk(ms_count[23:12]); |
`MSCOUNT+3: load_tsk(ms_count[11: 0]); |
`ifdef SUPPORT_DEBUG_REG |
`BRKAD0+0: load_tsk(brkad[0][`BYTE2]); |
`BRKAD0+1: load_tsk(brkad[0][`BYTE1]); |
`BRKAD1+0: load_tsk(brkad[1][`BYTE2]); |
`BRKAD1+1: load_tsk(brkad[1][`BYTE1]); |
`BRKAD2+0: load_tsk(brkad[2][`BYTE2]); |
`BRKAD2+1: load_tsk(brkad[2][`BYTE1]); |
`BRKAD3+0: load_tsk(brkad[3][`BYTE2]); |
`BRKAD3+1: load_tsk(brkad[3][`BYTE1]); |
`BRKCTRL0: load_tsk(brkctrl[0]); |
`BRKCTRL1: load_tsk(brkctrl[1]); |
`BRKCTRL2: load_tsk(brkctrl[2]); |
`BRKCTRL3: load_tsk(brkctrl[3]); |
`endif |
default: |
`ifdef SUPPORT_DEBUG_REG |
if (brkctrl[0].en && brkctrl[0].match_type==BMT_LS && (radr & {{20{1'b1}},brkctrl[0].amask})==brkad[0]) begin |
brkctrl[0].hit <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `DBG_VECT; |
next_state(DECODE); |
end |
else if (brkctrl[1].en && brkctrl[1].match_type==BMT_LS && (radr & {{20{1'b1}},brkctrl[1].amask})==brkad[1]) begin |
brkctrl[1].hit <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `DBG_VECT; |
next_state(DECODE); |
end |
else if (brkctrl[2].en && brkctrl[2].match_type==BMT_LS && (radr & {{20{1'b1}},brkctrl[2].amask})==brkad[2]) begin |
brkctrl[2].hit <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `DBG_VECT; |
next_state(DECODE); |
end |
else if (brkctrl[3].en && brkctrl[3].match_type==BMT_LS && (radr & {{20{1'b1}},brkctrl[3].amask})==brkad[3]) begin |
brkctrl[3].hit <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `DBG_VECT; |
next_state(DECODE); |
end |
else |
`endif |
if (~ack_i) begin |
lock_o <= lock_bus; |
wb_read(radr); |
2437,19 → 2889,26
begin |
next_state(IFETCH); |
case(ir12) |
`SUBD_IMM, |
`SUBD_DP,`SUBD_NDX,`SUBD_EXT, |
`CMPD_DP,`CMPD_NDX,`CMPD_EXT: |
begin |
if (dm) |
res <= bcdsubo; |
else begin |
a <= {acca[`LOBYTE],accb[`LOBYTE]}; |
res <= {acca[`LOBYTE],accb[`LOBYTE]} - b[`DBLBYTE]; |
end |
`SBCD_DP,`SBCD_NDX,`SBCD_EXT: |
begin |
`SBCD_IMM,`SBCD_DP,`SBCD_NDX,`SBCD_EXT: |
if (dm) |
res <= bcdsubo; |
else begin |
a <= {acca[`LOBYTE],accb[`LOBYTE]}; |
res <= {acca[`LOBYTE],accb[`LOBYTE]} - b[`DBLBYTE] - {23'b0,cf}; |
end |
`ADDD_DP,`ADDD_NDX,`ADDD_EXT: |
begin |
`ADDD_IMM,`ADDD_DP,`ADDD_NDX,`ADDD_EXT: |
if (dm) |
res <= bcdaddo; |
else begin |
a <= {acca[`LOBYTE],accb[`LOBYTE]}; |
res <= {acca[`LOBYTE],accb[`LOBYTE]} + b[`DBLBYTE]; |
end |
2468,8 → 2927,10
`LDW_DP,`LDW_NDX,`LDW_EXT: |
res <= b[`DBLBYTE]; |
`endif |
`ADCD_DP,`ADCD_NDX,`ADCD_EXT: |
begin |
`ADCD_IMM,`ADCD_DP,`ADCD_NDX,`ADCD_EXT: |
if (dm) |
res <= bcdaddo; |
else begin |
a <= {acca[`LOBYTE],accb[`LOBYTE]}; |
res <= {acca[`LOBYTE],accb[`LOBYTE]} + b[`DBLBYTE] + {23'b0,cf}; |
end |
2479,23 → 2940,31
`CMPE_DP,`CMPE_NDX,`CMPE_EXT, |
`CMPF_DP,`CMPF_NDX,`CMPF_EXT, |
`SUBE_DP,`SUBE_NDX,`SUBE_EXT, |
`SUBF_DP,`SUBF_NDX,`SUBF_EXT, |
`endif |
`CMPA_DP,`CMPA_NDX,`CMPA_EXT, |
`SUBA_DP,`SUBA_NDX,`SUBA_EXT, |
`CMPB_DP,`CMPB_NDX,`CMPB_EXT, |
`SUBB_DP,`SUBB_NDX,`SUBB_EXT: |
`SUBF_DP,`SUBF_NDX,`SUBF_EXT: |
begin |
a <= acc; |
res12 <= acc[`LOBYTE] - b12; |
end |
`endif |
`CMPA_IMM,`CMPA_DP,`CMPA_NDX,`CMPA_EXT, |
`SUBA_IMM,`SUBA_DP,`SUBA_NDX,`SUBA_EXT, |
`CMPB_IMM,`CMPB_DP,`CMPB_NDX,`CMPB_EXT, |
`SUBB_IMM,`SUBB_DP,`SUBB_NDX,`SUBB_EXT: |
if (dm) |
res12 <= bcdsubbo; |
else begin |
a <= acc; |
res12 <= acc[`LOBYTE] - b12; |
end |
|
`SBCA_DP,`SBCA_NDX,`SBCA_EXT, |
`SBCB_DP,`SBCB_NDX,`SBCB_EXT: |
begin |
a <= acc; |
res12 <= acc[`LOBYTE] - b12 - cf; |
end |
`SBCA_IMM,`SBCA_DP,`SBCA_NDX,`SBCA_EXT, |
`SBCB_IMM,`SBCB_DP,`SBCB_NDX,`SBCB_EXT: |
if (dm) |
res12 <= bcdsubbo; |
else begin |
a <= acc; |
res12 <= acc[`LOBYTE] - b12 - cf; |
end |
`BITA_DP,`BITA_NDX,`BITA_EXT, |
`ANDA_DP,`ANDA_NDX,`ANDA_EXT, |
`BITB_DP,`BITB_NDX,`BITB_EXT, |
2505,6 → 2974,23
`BITD_DP,`BITD_NDX,`BITD_EXT, |
`ANDD_DP,`ANDD_NDX,`ANDD_EXT: |
res <= {acca[`LOBYTE],accb[`LOBYTE]} & b[`DBLBYTE]; |
`DIVQ_DP,`DIVQ_NDX,`DIVQ_EXT, |
`DIVD_DP,`DIVD_NDX,`DIVD_EXT: |
if (b==24'd0) begin |
dbz <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `IOP_VECT; |
next_state(DECODE); |
end |
else |
next_state(DIV1); |
`MULD_DP,`MULD_NDX,`MULD_EXT: |
begin |
divcnt <= 6'd7; |
next_state(MUL2); |
end |
`EORD_DP,`EORD_NDX,`EORD_EXT: |
res <= {acca[`LOBYTE],accb[`LOBYTE]} ^ b[`DBLBYTE]; |
`ORD_DP,`ORD_NDX,`ORD_EXT: |
2519,12 → 3005,14
`EORA_DP,`EORA_NDX,`EORA_EXT, |
`EORB_DP,`EORB_NDX,`EORB_EXT: |
res12 <= acc[`LOBYTE] ^ b12; |
`ADCA_DP,`ADCA_NDX,`ADCA_EXT, |
`ADCB_DP,`ADCB_NDX,`ADCB_EXT: |
begin |
a <= acc; |
res12 <= acc[`LOBYTE] + b12 + cf; |
end |
`ADCA_IMM,`ADCA_DP,`ADCA_NDX,`ADCA_EXT, |
`ADCB_IMM,`ADCB_DP,`ADCB_NDX,`ADCB_EXT: |
if (dm) |
res12 <= bcdaddbo; |
else begin |
a <= acc; |
res12 <= acc[`LOBYTE] + b12 + cf; |
end |
`ORA_DP,`ORA_NDX,`ORA_EXT, |
`ORB_DP,`ORB_NDX,`ORB_EXT: |
res12 <= acc[`LOBYTE] | b12; |
2532,12 → 3020,14
`ADDE_DP,`ADDE_NDX,`ADDE_EXT, |
`ADDF_DP,`ADDF_NDX,`ADDF_EXT, |
`endif |
`ADDA_DP,`ADDA_NDX,`ADDA_EXT, |
`ADDB_DP,`ADDB_NDX,`ADDB_EXT: |
begin |
a <= acc; |
res12 <= acc[`LOBYTE] + b12; |
end |
`ADDA_IMM,`ADDA_DP,`ADDA_NDX,`ADDA_EXT, |
`ADDB_IMM,`ADDB_DP,`ADDB_NDX,`ADDB_EXT: |
if (dm) |
res12 <= bcdaddbo; |
else begin |
a <= acc; |
res12 <= acc[`LOBYTE] + b12; |
end |
|
`LDU_DP,`LDS_DP,`LDX_DP,`LDY_DP, |
`LDU_NDX,`LDS_NDX,`LDX_NDX,`LDY_NDX, |
2548,6 → 3038,7
`CMPU_DP,`CMPU_NDX,`CMPU_EXT: begin a <= usp; res <= usp[`DBLBYTE] - b[`DBLBYTE]; end |
|
`NEG_DP,`NEG_NDX,`NEG_EXT: begin res12 <= -b12; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end |
`NEGA,`NEGB: begin res12 <= bcdnegbo; end |
`COM_DP,`COM_NDX,`COM_EXT: begin res12 <= ~b12; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end |
`LSR_DP,`LSR_NDX,`LSR_EXT: begin res12 <= {b[0],1'b0,b[BPBM1:1]}; store_what <= `SW_RES8; wadr <= radr; next_state(STORE1); end |
`ROR_DP,`ROR_NDX,`ROR_EXT: begin res12 <= {b[0],cf,b[BPBM1:1]}; store_what <= `SW_RES8; wadr <= radr; next_state(STORE1); end |
2558,6 → 3049,7
`INC_DP,`INC_NDX,`INC_EXT: begin res12 <= b12 + 2'd1; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end |
`TST_DP,`TST_NDX,`TST_EXT: res12 <= b12; |
`ifdef SUPPORT_6309 |
`NEGD: begin res <= bcdnego; end |
`AIM_DP,`AIM_NDX,`AIM_EXT: begin res12 <= ir[`HIBYTE] & b12; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end |
`OIM_DP,`OIM_NDX,`OIM_EXT: begin res12 <= ir[`HIBYTE] | b12; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end |
`EIM_DP,`EIM_NDX,`OIM_EXT: begin res12 <= ir[`HIBYTE] ^ b12; wadr <= radr; store_what <= `SW_RES8; next_state(STORE1); end |
2577,10 → 3069,45
if (!ack_i) begin |
lock_o <= lock_bus; |
`ifdef SUPPORT_CHECKPOINT |
if (wadr=={{BPB*3-8{1'b1}},8'hE1}) |
if (wadr==CHKPOINT) |
next_state(IFETCH); |
else |
`endif |
`ifdef SUPPORT_DEBUG_REG |
if (brkctrl[0].en && brkctrl[0].match_type==BMT_DS && (radr & {{20{1'b1}},brkctrl[0].amask})==brkad[0]) begin |
brkctrl[0].hit <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `DBG_VECT; |
next_state(DECODE); |
end |
else if (brkctrl[1].en && brkctrl[1].match_type==BMT_DS && (radr & {{20{1'b1}},brkctrl[1].amask})==brkad[1]) begin |
brkctrl[1].hit <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `DBG_VECT; |
next_state(DECODE); |
end |
else if (brkctrl[2].en && brkctrl[2].match_type==BMT_DS && (radr & {{20{1'b1}},brkctrl[2].amask})==brkad[2]) begin |
brkctrl[2].hit <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `DBG_VECT; |
next_state(DECODE); |
end |
else if (brkctrl[3].en && brkctrl[3].match_type==BMT_DS && (radr & {{20{1'b1}},brkctrl[3].amask})==brkad[3]) begin |
brkctrl[3].hit <= 1'b1; |
bs_o <= 1'b1; |
ir[`LOBYTE] <= `INT; |
ipg <= 2'b11; |
vect <= `DBG_VECT; |
next_state(DECODE); |
end |
else |
`endif |
begin |
case(store_what) |
`SW_ACCDH: wb_write(wadr,acca[`LOBYTE]); |
2800,7 → 3327,7
`ADDA_IMM,`ADDA_DP,`ADDA_NDX,`ADDA_EXT, |
`ADCA_IMM,`ADCA_DP,`ADCA_NDX,`ADCA_EXT: |
begin |
cf <= (a[BPBM1]&b[BPBM1])|(a[BPBM1]&~res12[BPBM1])|(b[BPBM1]&~res12[BPBM1]); |
cf <= dm ? bcdaddbcf : (a[BPBM1]&b[BPBM1])|(a[BPBM1]&~res12[BPBM1])|(b[BPBM1]&~res12[BPBM1]); |
hf <= (a[`HCBIT]&b[`HCBIT])|(a[`HCBIT]&~res12[`HCBIT])|(b[`HCBIT]&~res12[`HCBIT]); |
vf <= (res12[BPBM1] ^ b[BPBM1]) & (1'b1 ^ a[BPBM1] ^ b[BPBM1]); |
nf <= res12[BPBM1]; |
2810,7 → 3337,7
`ADDB_IMM,`ADDB_DP,`ADDB_NDX,`ADDB_EXT, |
`ADCB_IMM,`ADCB_DP,`ADCB_NDX,`ADCB_EXT: |
begin |
cf <= (a[BPBM1]&b[BPBM1])|(a[BPBM1]&~res12[BPBM1])|(b[BPBM1]&~res12[BPBM1]); |
cf <= dm ? bcdaddbcf : (a[BPBM1]&b[BPBM1])|(a[BPBM1]&~res12[BPBM1])|(b[BPBM1]&~res12[BPBM1]); |
hf <= (a[`HCBIT]&b[`HCBIT])|(a[`HCBIT]&~res12[`HCBIT])|(b[`HCBIT]&~res12[`HCBIT]); |
vf <= (res12[BPBM1] ^ b[BPBM1]) & (1'b1 ^ a[BPBM1] ^ b[BPBM1]); |
nf <= res12[BPBM1]; |
2839,7 → 3366,7
`endif |
`ADDD_IMM,`ADDD_DP,`ADDD_NDX,`ADDD_EXT: |
begin |
cf <= (a[BPBX2M1]&b[BPBX2M1])|(a[BPBX2M1]&~res[BPBX2M1])|(b[BPBX2M1]&~res[BPBX2M1]); |
cf <= dm ? bcdaddcf : (a[BPBX2M1]&b[BPBX2M1])|(a[BPBX2M1]&~res[BPBX2M1])|(b[BPBX2M1]&~res[BPBX2M1]); |
vf <= (res[BPBX2M1] ^ b[BPBX2M1]) & (1'b1 ^ a[BPBX2M1] ^ b[BPBX2M1]); |
nf <= res[BPBX2M1]; |
zf <= res[`DBLBYTE]==24'h000000; |
2858,7 → 3385,7
end |
`ADCD_IMM,`ADCD_DP,`ADCD_NDX,`ADCD_EXT: |
begin |
cf <= (a[BPBX2M1]&b[BPBX2M1])|(a[BPBX2M1]&~res[BPBX2M1])|(b[BPBX2M1]&~res[BPBX2M1]); |
cf <= dm ? bcdaddcf : (a[BPBX2M1]&b[BPBX2M1])|(a[BPBX2M1]&~res[BPBX2M1])|(b[BPBX2M1]&~res[BPBX2M1]); |
vf <= (res[BPBX2M1] ^ b[BPBX2M1]) & (1'b1 ^ a[BPBX2M1] ^ b[BPBX2M1]); |
nf <= res[BPBX2M1]; |
zf <= res[`DBLBYTE]==24'h0000; |
2906,6 → 3433,49
zf <= res24z; |
vf <= 1'b0; |
end |
`DIVD_IMM,`DIVD_DP,`DIVD_NDX,`DIVD_EXT: |
begin |
acca <= res[`BYTE2]; |
accb <= res[`BYTE1]; |
// Overflow set eariler |
cf <= res[0]; |
nf <= res[bitsPerByte-1]; |
zf <= ~|res[bitsPerByte-1:0]; |
end |
`DIVQ_IMM,`DIVQ_DP,`DIVQ_NDX,`DIVQ_EXT: |
begin |
if (bitsPerByte==12) begin |
acce <= divrem24[`BYTE2]; |
accf <= divrem24[`BYTE1]; |
acca <= divres48[`BYTE2]; |
accb <= divres48[`BYTE1]; |
// Overflow set eariler |
cf <= divres48[0]; |
vf <= divres48[47:24]!={24{divres48[23]}}; |
nf <= divres48[23]; |
zf <= ~|divres48[23:0]; |
end |
else if (bitsPerByte==8) begin |
acce <= divrem16[`BYTE2]; |
accf <= divrem16[`BYTE1]; |
acca <= divres32[`BYTE2]; |
accb <= divres32[`BYTE1]; |
// Overflow set eariler |
cf <= divres32[0]; |
vf <= divres32[31:16]!={16{divres32[15]}}; |
nf <= divres48[15]; |
zf <= ~|divres48[15:0]; |
end |
end |
`MULD_IMM,`MULD_DP,`MULD_NDX,`MULD_EXT: |
begin |
accb <= muld_res6[`BYTE1]; |
acca <= muld_res6[`BYTE2]; |
accf <= muld_res6[`BYTE3]; |
acce <= muld_res6[`BYTE4]; |
zf <= ~|muld_res6; |
nf <= muld_res6[bitsPerByte*4-1]; |
end |
`endif |
`ASLA: |
begin |
3027,6 → 3597,8
accb <= 12'h000; |
end |
`ifdef SUPPORT_6309 |
`BITMD: |
zf <= res12==12'h0; |
`CLRD: |
begin |
vf <= 1'b0; |
3071,12 → 3643,19
end |
`ifdef SUPPORT_6309 |
`CMPE_IMM,`CMPE_DP,`CMPE_NDX,`CMPE_EXT, |
`CMPF_IMM,`CMPF_DP,`CMPF_NDX,`CMPF_EXT, |
`CMPF_IMM,`CMPF_DP,`CMPF_NDX,`CMPF_EXT: |
begin |
cf <= (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]); |
hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]); |
vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]); |
nf <= res12[BPBM1]; |
zf <= res12[`LOBYTE]==12'h000; |
end |
`endif |
`CMPA_IMM,`CMPA_DP,`CMPA_NDX,`CMPA_EXT, |
`CMPB_IMM,`CMPB_DP,`CMPB_NDX,`CMPB_EXT: |
begin |
cf <= (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]); |
cf <= dm ? bcdsubbcf : (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]); |
hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]); |
vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]); |
nf <= res12[BPBM1]; |
3083,11 → 3662,17
zf <= res12[`LOBYTE]==12'h000; |
end |
`ifdef SUPPORT_6309 |
`CMPW_IMM,`CMPW_DP,`CMPW_NDX,`CMPW_EXT, |
`CMPW_IMM,`CMPW_DP,`CMPW_NDX,`CMPW_EXT: |
begin |
cf <= (~a[BPBX2M1]&b[BPBX2M1])|(res[BPBX2M1]&~a[BPBX2M1])|(res[BPBX2M1]&b[BPBX2M1]); |
vf <= (1'b1 ^ res[BPBX2M1] ^ b[BPBX2M1]) & (a[BPBX2M1] ^ b[BPBX2M1]); |
nf <= res[BPBX2M1]; |
zf <= res[`DBLBYTE]==24'h000000; |
end |
`endif |
`CMPD_IMM,`CMPD_DP,`CMPD_NDX,`CMPD_EXT: |
begin |
cf <= (~a[BPBX2M1]&b[BPBX2M1])|(res[BPBX2M1]&~a[BPBX2M1])|(res[BPBX2M1]&b[BPBX2M1]); |
cf <= dm ? bcdsubcf : (~a[BPBX2M1]&b[BPBX2M1])|(res[BPBX2M1]&~a[BPBX2M1])|(res[BPBX2M1]&b[BPBX2M1]); |
vf <= (1'b1 ^ res[BPBX2M1] ^ b[BPBX2M1]) & (a[BPBX2M1] ^ b[BPBX2M1]); |
nf <= res[BPBX2M1]; |
zf <= res[`DBLBYTE]==24'h000000; |
3258,6 → 3843,7
hf <= src1[5]; |
firqim <= src1[6]; |
ef <= src1[7]; |
dm <= src1[8]; |
end |
4'b1011: dpr <= src1[`LOBYTE]; |
4'b1100: usppg <= src1[`DBLBYTE]; |
3294,6 → 3880,7
hf <= src2[5]; |
firqim <= src2[6]; |
ef <= src2[7]; |
dm <= src2[8]; |
end |
4'b1011: dpr <= src2[`LOBYTE]; |
4'b1100: usppg <= src2[`DBLBYTE]; |
3467,7 → 4054,13
zf <= res12[`LOBYTE]==12'h000; |
end |
`MUL: |
begin |
if (dm) begin |
accb <= bcdmul_res16[`BYTE1]; |
acca <= bcdmul_res16[`BYTE2]; |
zf <= ~|bcdmul_res16; |
cf <= bcdmul_res16[bitsPerByte*2-1]; |
end |
else begin |
cf <= prod[BPBM1]; |
zf <= res24z; |
acca <= prod[`HIBYTE]; |
3475,7 → 4068,7
end |
`NEGA: |
begin |
cf <= (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]); |
cf <= dm ? bcdnegbcf : (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]); |
hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]); |
vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]); |
nf <= res12[BPBM1]; |
3484,7 → 4077,7
end |
`NEGB: |
begin |
cf <= (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]); |
cf <= dm ? bcdnegbcf : (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]); |
hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]); |
vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]); |
nf <= res12[BPBM1]; |
3494,7 → 4087,7
`ifdef SUPPORT_6309 |
`NEGD: |
begin |
cf <= (~a[bitsPerByte*2-1]&b[bitsPerByte*2-1])|(res[bitsPerByte*2-1]&~a[bitsPerByte*2-1])|(res[bitsPerByte*2-1]&b[bitsPerByte*2-1]); |
cf <= dm ? bcdnegcf : (~a[bitsPerByte*2-1]&b[bitsPerByte*2-1])|(res[bitsPerByte*2-1]&~a[bitsPerByte*2-1])|(res[bitsPerByte*2-1]&b[bitsPerByte*2-1]); |
hf <= (~a[`HCBIT]&b[`HCBIT])|(res[`HCBIT]&~a[`HCBIT])|(res[`HCBIT]&b[`HCBIT]); |
vf <= (1'b1 ^ res[bitsPerByte*2-1] ^ b[bitsPerByte*2-1]) & (a[bitsPerByte*2-1] ^ b[bitsPerByte*2-1]); |
nf <= res[bitsPerByte*2-1]; |
3558,7 → 4151,7
end |
`SBCA_IMM,`SBCA_DP,`SBCA_NDX,`SBCA_EXT: |
begin |
cf <= (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]); |
cf <= dm ? bcdsubbcf : (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]); |
hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]); |
vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]); |
nf <= res12[BPBM1]; |
3567,7 → 4160,7
end |
`SBCB_IMM,`SBCB_DP,`SBCB_NDX,`SBCB_EXT: |
begin |
cf <= (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]); |
cf <= dm ? bcdsubbcf : (~a[BPBM1]&b[BPBM1])|(res12[BPBM1]&~a[BPBM1])|(res12[BPBM1]&b[BPBM1]); |
hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]); |
vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]); |
nf <= res12[BPBM1]; |
3629,6 → 4222,7
hf <= src1[5]; |
firqim <= src1[6]; |
ef <= src1[7]; |
dm <= src1[8]; |
end |
4'b1011: dpr <= src1[`LOBYTE]; |
4'b1100: usppg <= src1[`DBLBYTE]; |
3676,7 → 4270,7
nf <= res12n; |
zf <= res12z; |
vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]); |
cf <= res12c; |
cf <= dm ? bcdsubbcf : res12c; |
hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]); |
end |
`SUBB_IMM,`SUBB_DP,`SUBB_NDX,`SUBB_EXT: |
3685,7 → 4279,7
nf <= res12n; |
zf <= res12z; |
vf <= (1'b1 ^ res12[BPBM1] ^ b[BPBM1]) & (a[BPBM1] ^ b[BPBM1]); |
cf <= res12c; |
cf <= dm ? bcdsubbcf : res12c; |
hf <= (~a[`HCBIT]&b[`HCBIT])|(res12[`HCBIT]&~a[`HCBIT])|(res12[`HCBIT]&b[`HCBIT]); |
end |
`ifdef SUPPORT_6309 |
3720,7 → 4314,7
`endif |
`SUBD_IMM,`SUBD_DP,`SUBD_NDX,`SUBD_EXT: |
begin |
cf <= res24c; |
cf <= dm ? bcdsubcf : res24c; |
vf <= (1'b1 ^ res[BPBX2M1] ^ b[BPBX2M1]) & (a[BPBX2M1] ^ b[BPBX2M1]); |
nf <= res[BPBX2M1]; |
zf <= res[`DBLBYTE]==24'h000000; |
3804,15 → 4398,39
end |
endtask |
|
// Trap writes to special registers |
task wb_write; |
input [`TRPBYTE] adr; |
input [`LOBYTE] dat; |
begin |
if (!tsc) begin |
we_o <= 1'b1; |
adr_o <= adr; |
dat_o <= dat; |
end |
if (!tsc) begin |
next_state(IFETCH); |
`ifdef SUPPORT_DEBUG_REG |
case(adr) |
`BRKAD0+0: brkad[0][`BYTE2] <= dat; |
`BRKAD0+1: brkad[0][`BYTE1] <= dat; |
`BRKAD1+0: brkad[1][`BYTE2] <= dat; |
`BRKAD1+1: brkad[1][`BYTE1] <= dat; |
`BRKAD2+0: brkad[2][`BYTE2] <= dat; |
`BRKAD2+1: brkad[2][`BYTE1] <= dat; |
`BRKAD3+0: brkad[3][`BYTE2] <= dat; |
`BRKAD3+1: brkad[3][`BYTE1] <= dat; |
`BRKCTRL0: brkctrl[0] <= dat; |
`BRKCTRL1: brkctrl[1] <= dat; |
`BRKCTRL2: brkctrl[2] <= dat; |
`BRKCTRL3: brkctrl[3] <= dat; |
default: |
begin |
`endif |
we_o <= 1'b1; |
adr_o <= adr; |
dat_o <= dat; |
next_state(STORE1a); |
`ifdef SUPPORT_DEBUG_REG |
end |
endcase |
`endif |
end |
end |
endtask |
|
3857,9 → 4475,10
hf <= dat[5]; |
firqim <= dat[6]; |
ef <= dat[7]; |
dm <= dat[8]; |
if (isRTI) begin |
$display("loaded ccr=%b", dat); |
ir[`HIBYTE] <= dat[7] ? 12'hFE : 12'h80; |
ir[`HIBYTE] <= dat[7] ? 12'h3FE : 12'h080; |
ssp <= ssp + 2'd1; |
end |
else if (isPULS) |
/cpu/rf6809_pkg.sv
4,6 → 4,23
typedef logic [23:0] Address; |
typedef logic [11:0] Data; |
|
// Breakpoint Control Register |
// One for each breakpoint address register |
typedef struct packed |
{ |
logic hit; |
logic [2:0] pad; |
logic en; |
logic trace_en; |
logic [1:0] match_type; |
logic [3:0] amask; |
} brkCtrl; |
|
// Breakpoint match types |
parameter BMT_IA = 2'd0; |
parameter BMT_DS = 2'd1; |
parameter BMT_LS = 2'd3; |
|
parameter bitsPerByte = $bits(Data); |
parameter BPB = bitsPerByte; |
parameter BPBM1 = BPB-1; |
10,8 → 27,14
parameter BPBX2M1 = BPB*2-1; |
|
// The following adds support for many 6309 instructions. |
//`define SUPPORT_6309 |
`define SUPPORT_6309 1 |
// Support BCD arithmetic mode and the decimal mode flag |
`define SUPPORT_BCD 1 |
// Support divide operations |
`define SUPPORT_DIVIDE 1 |
|
`define SUPPORT_DEBUG_REG 1 |
|
// The following allows asynchronous reads for icache updating. |
// It increases the size of the core. |
//`define SUPPORT_AREAD 1 |
31,6 → 54,7
`define HIBYTE 15:8 |
`define DBLBYTE 15:0 |
`define TRPBYTE 23:0 |
`define QUADBYTE 31:0 |
`define BYTE1 7:0 |
`define BYTE2 15:8 |
`define BYTE3 23:16 |
48,6 → 72,7
`define HIBYTE 23:12 |
`define DBLBYTE 23:0 |
`define TRPBYTE 35:0 |
`define QUADBYTE 47:0 |
`define BYTE1 11:0 |
`define BYTE2 23:12 |
`define BYTE3 35:24 |
70,8 → 95,30
`define FIRQ_VECT 24'hFFFFF6 |
`define SWI2_VECT 24'hFFFFF4 |
`define SWI3_VECT 24'hFFFFF2 |
`define RESV_VECT 24'hFFFFF0 |
`define IOP_VECT 24'hFFFFF0 |
`define IPL7_VECT 24'hFFFFEE |
`define IPL6_VECT 24'hFFFFEC |
`define IPL5_VECT 24'hFFFFEA |
`define IPL4_VECT 24'hFFFFE8 |
`define IPL3_VECT 24'hFFFFE6 |
`define IPL2_VECT 24'hFFFFE4 |
`define IPL1_VECT 24'hFFFFE2 |
`define DBG_VECT 24'hFFFFE0 |
|
`define MSCOUNT 24'hFFFF14 |
`define CHKPOINT 24'hFFFF11 |
`define CORENO 24'hFFFF10 |
|
`define BRKCTRL3 24'hFFFF0B |
`define BRKCTRL2 24'hFFFF0A |
`define BRKCTRL1 24'hFFFF09 |
`define BRKCTRL0 24'hFFFF08 |
`define BRKAD3 24'hFFFF06 |
`define BRKAD2 24'hFFFF04 |
`define BRKAD1 24'hFFFF02 |
`define BRKAD0 24'hFFFF00 |
|
|
`define NEG_DP 12'h000 |
`define OIM_DP 12'h001 |
`define AIM_DP 12'h002 |
448,6 → 495,7
`define STQ_EXT 12'h1FD |
`define LDS_EXT 12'h1FE |
`define STS_EXT 12'h1FF |
`define BITMD 12'h23C |
`define LDMD 12'h23D |
`define SWI3 12'h23F |
`define COME 12'h243 |
465,18 → 513,26
`define LDE_IMM 12'h286 |
`define ADDE_IMM 12'h28B |
`define DIVD_IMM 12'h28D |
`define DIVQ_IMM 12'h28E |
`define MULD_IMM 12'h28F |
`define SUBE_DP 12'h290 |
`define LDE_DP 12'h296 |
`define ADDE_DP 12'h29B |
`define DIVD_DP 12'h29D |
`define DIVQ_DP 12'h29E |
`define MULD_DP 12'h29F |
`define SUBE_NDX 12'h2A0 |
`define LDE_NDX 12'h2A6 |
`define ADDE_NDX 12'h2AB |
`define DIVD_NDX 12'h2AD |
`define DIVQ_NDX 12'h2AE |
`define MULD_NDX 12'h2AF |
`define SUBE_EXT 12'h2B0 |
`define LDE_EXT 12'h2B6 |
`define ADDE_EXT 12'h2BB |
`define DIVD_EXT 12'h2BD |
`define DIVQ_EXT 12'h2BE |
`define MULD_EXT 12'h2BF |
`define SUBF_IMM 12'h2C0 |
`define LDF_IMM 12'h2C6 |
`define ADDF_IMM 12'h2CB |
/lib/BCDMath.sv
0,0 → 1,554
`timescale 1ns / 1ps |
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2012-2021 Robert Finch, Waterloo |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@finitron.ca |
// || |
// |
// BCDMath.sv |
// |
// BSD 3-Clause License |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are met: |
// |
// 1. Redistributions of source code must retain the above copyright notice, this |
// list of conditions and the following disclaimer. |
// |
// 2. Redistributions in binary form must reproduce the above copyright notice, |
// this list of conditions and the following disclaimer in the documentation |
// and/or other materials provided with the distribution. |
// |
// 3. Neither the name of the copyright holder nor the names of its |
// contributors may be used to endorse or promote products derived from |
// this software without specific prior written permission. |
// |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
// |
// ============================================================================ |
// |
// Could use the following approach for add/sub but it ends up being larger |
// than using an adjustment lookup table. |
|
module BCDAddNyb(ci,a,b,o,c); |
input ci; // carry input |
input [3:0] a; |
input [3:0] b; |
output [3:0] o; |
output c; |
|
wire c0; |
|
reg [4:0] hsN0; |
always_comb |
begin |
hsN0 = a[3:0] + b[3:0] + ci; |
if (hsN0 > 5'd9) |
hsN0 = hsN0 + 3'd6; |
end |
assign o = hsN0[3:0]; |
assign c = hsN0[4]; |
|
endmodule |
|
module BCDAdd(ci,a,b,o,c); |
input ci; // carry input |
input [7:0] a; |
input [7:0] b; |
output [7:0] o; |
output c; |
|
wire c0,c1; |
reg [4:0] hsN0, hsN1; |
always_comb |
hsN0 <= a[3:0] + b[3:0] + ci; |
always_comb |
hsN1 <= a[7:4] + b[7:4] + c0; |
|
BCDAddAdjust u1 (hsN0,o[3:0],c0); |
BCDAddAdjust u2 (hsN1,o[7:4],c); |
|
endmodule |
|
module BCDAdd4(ci,a,b,o,c,c8); |
input ci; // carry input |
input [15:0] a; |
input [15:0] b; |
output [15:0] o; |
output c; |
output c8; |
|
wire c0,c1,c2; |
assign c8 = c1; |
|
reg [4:0] hsN0, hsN1, hsN2, hsN3; |
always_comb |
hsN0 <= a[3:0] + b[3:0] + ci; |
always_comb |
hsN1 <= a[7:4] + b[7:4] + c0; |
always_comb |
hsN2 <= a[11:8] + b[11:8] + c1; |
always_comb |
hsN3 <= a[15:12] + b[15:12] + c2; |
|
BCDAddAdjust u1 (hsN0,o[3:0],c0); |
BCDAddAdjust u2 (hsN1,o[7:4],c1); |
BCDAddAdjust u3 (hsN2,o[11:8],c2); |
BCDAddAdjust u4 (hsN3,o[15:12],c); |
|
endmodule |
|
module BCDAddN(ci,a,b,o,co); |
parameter N=24; |
input ci; // carry input |
input [N*4-1:0] a; |
input [N*4-1:0] b; |
output [N*4-1:0] o; |
output co; |
|
genvar g; |
generate begin : gBCDAddN |
reg [4:0] hsN [0:N-1]; |
wire [N:0] c; |
|
assign c[0] = ci; |
assign co = c[N]; |
|
for (g = 0; g < N; g = g + 1) |
always_comb |
hsN[g] = a[g*4+3:g*4] + b[g*4+3:g*4] + c[g]; |
|
for (g = 0; g < N; g = g + 1) |
BCDAddAdjust u1 (hsN[g],o[g*4+3:g*4],c[g+1]); |
end |
endgenerate |
|
endmodule |
|
module BCDSub(ci,a,b,o,c); |
input ci; // carry input |
input [7:0] a; |
input [7:0] b; |
output [7:0] o; |
output c; |
|
wire c0,c1; |
|
reg [4:0] hdN0, hdN1; |
always_comb |
hdN0 <= a[3:0] - b[3:0] - ci; |
always_comb |
hdN1 <= a[7:4] - b[7:4] - c0; |
|
BCDSubAdjust u1 (hdN0,o[3:0],c0); |
BCDSubAdjust u2 (hdN1,o[7:4],c); |
|
endmodule |
|
module BCDSub4(ci,a,b,o,c,c8); |
input ci; // carry input |
input [15:0] a; |
input [15:0] b; |
output [15:0] o; |
output c; |
output c8; |
|
wire c0,c1,c2; |
assign c8 = c1; |
|
reg [4:0] hdN0, hdN1, hdN2, hdN3; |
always_comb |
hdN0 <= a[3:0] - b[3:0] - ci; |
always_comb |
hdN1 <= a[7:4] - b[7:4] - c0; |
always_comb |
hdN2 <= a[11:8] - b[11:8] - c1; |
always_comb |
hdN3 <= a[15:12] - b[15:12] - c2; |
|
BCDSubAdjust u1 (hdN0,o[3:0],c0); |
BCDSubAdjust u2 (hdN1,o[7:4],c1); |
BCDSubAdjust u3 (hdN2,o[11:8],c2); |
BCDSubAdjust u4 (hdN3,o[15:12],c); |
|
endmodule |
|
module BCDSubN(ci,a,b,o,co); |
parameter N=24; |
input ci; // carry input |
input [N*4-1:0] a; |
input [N*4-1:0] b; |
output [N*4-1:0] o; |
output co; |
|
genvar g; |
generate begin : gBCDSubN |
reg [4:0] hdN [0:N-1]; |
wire [N:0] c; |
|
assign c[0] = ci; |
assign co = c[N]; |
|
for (g = 0; g < N; g = g + 1) |
always_comb |
hdN[g] = a[g*4+3:g*4] - b[g*4+3:g*4] - c[g]; |
|
for (g = 0; g < N; g = g + 1) |
BCDSubAdjust u1 (hdN[g],o[g*4+3:g*4],c[g+1]); |
end |
endgenerate |
|
endmodule |
|
module BCDAddAdjust(i,o,c); |
input [4:0] i; |
output [3:0] o; |
reg [3:0] o; |
output c; |
reg c; |
always_comb |
case(i) |
5'h0: begin o = 4'h0; c = 1'b0; end |
5'h1: begin o = 4'h1; c = 1'b0; end |
5'h2: begin o = 4'h2; c = 1'b0; end |
5'h3: begin o = 4'h3; c = 1'b0; end |
5'h4: begin o = 4'h4; c = 1'b0; end |
5'h5: begin o = 4'h5; c = 1'b0; end |
5'h6: begin o = 4'h6; c = 1'b0; end |
5'h7: begin o = 4'h7; c = 1'b0; end |
5'h8: begin o = 4'h8; c = 1'b0; end |
5'h9: begin o = 4'h9; c = 1'b0; end |
5'hA: begin o = 4'h0; c = 1'b1; end |
5'hB: begin o = 4'h1; c = 1'b1; end |
5'hC: begin o = 4'h2; c = 1'b1; end |
5'hD: begin o = 4'h3; c = 1'b1; end |
5'hE: begin o = 4'h4; c = 1'b1; end |
5'hF: begin o = 4'h5; c = 1'b1; end |
5'h10: begin o = 4'h6; c = 1'b1; end |
5'h11: begin o = 4'h7; c = 1'b1; end |
5'h12: begin o = 4'h8; c = 1'b1; end |
5'h13: begin o = 4'h9; c = 1'b1; end |
default: begin o = 4'h9; c = 1'b1; end |
endcase |
endmodule |
|
module BCDSubAdjust(i,o,c); |
input [4:0] i; |
output [3:0] o; |
reg [3:0] o; |
output c; |
reg c; |
always_comb |
case(i) |
5'h0: begin o = 4'h0; c = 1'b0; end |
5'h1: begin o = 4'h1; c = 1'b0; end |
5'h2: begin o = 4'h2; c = 1'b0; end |
5'h3: begin o = 4'h3; c = 1'b0; end |
5'h4: begin o = 4'h4; c = 1'b0; end |
5'h5: begin o = 4'h5; c = 1'b0; end |
5'h6: begin o = 4'h6; c = 1'b0; end |
5'h7: begin o = 4'h7; c = 1'b0; end |
5'h8: begin o = 4'h8; c = 1'b0; end |
5'h9: begin o = 4'h9; c = 1'b0; end |
5'h16: begin o = 4'h0; c = 1'b1; end |
5'h17: begin o = 4'h1; c = 1'b1; end |
5'h18: begin o = 4'h2; c = 1'b1; end |
5'h19: begin o = 4'h3; c = 1'b1; end |
5'h1A: begin o = 4'h4; c = 1'b1; end |
5'h1B: begin o = 4'h5; c = 1'b1; end |
5'h1C: begin o = 4'h6; c = 1'b1; end |
5'h1D: begin o = 4'h7; c = 1'b1; end |
5'h1E: begin o = 4'h8; c = 1'b1; end |
5'h1F: begin o = 4'h9; c = 1'b1; end |
default: begin o = 4'h9; c = 1'b1; end |
endcase |
endmodule |
|
// Multiply two BCD digits |
// Method used is table lookup |
module BCDMul1(a,b,o); |
input [3:0] a; |
input [3:0] b; |
output [7:0] o; |
reg [7:0] o; |
|
always_comb |
case({a,b}) |
8'h00: o = 8'h00; |
8'h01: o = 8'h00; |
8'h02: o = 8'h00; |
8'h03: o = 8'h00; |
8'h04: o = 8'h00; |
8'h05: o = 8'h00; |
8'h06: o = 8'h00; |
8'h07: o = 8'h00; |
8'h08: o = 8'h00; |
8'h09: o = 8'h00; |
8'h10: o = 8'h00; |
8'h11: o = 8'h01; |
8'h12: o = 8'h02; |
8'h13: o = 8'h03; |
8'h14: o = 8'h04; |
8'h15: o = 8'h05; |
8'h16: o = 8'h06; |
8'h17: o = 8'h07; |
8'h18: o = 8'h08; |
8'h19: o = 8'h09; |
8'h20: o = 8'h00; |
8'h21: o = 8'h02; |
8'h22: o = 8'h04; |
8'h23: o = 8'h06; |
8'h24: o = 8'h08; |
8'h25: o = 8'h10; |
8'h26: o = 8'h12; |
8'h27: o = 8'h14; |
8'h28: o = 8'h16; |
8'h29: o = 8'h18; |
8'h30: o = 8'h00; |
8'h31: o = 8'h03; |
8'h32: o = 8'h06; |
8'h33: o = 8'h09; |
8'h34: o = 8'h12; |
8'h35: o = 8'h15; |
8'h36: o = 8'h18; |
8'h37: o = 8'h21; |
8'h38: o = 8'h24; |
8'h39: o = 8'h27; |
8'h40: o = 8'h00; |
8'h41: o = 8'h04; |
8'h42: o = 8'h08; |
8'h43: o = 8'h12; |
8'h44: o = 8'h16; |
8'h45: o = 8'h20; |
8'h46: o = 8'h24; |
8'h47: o = 8'h28; |
8'h48: o = 8'h32; |
8'h49: o = 8'h36; |
8'h50: o = 8'h00; |
8'h51: o = 8'h05; |
8'h52: o = 8'h10; |
8'h53: o = 8'h15; |
8'h54: o = 8'h20; |
8'h55: o = 8'h25; |
8'h56: o = 8'h30; |
8'h57: o = 8'h35; |
8'h58: o = 8'h40; |
8'h59: o = 8'h45; |
8'h60: o = 8'h00; |
8'h61: o = 8'h06; |
8'h62: o = 8'h12; |
8'h63: o = 8'h18; |
8'h64: o = 8'h24; |
8'h65: o = 8'h30; |
8'h66: o = 8'h36; |
8'h67: o = 8'h42; |
8'h68: o = 8'h48; |
8'h69: o = 8'h54; |
8'h70: o = 8'h00; |
8'h71: o = 8'h07; |
8'h72: o = 8'h14; |
8'h73: o = 8'h21; |
8'h74: o = 8'h28; |
8'h75: o = 8'h35; |
8'h76: o = 8'h42; |
8'h77: o = 8'h49; |
8'h78: o = 8'h56; |
8'h79: o = 8'h63; |
8'h80: o = 8'h00; |
8'h81: o = 8'h08; |
8'h82: o = 8'h16; |
8'h83: o = 8'h24; |
8'h84: o = 8'h32; |
8'h85: o = 8'h40; |
8'h86: o = 8'h48; |
8'h87: o = 8'h56; |
8'h88: o = 8'h64; |
8'h89: o = 8'h72; |
8'h90: o = 8'h00; |
8'h91: o = 8'h09; |
8'h92: o = 8'h18; |
8'h93: o = 8'h27; |
8'h94: o = 8'h36; |
8'h95: o = 8'h45; |
8'h96: o = 8'h54; |
8'h97: o = 8'h63; |
8'h98: o = 8'h72; |
8'h99: o = 8'h81; |
default: o = 8'h00; |
endcase |
endmodule |
|
|
// Multiply two pairs of BCD digits |
// handles from 0x0 to 99x99 |
module BCDMul2(a,b,o); |
input [7:0] a; |
input [7:0] b; |
output [15:0] o; |
|
wire [7:0] p1,p2,p3,p4; |
wire [15:0] s1; |
|
BCDMul1 u1 (a[3:0],b[3:0],p1); |
BCDMul1 u2 (a[7:4],b[3:0],p2); |
BCDMul1 u3 (a[3:0],b[7:4],p3); |
BCDMul1 u4 (a[7:4],b[7:4],p4); |
|
BCDAdd4 u5 (1'b0,{p4,p1},{4'h0,p2,4'h0},s1); |
BCDAdd4 u6 (1'b0,s1,{4'h0,p3,4'h0},o); |
|
endmodule |
|
module BCDMul4(a,b,o); |
input [15:0] a; |
input [15:0] b; |
output [31:0] o; |
|
wire [15:0] p1,p2,p3,p4; |
wire [31:0] s1; |
|
BCDMul2 u1 (a[7:0],b[7:0],p1); |
BCDMul2 u2 (a[15:8],b[7:0],p2); |
BCDMul2 u3 (a[7:0],b[15:8],p3); |
BCDMul2 u4 (a[15:8],b[15:8],p4); |
|
BCDAddN #(.N(8)) u5 (1'b0,{p4,p1},{8'h0,p2,8'h0},s1); |
BCDAddN #(.N(8)) u6 (1'b0,s1,{8'h0,p3,8'h0},o); |
|
endmodule |
|
module BCDMul8(a,b,o); |
input [31:0] a; |
input [31:0] b; |
output [63:0] o; |
|
wire [31:0] p1,p2,p3,p4; |
wire [63:0] s1; |
|
BCDMul4 u1 (a[15:0],b[15:0],p1); |
BCDMul4 u2 (a[31:16],b[15:0],p2); |
BCDMul4 u3 (a[15:0],b[31:16],p3); |
BCDMul4 u4 (a[31:16],b[31:16],p4); |
|
BCDAddN #(.N(16)) u5 (1'b0,{p4,p1},{16'h0,p2,16'h0},s1); |
BCDAddN #(.N(16)) u6 (1'b0,s1,{16'h0,p3,16'h0},o); |
|
endmodule |
|
module BCDMul16(a,b,o); |
input [63:0] a; |
input [63:0] b; |
output [127:0] o; |
|
wire [63:0] p1,p2,p3,p4; |
wire [127:0] s1; |
|
BCDMul8 u1 (a[31:0],b[31:0],p1); |
BCDMul8 u2 (a[63:32],b[31:0],p2); |
BCDMul8 u3 (a[31:0],b[63:32],p3); |
BCDMul8 u4 (a[63:32],b[63:32],p4); |
|
BCDAddN #(.N(32)) u5 (1'b0,{p4,p1},{32'h0,p2,32'h0},s1); |
BCDAddN #(.N(32)) u6 (1'b0,s1,{32'h0,p3,32'h0},o); |
|
endmodule |
|
module BCDMul32(a,b,o); |
input [127:0] a; |
input [127:0] b; |
output [255:0] o; |
|
wire [127:0] p1,p2,p3,p4; |
wire [255:0] s1; |
|
BCDMul16 u1 (a[63:0],b[63:0],p1); |
BCDMul16 u2 (a[127:64],b[63:0],p2); |
BCDMul16 u3 (a[63:0],b[127:64],p3); |
BCDMul16 u4 (a[127:64],b[127:64],p4); |
|
BCDAddN #(.N(64)) u5 (1'b0,{p4,p1},{64'h0,p2,64'h0},s1); |
BCDAddN #(.N(64)) u6 (1'b0,s1,{64'h0,p3,64'h0},o); |
|
endmodule |
|
module BCDMul_tb(); |
|
wire [15:0] o1,o2,o3,o4; |
|
BCDMul2 u1 (8'h00,8'h00,o1); |
BCDMul2 u2 (8'h99,8'h99,o2); |
BCDMul2 u3 (8'h25,8'h18,o3); |
BCDMul2 u4 (8'h37,8'h21,o4); |
|
endmodule |
|
module BinToBCD(i, o); |
input [7:0] i; |
output [11:0] o; |
|
reg [11:0] tbl [0:255]; |
|
genvar g; |
generate begin : gTbl |
reg [3:0] n0 [0:255]; |
reg [3:0] n1 [0:255]; |
reg [3:0] n2 [0:255]; |
|
for (g = 0; g < 256; g = g + 1) begin |
initial begin |
n0[g] = g % 10; |
n1[g] = g / 10; |
n2[g] = g / 100; |
tbl[g] <= {n2[g],n1[g],n0[g]}; |
end |
end |
|
assign o = tbl[i]; |
|
end |
endgenerate |
|
endmodule |
|
// Perform a logical shift to the right. |
module BCDSRLN(ci, i, o, co); |
parameter N=4; |
input ci; |
input [N*4-1:0] i; |
output reg [N*4-1:0] o; |
output co; |
|
reg [N:0] c; |
|
genvar g; |
generate begin :gSRL |
always @* |
c[N] = ci; |
for (g = N - 1; g >= 0; g = g - 1) |
always @* |
c[g] = i[g*4]; |
for (g = N - 1; g >= 0; g = g - 1) |
always @* |
begin |
// Because there is a divide by two, the value will range between 0 and 4. |
// Adding 5 keeps it within deicmal boundaries of 0 to 9. No carry can be |
// generated |
if (c[g+1]) |
o[g*4+3:g*4] = {1'b0,i[g*4+3:g*4+1]} + 4'd5; |
else |
o[g*4+3:g*4] = {1'b0,i[g*4+3:g*4+1]}; |
end |
assign co = c[0]; |
end |
endgenerate |
|
endmodule |