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

Subversion Repositories rf6809

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /rf6809
    from Rev 21 to Rev 22
    Reverse comparison

Rev 21 → Rev 22

/trunk/doc/rf6809_guide.docx Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/trunk/rtl/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)
/trunk/rtl/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
/trunk/rtl/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
/trunk/software/a09/a09.c
379,19 → 379,19
{ "ADCD", OPCAT_6309 |
OPCAT_DBLREG1BYTE, 0x189, 0 },
{ "ADCR", OPCAT_6309 |
OPCAT_IREG, 0x1031, 0 },
OPCAT_IREG, 0x131, 0 },
{ "ADD", OPCAT_ACCARITH, 0x8b, 0 },
{ "ADDA", OPCAT_ARITH, 0x8b, 0 },
{ "ADDB", OPCAT_ARITH, 0xcb, 0 },
{ "ADDD", OPCAT_DBLREG1BYTE, 0xc3, 0 },
{ "ADDE", OPCAT_6309 |
OPCAT_2ARITH, 0x118b, 0 },
OPCAT_ARITH, 0x28b, 0 },
{ "ADDF", OPCAT_6309 |
OPCAT_2ARITH, 0x11cb, 0 },
OPCAT_ARITH, 0x2cb, 0 },
{ "ADDR", OPCAT_6309 |
OPCAT_IREG, 0x1030, 0 },
OPCAT_IREG, 0x130, 0 },
{ "ADDW", OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x108b, 0 },
OPCAT_DBLREG2BYTE, 0x18b, 0 },
{ "AIM", OPCAT_6309 |
OPCAT_BITDIRECT, 0x02, 0 },
{ "AND", OPCAT_ACCARITH, 0x84, 0 },
401,26 → 401,26
{ "ANDD", OPCAT_6309 |
OPCAT_DBLREG1BYTE, 0x184, 0 },
{ "ANDR", OPCAT_6309 |
OPCAT_IREG, 0x1034, 0 },
OPCAT_IREG, 0x134, 0 },
{ "ASL", OPCAT_SINGLEADDR, 0x08, 0 },
{ "ASLA", OPCAT_ONEBYTE, 0x48, 0 },
{ "ASLB", OPCAT_ONEBYTE, 0x58, 0 },
{ "ASLD", OPCAT_TWOBYTE, 0x058049, 0 },
{ "ASLD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1048, 0 },
OPCAT_TWOBYTE, 0x148, 0 },
{ "ASR", OPCAT_SINGLEADDR, 0x07, 0 },
{ "ASRA", OPCAT_ONEBYTE, 0x47, 0 },
{ "ASRB", OPCAT_ONEBYTE, 0x57, 0 },
{ "ASRD", OPCAT_TWOBYTE, 0x047056, 0 },
{ "ASRD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1047, 0 },
OPCAT_TWOBYTE, 0x147, 0 },
{ "BAND", OPCAT_6309 |
OPCAT_BITTRANS, 0x1130, 0 },
OPCAT_BITTRANS, 0x230, 0 },
{ "BCC", OPCAT_SBRANCH, 0x24, 0 },
{ "BCS", OPCAT_SBRANCH, 0x25, 0 },
{ "BEC", OPCAT_SBRANCH, 0x24, 0 },
{ "BEOR", OPCAT_6309 |
OPCAT_BITTRANS, 0x1134, 0 },
OPCAT_BITTRANS, 0x234, 0 },
{ "BEQ", OPCAT_SBRANCH, 0x27, 0 },
{ "BES", OPCAT_SBRANCH, 0x25, 0 },
{ "BGE", OPCAT_SBRANCH, 0x2c, 0 },
428,13 → 428,13
{ "BHI", OPCAT_SBRANCH, 0x22, 0 },
{ "BHS", OPCAT_SBRANCH, 0x24, 0 },
{ "BIAND", OPCAT_6309 |
OPCAT_BITTRANS, 0x1131, 0 },
OPCAT_BITTRANS, 0x231, 0 },
{ "BIEOR", OPCAT_6309 |
OPCAT_BITTRANS, 0x1135, 0 },
OPCAT_BITTRANS, 0x235, 0 },
{ "BIN", OPCAT_PSEUDO, PSEUDO_BINARY, 0 },
{ "BINARY", OPCAT_PSEUDO, PSEUDO_BINARY, 0 },
{ "BIOR", OPCAT_6309 |
OPCAT_BITTRANS, 0x1133, 0 },
OPCAT_BITTRANS, 0x233, 0 },
{ "BIT", OPCAT_ACCARITH, 0x85, 0 },
{ "BITA", OPCAT_ARITH, 0x85, 0 },
{ "BITB", OPCAT_ARITH, 0xc5, 0 },
441,7 → 441,7
{ "BITD", OPCAT_6309 |
OPCAT_DBLREG1BYTE, 0x185, 0 },
{ "BITMD", OPCAT_6309 |
OPCAT_2IMMBYTE, 0x113c, 0 },
OPCAT_IMMBYTE, 0x23c, 0 },
{ "BLE", OPCAT_SBRANCH, 0x2f, 0 },
{ "BLO", OPCAT_SBRANCH, 0x25, 0 },
{ "BLS", OPCAT_SBRANCH, 0x23, 0 },
449,7 → 449,7
{ "BMI", OPCAT_SBRANCH, 0x2b, 0 },
{ "BNE", OPCAT_SBRANCH, 0x26, 0 },
{ "BOR", OPCAT_6309 |
OPCAT_BITTRANS, 0x1132, 0 },
OPCAT_BITTRANS, 0x232, 0 },
{ "BPL", OPCAT_SBRANCH, 0x2a, 0 },
{ "BRA", OPCAT_SBRANCH, 0x20, 0 },
{ "BRN", OPCAT_SBRANCH, 0x21, 0 },
466,13 → 466,13
{ "CLRB", OPCAT_ONEBYTE, 0x5f, 0 },
{ "CLRD", OPCAT_TWOBYTE, 0x4f05f, 0 },
{ "CLRD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x104f, 0 },
OPCAT_TWOBYTE, 0x14f, 0 },
{ "CLRE", OPCAT_6309 |
OPCAT_TWOBYTE, 0x114f, 0 },
OPCAT_TWOBYTE, 0x24f, 0 },
{ "CLRF", OPCAT_6309 |
OPCAT_TWOBYTE, 0x115f, 0 },
OPCAT_TWOBYTE, 0x25f, 0 },
{ "CLRW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x105f, 0 },
OPCAT_TWOBYTE, 0x15f, 0 },
{ "CLV", OPCAT_TWOBYTE, 0x1c0fd, 0 },
{ "CLZ", OPCAT_TWOBYTE, 0x1c0fb, 0 },
{ "CMP", OPCAT_ACCARITH, 0x81, 0 },
480,15 → 480,15
{ "CMPB", OPCAT_ARITH, 0xc1, 0 },
{ "CMPD", OPCAT_DBLREG1BYTE, 0x183, 0 },
{ "CMPE", OPCAT_6309 |
OPCAT_2ARITH, 0x1181, 0 },
OPCAT_ARITH, 0x281, 0 },
{ "CMPF", OPCAT_6309 |
OPCAT_2ARITH, 0x11c1, 0 },
OPCAT_ARITH, 0x2c1, 0 },
{ "CMPR", OPCAT_6309 |
OPCAT_IREG, 0x1037, 0 },
OPCAT_IREG, 0x137, 0 },
{ "CMPS", OPCAT_DBLREG1BYTE, 0x28c, 4 },
{ "CMPU", OPCAT_DBLREG1BYTE, 0x283, 3 },
{ "CMPW", OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x1081, 0 },
OPCAT_DBLREG2BYTE, 0x181, 0 },
{ "CMPX", OPCAT_DBLREG1BYTE, 0x8c, 1 },
{ "CMPY", OPCAT_DBLREG1BYTE, 0x18c, 2 },
{ "COM", OPCAT_SINGLEADDR, 0x03, 0 },
497,11 → 497,11
{ "COMD", OPCAT_6309 |
OPCAT_ONEBYTE, 0x143, 0 },
{ "COME", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1143, 0 },
OPCAT_TWOBYTE, 0x243, 0 },
{ "COMF", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1153, 0 },
OPCAT_TWOBYTE, 0x253, 0 },
{ "COMW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1053, 0 },
OPCAT_TWOBYTE, 0x153, 0 },
{ "COMMON", OPCAT_PSEUDO, PSEUDO_COMMON, 0 },
{ "CPD", OPCAT_DBLREG1BYTE, 0x183, 0 },
{ "CPX", OPCAT_DBLREG1BYTE, 0x8c, 1 },
513,13 → 513,13
{ "DECB", OPCAT_ONEBYTE, 0x5a, 0 },
{ "DECD", OPCAT_THREEBYTE, 0x083000001LL, 0 },
{ "DECD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x104a, 0 },
OPCAT_TWOBYTE, 0x14a, 0 },
{ "DECE", OPCAT_6309 |
OPCAT_TWOBYTE, 0x114a, 0 },
OPCAT_TWOBYTE, 0x24a, 0 },
{ "DECF", OPCAT_6309 |
OPCAT_TWOBYTE, 0x115a, 0 },
OPCAT_TWOBYTE, 0x25a, 0 },
{ "DECW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x105a, 0 },
OPCAT_TWOBYTE, 0x15a, 0 },
{ "DEF", OPCAT_PSEUDO, PSEUDO_DEF, 0 },
{ "DEFINE", OPCAT_PSEUDO, PSEUDO_DEF, 0 },
{ "DES", OPCAT_TWOBYTE, 0x327ff, 4 },
527,9 → 527,9
{ "DEX", OPCAT_TWOBYTE, 0x301ff, 1 },
{ "DEY", OPCAT_TWOBYTE, 0x313ff, 2 },
{ "DIVD", OPCAT_6309 |
OPCAT_2ARITH, 0x118d, 0 },
OPCAT_ARITH, 0x28d, 0 },
{ "DIVQ", OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x118e, 0 },
OPCAT_DBLREG2BYTE, 0x28e, 0 },
{ "DUP", OPCAT_PSEUDO, PSEUDO_DUP, 0 },
{ "EIM", OPCAT_6309 |
OPCAT_BITDIRECT, 0x05, 0 },
546,7 → 546,7
{ "EORD", OPCAT_6309 |
OPCAT_DBLREG1BYTE, 0x188, 0 },
{ "EORR", OPCAT_6309 |
OPCAT_IREG, 0x1036, 0 },
OPCAT_IREG, 0x136, 0 },
{ "EQU", OPCAT_PSEUDO, PSEUDO_EQU, 0 },
{ "ERR", OPCAT_PSEUDO, PSEUDO_ERR, 0 },
{ "EXG", OPCAT_2REG, 0x1e, 0 },
570,14 → 570,14
{ "INCB", OPCAT_ONEBYTE, 0x5c, 0 },
{ "INCD", OPCAT_THREEBYTE, 0x0c3000001LL, 0 },
{ "INCD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x104c, 0 },
OPCAT_TWOBYTE, 0x14c, 0 },
{ "INCE", OPCAT_6309 |
OPCAT_TWOBYTE, 0x114c, 0 },
OPCAT_TWOBYTE, 0x24c, 0 },
{ "INCF", OPCAT_6309 |
OPCAT_TWOBYTE, 0x115c, 0 },
OPCAT_TWOBYTE, 0x25c, 0 },
{ "INCLUDE", OPCAT_PSEUDO, PSEUDO_INCLUDE, 0 },
{ "INCW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x105c, 0 },
OPCAT_TWOBYTE, 0x15c, 0 },
{ "INS", OPCAT_TWOBYTE, 0x32601, 4 },
{ "INU", OPCAT_TWOBYTE, 0x33401, 3 },
{ "INX", OPCAT_TWOBYTE, 0x30001, 1 },
612,20 → 612,20
{ "LDAD", OPCAT_DBLREG1BYTE, 0xcc, 0 },
{ "LDB", OPCAT_ARITH, 0xc6, 0 },
{ "LDBT", OPCAT_6309 |
OPCAT_BITTRANS, 0x1136, 0 },
OPCAT_BITTRANS, 0x236, 0 },
{ "LDD", OPCAT_DBLREG1BYTE, 0xcc, 0 },
{ "LDE", OPCAT_6309 |
OPCAT_2ARITH, 0x1186, 0 },
OPCAT_ARITH, 0x286, 0 },
{ "LDF", OPCAT_6309 |
OPCAT_2ARITH, 0x11c6, 0 },
OPCAT_ARITH, 0x2c6, 0 },
{ "LDMD", OPCAT_6309 |
OPCAT_2IMMBYTE, 0x113d, 0 },
OPCAT_IMMBYTE, 0x23d, 0 },
{ "LDQ", OPCAT_6309 |
OPCAT_QUADREG1BYTE,0x10cc, 0 },
OPCAT_QUADREG1BYTE,0x1cc, 0 },
{ "LDS", OPCAT_DBLREG1BYTE, 0x1ce, 4 },
{ "LDU", OPCAT_DBLREG1BYTE, 0xce, 3 },
{ "LDW", OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x1086, 0 },
OPCAT_DBLREG2BYTE, 0x186, 0 },
{ "LDX", OPCAT_DBLREG1BYTE, 0x8e, 1 },
{ "LDY", OPCAT_DBLREG1BYTE, 0x18e, 2 },
{ "LEAS", OPCAT_LEA, 0x32, 4 },
639,19 → 639,19
{ "LSLB", OPCAT_ONEBYTE, 0x58, 0 },
{ "LSLD", OPCAT_TWOBYTE, 0x58049, 0 },
{ "LSLD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1048, 0 },
OPCAT_TWOBYTE, 0x148, 0 },
{ "LSR", OPCAT_SINGLEADDR, 0x04, 0 },
{ "LSRA", OPCAT_ONEBYTE, 0x44, 0 },
{ "LSRB", OPCAT_ONEBYTE, 0x54, 0 },
{ "LSRD", OPCAT_TWOBYTE, 0x44056, 0 },
{ "LSRD63", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1044, 0 },
OPCAT_TWOBYTE, 0x144, 0 },
{ "LSRW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1054, 0 },
OPCAT_TWOBYTE, 0x154, 0 },
{ "MACRO", OPCAT_PSEUDO, PSEUDO_MACRO, 0 },
{ "MUL", OPCAT_ONEBYTE, 0x3d, 0 },
{ "MULD", OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x118f, 0 },
OPCAT_DBLREG2BYTE, 0x28f, 0 },
{ "NAM", OPCAT_PSEUDO, PSEUDO_NAM, 0 },
{ "NAME", OPCAT_PSEUDO, PSEUDO_NAME, 0 },
{ "NEG", OPCAT_SINGLEADDR, 0x00, 0 },
673,7 → 673,7
OPCAT_DBLREG1BYTE, 0x18a, 0 },
{ "ORG", OPCAT_PSEUDO, PSEUDO_ORG, 0 },
{ "ORR", OPCAT_6309 |
OPCAT_IREG, 0x1035, 0 },
OPCAT_IREG, 0x135, 0 },
{ "PAG", OPCAT_PSEUDO, PSEUDO_PAG, 0 },
{ "PAGE", OPCAT_PSEUDO, PSEUDO_PAG, 0 },
{ "PSH", OPCAT_STACK, 0x34, 0 },
682,10 → 682,10
{ "PSHD", OPCAT_TWOBYTE, 0x34006, 0 },
{ "PSHS", OPCAT_STACK, 0x34, 4 },
{ "PSHSW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1038, 0 },
OPCAT_TWOBYTE, 0x138, 0 },
{ "PSHU", OPCAT_STACK, 0x36, 3 },
{ "PSHUW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x103a, 0 },
OPCAT_TWOBYTE, 0x13a, 0 },
{ "PSHX", OPCAT_TWOBYTE, 0x34010, 1 },
{ "PSHY", OPCAT_TWOBYTE, 0x34020, 2 },
{ "PUB", OPCAT_PSEUDO, PSEUDO_PUB, 0 },
696,10 → 696,10
{ "PULD", OPCAT_TWOBYTE, 0x35006, 0 },
{ "PULS", OPCAT_STACK, 0x35, 4 },
{ "PULSW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1039, 0 },
OPCAT_TWOBYTE, 0x139, 0 },
{ "PULU", OPCAT_STACK, 0x37, 3 },
{ "PULUW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x103b, 0 },
OPCAT_TWOBYTE, 0x13b, 0 },
{ "PULX", OPCAT_TWOBYTE, 0x35010, 1 },
{ "PULY", OPCAT_TWOBYTE, 0x35020, 2 },
{ "REG", OPCAT_PSEUDO, PSEUDO_REG, 0 },
713,7 → 713,7
{ "ROLD", OPCAT_6309 |
OPCAT_ONEBYTE, 0x149, 0 },
{ "ROLW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1059, 0 },
OPCAT_TWOBYTE, 0x159, 0 },
{ "ROR", OPCAT_SINGLEADDR, 0x06, 0 },
{ "RORA", OPCAT_ONEBYTE, 0x46, 0 },
{ "RORB", OPCAT_ONEBYTE, 0x56, 0 },
720,7 → 720,7
{ "RORD", OPCAT_6309 |
OPCAT_ONEBYTE, 0x146, 0 },
{ "RORW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x1056, 0 },
OPCAT_TWOBYTE, 0x156, 0 },
{ "RPT", OPCAT_PSEUDO, PSEUDO_REP, 0 },
{ "RTF", OPCAT_ONEBYTE, 0x38, 0 },
{ "RTI", OPCAT_ONEBYTE, 0x3b, 0 },
733,7 → 733,7
{ "SBCD", OPCAT_6309 |
OPCAT_DBLREG1BYTE, 0x182, 0 },
{ "SBCR", OPCAT_6309 |
OPCAT_IREG, 0x1033, 0 },
OPCAT_IREG, 0x133, 0 },
{ "SEC", OPCAT_TWOBYTE, 0x1a001, 0 },
{ "SEF", OPCAT_TWOBYTE, 0x1a040, 0 },
{ "SEI", OPCAT_TWOBYTE, 0x1a010, 0 },
759,18 → 759,18
{ "STB", OPCAT_NOIMM |
OPCAT_ARITH, 0xc7, 0 },
{ "STBT", OPCAT_6309 |
OPCAT_BITTRANS, 0x1137, 0 },
OPCAT_BITTRANS, 0x237, 0 },
{ "STD", OPCAT_NOIMM |
OPCAT_DBLREG1BYTE, 0xcd, 0 },
{ "STE", OPCAT_NOIMM |
OPCAT_6309 |
OPCAT_2ARITH, 0x1187, 0 },
OPCAT_ARITH, 0x287, 0 },
{ "STF", OPCAT_NOIMM |
OPCAT_6309 |
OPCAT_2ARITH, 0x11c7, 0 },
OPCAT_ARITH, 0x2c7, 0 },
{ "STQ", OPCAT_NOIMM |
OPCAT_6309 |
OPCAT_QUADREG1BYTE,0x10cd, 0 },
OPCAT_QUADREG1BYTE,0x1cd, 0 },
{ "STS", OPCAT_NOIMM |
OPCAT_DBLREG1BYTE, 0x1cf, 4 },
{ "STTL", OPCAT_PSEUDO, PSEUDO_STTL, 0 },
778,7 → 778,7
OPCAT_DBLREG1BYTE, 0xcf, 3 },
{ "STW", OPCAT_NOIMM |
OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x1087, 0 },
OPCAT_DBLREG2BYTE, 0x187, 0 },
{ "STX", OPCAT_NOIMM |
OPCAT_DBLREG1BYTE, 0x8f, 1 },
{ "STY", OPCAT_NOIMM |
788,13 → 788,13
{ "SUBB", OPCAT_ARITH, 0xc0, 0 },
{ "SUBD", OPCAT_DBLREG1BYTE, 0x83, 0 },
{ "SUBE", OPCAT_6309 |
OPCAT_2ARITH, 0x1180, 0 },
OPCAT_ARITH, 0x280, 0 },
{ "SUBF", OPCAT_6309 |
OPCAT_2ARITH, 0x11c0, 0 },
OPCAT_ARITH, 0x2c0, 0 },
{ "SUBW", OPCAT_6309 |
OPCAT_DBLREG2BYTE, 0x1080, 0 },
OPCAT_DBLREG2BYTE, 0x180, 0 },
{ "SUBR", OPCAT_6309 |
OPCAT_IREG, 0x1032, 0 },
OPCAT_IREG, 0x132, 0 },
{ "SWI", OPCAT_ONEBYTE, 0x3f, 0 },
{ "SWI2", OPCAT_ONEBYTE, 0x13f, 0 },
{ "SWI3", OPCAT_ONEBYTE, 0x23f, 0 },
805,7 → 805,7
{ "TBA", OPCAT_THREEBYTE, 0x1f09804dLL, 0 },
{ "TEXT", OPCAT_PSEUDO, PSEUDO_TEXT, 0 },
{ "TFM", OPCAT_6309 |
OPCAT_BLOCKTRANS, 0x1138, 0 },
OPCAT_BLOCKTRANS, 0x238, 0 },
{ "TFR", OPCAT_2REG, 0x1f, 0 },
{ "TIM", OPCAT_6309 |
OPCAT_BITDIRECT, 0x0b, 0 },
817,11 → 817,11
{ "TSTD", OPCAT_6309 |
OPCAT_ONEBYTE, 0x14d, 0 },
{ "TSTE", OPCAT_6309 |
OPCAT_TWOBYTE, 0x114d, 0 },
OPCAT_TWOBYTE, 0x24d, 0 },
{ "TSTF", OPCAT_6309 |
OPCAT_TWOBYTE, 0x115d, 0 },
OPCAT_TWOBYTE, 0x25d, 0 },
{ "TSTW", OPCAT_6309 |
OPCAT_TWOBYTE, 0x105d, 0 },
OPCAT_TWOBYTE, 0x15d, 0 },
{ "TSX", OPCAT_TWOBYTE, 0x1f041, 1 },
{ "TSY", OPCAT_FOURBYTE, 0x034040035020LL, 2 }, /* PSHS S/PULS Y */
{ "TTL", OPCAT_PSEUDO, PSEUDO_NAM, 0 },
3517,8 → 3517,30
{
if (objfile)
{
for (i = 0; i < hexcount; i++)
fprintf(objfile, "rommem[%5d] <= 12'h%03X;\r\n", (hexaddr+i) & 0x3fff, hexbuffer[i] & 0xfff);
i = 0;
for (i = 0; i < hexcount; i++)
fprintf(objfile, "rommem[%5d] <= 12'h%03X;\r\n", (hexaddr + i) & 0x3fff, hexbuffer[i] & 0xfff);
/*
fprintf(objfile, "rommem[%5d] <= 192'h%03X%03X%03X%03X%03X%03X%03X%03X%03X%03X%03X%03X%03X%03X%03X%03X;\r\n",
(hexaddr>>4) & 0x3ff,
hexbuffer[i+15] & 0xfff,
hexbuffer[i + 14] & 0xfff,
hexbuffer[i + 13] & 0xfff,
hexbuffer[i + 12] & 0xfff,
hexbuffer[i + 11] & 0xfff,
hexbuffer[i + 10] & 0xfff,
hexbuffer[i + 9] & 0xfff,
hexbuffer[i + 8] & 0xfff,
hexbuffer[i + 7] & 0xfff,
hexbuffer[i + 6] & 0xfff,
hexbuffer[i + 5] & 0xfff,
hexbuffer[i + 4] & 0xfff,
hexbuffer[i + 3] & 0xfff,
hexbuffer[i + 2] & 0xfff,
hexbuffer[i + 1] & 0xfff,
hexbuffer[i + 0] & 0xfff
);
*/
hexaddr += hexcount;
hexcount = 0;
chksum = 0;
3527,8 → 3549,35
}
}
 
int crc24(int count)
{
int crc = 0xB704CEL;
int n, i;
crc = crc ^ (((hexaddr >> 12) & 0xfff) << 12);
for (i = 0; i < 12; i++) {
crc <<= 1;
if (crc & 0x1000000)
crc ^= 0xCFB864;
}
crc = crc ^ ((hexaddr & 0xfff) << 12);
for (i = 0; i < 12; i++) {
crc <<= 1;
if (crc & 0x1000000)
crc ^= 0xCFB864;
}
for (n = 0; --count >= 0; n++) {
crc = crc ^ (hexbuffer[n] << 12);
for (i = 0; i < 12; i++) {
crc <<= 1;
if (crc & 0x1000000)
crc ^= 0xCFB864;
}
}
return (crc);
}
 
/*****************************************************************************/
/* flushhex : write Motorola s-records */
/* flushhex : write Finitron c-records */
/* Flushes using 12-bit bytes */
/*****************************************************************************/
 
3540,11 → 3589,12
{
if (objfile)
{
fprintf(objfile, "S1%03X%06X", (hexcount + 3) & 0xfff, hexaddr & 0xffffff);
fprintf(objfile, "C1%03X%06X", (hexcount + 3) & 0xfff, hexaddr & 0xffffff);
for (i = 0; i < hexcount; i++)
fprintf(objfile, "%03X", hexbuffer[i] & 0xfff);
chksum += (hexaddr & 0xfff) + ((hexaddr >> 12) & 0xfff) + hexcount + 3;
fprintf(objfile, "%03X\n", 0xfff - (chksum & 0xfff));
// chksum += (hexaddr & 0xfff) + ((hexaddr >> 12) & 0xfff) + hexcount + 3;
// fprintf(objfile, "%03X\n", 0xfff - (chksum & 0xfff));
fprintf(objfile, "%06X\n", crc24(hexcount) & 0xffffff);
}
hexaddr += hexcount;
hexcount = 0;
3624,7 → 3674,7
 
void outver (unsigned short x)
{
if (hexcount==4)
if (hexcount==16)
flushver();
hexbuffer[hexcount] = x;
hexcount++;
6684,7 → 6734,7
#endif
break;
case OUT_SREC : /* Motorola S51-09 ? */
strcpy(ld, ".s09");
strcpy(ld, ".c19");
break;
case OUT_IHEX : /* Intel Hex ? */
strcpy(ld, ".hex");
7011,7 → 7061,7
case OUT_SREC : /* Motorola S51-09 */
flushhex();
chksum = (tfradr & 0xfff) + ((tfradr >> 12) & 0xfff) + 3;
fprintf(objfile, "S9003%06X%03X\n", tfradr, 0xfff - (chksum & 0xfff));
fprintf(objfile, "C9003%06X%03X\n", tfradr, 0xfff - (chksum & 0xfff));
break;
case OUT_IHEX : /* Intel Hex */
flushihex();

powered by: WebSVN 2.1.0

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