Skip to content

Commit

Permalink
Added sources.
Browse files Browse the repository at this point in the history
thasega committed Jan 11, 2015
1 parent bcec932 commit a97c732
Showing 11 changed files with 3,210 additions and 0 deletions.
239 changes: 239 additions & 0 deletions HD63701.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
/******************************************************
HD63701V0(Mode6) Compatible Processor Core
Written by Tsuyoshi HASEGAWA 2013-14
*******************************************************/
module HD63701V0_M6
(
input CLKx2, // XTAL/EXTAL (200K~2.0MHz)

input RST, // RES
input NMI, // NMI
input IRQ, // IRQ1

output RW, // CS2
output [15:0] AD, // AS ? {PO4,PO3}
output [7:0] DO, // ~AS ? {PO3}
input [7:0] DI, // {PI3}

input [7:0] PI1, // Port1 IN
output [7:0] PO1, // OUT

input [4:0] PI2, // Port2 IN
output [4:0] PO2, // OUT

// for DEBUG
output [6:0] phase
);

// Built-In Instruction ROM
wire en_birom = (AD[15:12]==4'b1111); // $F000-$FFFF
wire [7:0] biromd;
MCU_BIROM irom( CLKx2, AD[11:0], biromd );


// Built-In WorkRAM
wire en_biram;
wire [7:0] biramd;
HD63701_BIRAM biram( CLKx2, AD, RW, DO, en_biram, biramd );


// Built-In I/O Ports
wire en_biio;
wire [7:0] biiod;
HD63701_IOPort iopt( RST, CLKx2, AD, RW, DO, en_biio, biiod, PI1, PI2, PO1, PO2 );


// Built-In Timer
wire irq2;
wire [3:0] irq2v;
wire en_bitim;
wire [7:0] bitimd;
HD63701_Timer timer( RST, CLKx2, AD, RW, DO, irq2, irq2v, en_bitim, bitimd );


// Built-In Devices Data Selector
wire [7:0] biddi;
HD63701_BIDSEL bidsel
(
biddi,
en_birom, biromd,
en_biram, biramd,
en_biio , biiod,
en_bitim, bitimd,
DI
);

// Processor Core
HD63701_Core core
(
.CLKx2(CLKx2),.RST(RST),
.NMI(NMI),.IRQ(IRQ),.IRQ2(irq2),.IRQ2V(irq2v),
.RW(RW),.AD(AD),.DO(DO),.DI(biddi),
.PH(phase[5:0])
);
assign phase[6] = irq2;

endmodule


module HD63701_BIDSEL
(
output [7:0] o,

input e0, input [7:0] d0,
input e1, input [7:0] d1,
input e2, input [7:0] d2,
input e3, input [7:0] d3,

input [7:0] dx
);

assign o = e0 ? d0 :
e1 ? d1 :
e2 ? d2 :
e3 ? d3 :
dx;

endmodule


module HD63701_BIRAM
(
input mcu_clx2,
input [15:0] mcu_ad,
input mcu_wr,
input [7:0] mcu_do,
output en_biram,
output reg [7:0] biramd
);

assign en_biram = (mcu_ad[15: 7]==9'b000000001); // $0080-$00FF
wire [6:0] biad = mcu_ad[6:0];

reg [7:0] bimem[0:127];
always @( posedge mcu_clx2 ) begin
if (en_biram & mcu_wr) bimem[biad] <= mcu_do;
else biramd <= bimem[biad];
end

endmodule


module HD63701_IOPort
(
input mcu_rst,
input mcu_clx2,
input [15:0] mcu_ad,
input mcu_wr,
input [7:0] mcu_do,

output en_io,
output [7:0] iod,

input [7:0] PI1,
input [4:0] PI2,

output reg [7:0] PO1,
output reg [4:0] PO2
);

always @( posedge mcu_clx2 or posedge mcu_rst ) begin
if (mcu_rst) begin
PO1 <= 8'hFF;
PO2 <= 5'h1F;
end
else begin
if (mcu_wr) begin
if (mcu_ad==16'h2) PO1 <= mcu_do;
if (mcu_ad==16'h3) PO2 <= mcu_do[4:0];
end
end
end

assign en_io = (mcu_ad==16'h2)|(mcu_ad==16'h3);
assign iod = (mcu_ad==16'h2) ? PI1 : {3'b111,PI2};

endmodule


module HD63701_Timer
(
input mcu_rst,
input mcu_clx2,
input [15:0] mcu_ad,
input mcu_wr,
input [7:0] mcu_do,

output mcu_irq2,
output [3:0] mcu_irq2v,

output en_timer,
output [7:0] timerd
);

reg oci, oce;
reg [15:0] ocr, icr;
reg [16:0] frc;
reg [7:0] frt;
reg [7:0] rmc, rg5;

always @( posedge mcu_clx2 or posedge mcu_rst ) begin
if (mcu_rst) begin
oce <= 0;
ocr <= 16'hFFFF;
icr <= 16'hFFFF;
frc <= 0;
frt <= 0;
rmc <= 8'h40;
rg5 <= 0;
end
else begin
frc <= frc+1;
if (mcu_wr) begin
case (mcu_ad)
16'h05: rg5 <= mcu_do;
16'h08: oce <= mcu_do[3];
16'h09: frt <= mcu_do;
16'h0A: frc <= {frt,mcu_do,1'h0};
16'h0B: ocr[15:8] <= mcu_do;
16'h0C: ocr[ 7:0] <= mcu_do;
16'h0D: icr[15:8] <= mcu_do;
16'h0E: icr[ 7:0] <= mcu_do;
16'h14: rmc <= {mcu_do[7:6],6'h0};
default:;
endcase
end
end
end

always @( negedge mcu_clx2 or posedge mcu_rst ) begin
if (mcu_rst) begin
oci <= 0;
end
else begin
case (mcu_ad)
16'h0B: oci <= 0;
16'h0C: oci <= 0;
default: if (frc[16:1]==ocr) oci <= 1'b1;
endcase
end
end

assign mcu_irq2 = oci & oce;
assign mcu_irq2v = 4'h4;

assign en_timer = (mcu_ad==16'h05)|((mcu_ad>=16'h8)&(mcu_ad<=16'hE))|(mcu_ad==16'h14);

assign timerd = (mcu_ad==16'h05) ? rg5 :
(mcu_ad==16'h08) ? {1'b0,oci,2'b10,oce,3'b000}:
(mcu_ad==16'h09) ? frc[16:9] :
(mcu_ad==16'h0A) ? frc[ 8:1] :
(mcu_ad==16'h0B) ? ocr[15:8] :
(mcu_ad==16'h0C) ? ocr[ 7:0] :
(mcu_ad==16'h0D) ? icr[15:8] :
(mcu_ad==16'h0E) ? icr[ 7:0] :
(mcu_ad==16'h14) ? rmc :
8'h0;

endmodule

73 changes: 73 additions & 0 deletions HD63701_ALU.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/***************************************************************************
This file is part of "HD63701V0 Compatible Processor Core".
****************************************************************************/
`timescale 1ps / 1ps
`include "HD63701_defs.i"

module HD63701_ALU
(
input [4:0] op,
input [7:0] cf,
input bw,

input [15:0] R0,
input [15:0] R1,
input C,

output [15:0] RR,
output [5:0] RC
);

wire [16:0] r =
(op==`mcTST) ? (R0):
(op==`mcLDR) ? (R0):
(op==`mcLDN) ? (R0):
(op==`mcPSH) ? (R0):
(op==`mcPUL) ? (R0):
(op==`mcINT) ? (R0):
(op==`mcDAA) ? (R0): // todo: DAA
(op==`mcINC) ? (R0+16'h1):
(op==`mcADD) ? (R0+R1):
(op==`mcADC) ? (R0+R1+C):
(op==`mcDEC) ? (R0-16'h1):
(op==`mcSUB) ? (R0-R1):
(op==`mcSBC) ? (R0-R1-C):
(op==`mcMUL) ? (R0*R1):
(op==`mcNEG) ? ((~R0)+16'h1):
(op==`mcNOT) ? (~R0):
(op==`mcAND) ? (R0&R1):
(op==`mcLOR) ? (R0|R1):
(op==`mcEOR) ? (R0^R1):
(op==`mcASL) ? {R0[15:0],1'b0}:
(op==`mcASR) ? (bw ? {R0[15],R0[15:1]}:{R0[7],R0[7:1]}):
(op==`mcLSR) ? {1'b0,R0[15:1]}:
(op==`mcROL) ? {R0[15:0],C}:
(op==`mcROR) ? (bw ? {C,R0[15:1]} : {C,R0[7:1]}):
(op==`mcCCB) ? {10'h3,(R0[5:0]&cf[5:0])}:
(op==`mcSCB) ? {10'h3,(R0[5:0]|cf[5:0])}:
(16'h0);

assign RR = r[15:0];

wire chCarryL = (op==`mcASL)|(op==`mcROL)|
(op==`mcADD)|(op==`mcADC)|
(op==`mcSUB)|(op==`mcSBC)|
(op==`mcMUL);

wire chCarryR = (op==`mcASR)|(op==`mcLSR)|(op==`mcROR);

assign fC = (op==`mcNOT) ? 1'b1 :
chCarryL ? ( bw ? r[16] : r[8] ) :
chCarryR ? R0[0] :
C ;

assign fZ = bw ?(RR[15:0]==0) : (RR[7:0]==0);
assign fN = bw ? RR[15] : RR[7];

assign fV = (op==`mcLDR) ? 1'b0 : (bw ?(R0[15]^R1[15]^RR[15]^RR[14]) : (R0[7]^R1[7]^RR[7]^RR[6]));
assign fH = (op==`mcLDR) ? 1'b0 : R0[4]^R1[4]^RR[4];

assign RC = {fH,1'b0,fN,fZ,fV,fC};

endmodule

54 changes: 54 additions & 0 deletions HD63701_CORE.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/***************************************************************************
This file is part of "HD63701V0 Compatible Processor Core".
****************************************************************************/
`timescale 1ps / 1ps
`include "HD63701_defs.i"

module HD63701_Core
(
input CLKx2,

input RST,
input NMI,
input IRQ,
input IRQ2,
input [3:0] IRQ2V,

output RW,
output [15:0] AD,
output [7:0] DO,
input [7:0] DI,

// for DEBUG
output CLKo,
output [5:0] PH,
output `mcwidth MC,
output [15:0] REG_D,
output [15:0] REG_X,
output [15:0] REG_S,
output [5:0] REG_C
);

reg CLK = 0;
always @( negedge CLKx2 ) CLK <= ~CLK;
assign CLKo = CLK;

wire `mcwidth mcode;
wire [7:0] vect;
wire inte, fncu;

assign MC = mcode;

HD63701_SEQ SEQ(.CLK(CLK),.RST(RST),
.NMI(NMI),.IRQ(IRQ),.IRQ2(IRQ2),.IRQ2V(IRQ2V),
.DI(DI),
.mcout(mcode),.vect(vect),.inte(inte),.fncu(fncu),
.PH(PH) );

HD63701_EXEC EXEC(.CLK(CLK),.RST(RST),.DI(DI),.AD(AD),.RW(RW),.DO(DO),
.mcode(mcode),.vect(vect),.inte(inte),.fncu(fncu),
.REG_D(REG_D),.REG_X(REG_X),.REG_S(REG_S),.REG_C(REG_C) );

endmodule


255 changes: 255 additions & 0 deletions HD63701_EXEC.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
/***************************************************************************
This file is part of "HD63701V0 Compatible Processor Core".
****************************************************************************/
`timescale 1ps / 1ps
`include "HD63701_defs.i"

module HD63701_EXEC
(
input CLK,
input RST,

input [7:0] DI,

output [15:0] AD,
output reg RW,
output reg [7:0] DO,

input `mcwidth mcode,
output reg [7:0] vect,
output inte,
input fncu,

output [15:0] REG_D,
output [15:0] REG_X,
output [15:0] REG_S,
output [5:0] REG_C
);

// MicroCode Format
wire mcpi = mcode[0];
wire [2:0] mcam = mcode[3:1];
wire [2:0] mcph = mcode[6:4];
wire [3:0] mcr2 = mcode[10:7];
wire [3:0] mcr1 = mcode[14:11];
wire [3:0] mcr0 = mcode[18:15];
wire [4:0] mcop = mcode[23:19];

wire mcnw = (mcop==`mcCCB)|(mcop==`mcSCB)|(mcop==`mcAPC)|
(mcop==`mcLDV)|(mcop==`mcINT);

wire [7:0] mccf = {mcr0,mcr1}; // case of mcCCB & mcSCB & mcAPC
wire [7:0] mcva = {mcr0,mcr1}; // case of mcLDV & mcINT


// Registers
reg [15:0] rT, rE, rD, rX, rS, rSp, rP;
reg [5:0] rC;

`define rA rD[15:8]
`define rB rD[7:0]
`define rU rT[15:8]
`define rV rT[7:0]


// ALU
wire IsCCR = (mcop==`mcCCB)|(mcop==`mcSCB);
wire IsCChit = (({(rC[1]^rC[3]),rC} & mccf[6:0]) == 7'h0) ^ mccf[7];

wire [15:0] R0, R1, RR;
wire [5:0] CC;

HD63701_DSEL13 sR0(
.o(R0),
.f0((mcr0 == `mcrC)|IsCCR),.d0({10'b00000000_11,rC}),
.f1(mcr0 == `mcrA), .d1({8'h0,`rA}),
.f2(mcr0 == `mcrB), .d2({8'h0,`rB}),
.f3(mcr0 == `mcrD), .d3(rD),
.f4(mcr0 == `mcrX), .d4(rX),
.f5(mcr0 == `mcrS), .d5(rS),
.f6(mcr0 == `mcrP), .d6(rP),
.f7(mcr0 == `mcrU), .d7({8'h0,`rU}),
.f8(mcr0 == `mcrV), .d8({8'h0,`rV}),
.f9(mcr0 == `mcrN), .d9({DI,8'h0}),
.fA(mcr0 == `mcrM), .dA({8'h0,DI}),
.fB(mcr0 == `mcrT), .dB(rT),
.fC(mcr0 == `mcrE), .dC(rE)
);

HD63701_DSEL13 sR1(
.o(R1),
.f0((mcr1 == `mcrC)|IsCCR),.d0({10'b00000000_11,rC}),
.f1(mcr1 == `mcrA), .d1({8'h0,`rA}),
.f2(mcr1 == `mcrB), .d2({8'h0,`rB}),
.f3(mcr1 == `mcrD), .d3(rD),
.f4(mcr1 == `mcrX), .d4(rX),
.f5(mcr1 == `mcrS), .d5(rS),
.f6(mcr1 == `mcrP), .d6(rP),
.f7(mcr1 == `mcrU), .d7({8'h0,`rU}),
.f8(mcr1 == `mcrV), .d8({8'h0,`rV}),
.f9(mcr1 == `mcrN), .d9({DI,8'h0}),
.fA(mcr1 == `mcrM), .dA({8'h0,DI}),
.fB(mcr1 == `mcrT), .dB(rT),
.fC(mcr1 == `mcrE), .dC(rE)
);

HD63701_ALU ALU(
.op(mcop),.cf(mccf),.bw((mcr2==`mcrn) ? mcr0[2] : mcr2[2]),
.R0(R0),.R1(R1),.C(rC[0]),
.RR(RR),.RC(CC)
);


// Bus Control
HD63701_DSEL8 sAB(
.o(AD),
.f0(mcam==`amPC), .d0(rP),
.f1(mcam==`amP1), .d1(rP+16'h1),
.f2(mcam==`amSP), .d2(rS),
.f3(mcam==`amS1), .d3(rS+16'h1),
.f4(mcam==`amX0), .d4(rX),
.f5(mcam==`amXT), .d5(rX+rT),
.f6(mcam==`amE0), .d6(rE),
.f7(mcam==`amE1), .d7(rE+16'h1)
);


// Update Registers
reg [4:0] pmcop;
always @( posedge CLK ) begin
if (pmcop==`mcPSH) rS <= rSp-16'h1;
else if (pmcop==`mcPUL) rS <= rSp+16'h1;
else rS <= rSp;
end

wire noCCop = (mcop!=`mcLDV)&(mcop!=`mcLDN)&(mcop!=`mcPSH)&(mcop!=`mcPUL)&(mcop!=`mcAPC)&(mcop!=`mcTST)&(~fncu);
wire noCCrg = (mcr2!=`mcrC )&(mcr2!=`mcrS )&(mcr2!=`mcrP )&(mcr0!=`mcrC );

always @( negedge CLK or posedge RST ) begin
if (RST) begin
pmcop <= 0;
vect <= 0;
rT <= 0;
rE <= 0;
rP <= 0;
rC <= 6'b010000;
DO <= 0;
end
else begin
if ((mcr2!=`mcrP)&(mcpi==`pcI)) rP <= rP+16'h1;
if (noCCrg & noCCop) rC <= {CC[5],rC[4],CC[3:0]};
if (mcr2!=`mcrS) rSp <= rS;
case (mcop)
`mcXTD: begin rT <= rX; rX <= rD; end
`mcAPC: if (IsCChit) rP <= rP+{{8{rT[7]}},rT[7:0]};
`mcINT: vect <= mcva;
`mcLDV: rE <= {8'hFF,mcva};
`mcTST: rC <= {rC[5:3],CC[2],rC[1:0]};
default: case (mcr2)
`mcrA: `rA <= RR[7:0];
`mcrB: `rB <= RR[7:0];
`mcrC: rC <= RR[5:0];
`mcrD: rD <= RR;
`mcrX: rX <= RR;
`mcrS: rSp <= RR;
`mcrP: rP <= RR;
`mcrU: `rU <= RR[7:0];
`mcrV: `rV <= RR[7:0];
`mcrT: rT <= RR;
`mcrE: rE <= RR;
default:;
endcase
endcase
DO <= mcnw ? 8'h0 :
(mcr2==`mcrN) ? RR[15:8] :
(mcr2==`mcrM) ? RR[ 7:0] :
8'h0;

pmcop <= mcop;
end
end

wire RWRES = CLK;
always @( negedge CLK or posedge RWRES ) begin
if (RWRES) RW <= 0;
else begin
RW <= ((mcr2==`mcrN)|(mcr2==`mcrM)) & (~mcnw);
end
end

assign inte = ~rC[4];


assign REG_D = rD;
assign REG_X = rX;
assign REG_S = rS;
assign REG_C = rC;

endmodule


module HD63701_DSEL13
(
output [15:0] o,

input f0, input [15:0] d0,
input f1, input [15:0] d1,
input f2, input [15:0] d2,
input f3, input [15:0] d3,
input f4, input [15:0] d4,
input f5, input [15:0] d5,
input f6, input [15:0] d6,
input f7, input [15:0] d7,
input f8, input [15:0] d8,
input f9, input [15:0] d9,
input fA, input [15:0] dA,
input fB, input [15:0] dB,
input fC, input [15:0] dC
);

assign o =
f0 ? d0 :
f1 ? d1 :
f2 ? d2 :
f3 ? d3 :
f4 ? d4 :
f5 ? d5 :
f6 ? d6 :
f7 ? d7 :
f8 ? d8 :
f9 ? d9 :
fA ? dA :
fB ? dB :
fC ? dC :
16'h0 ;

endmodule


module HD63701_DSEL8
(
output [15:0] o,

input f0, input [15:0] d0,
input f1, input [15:0] d1,
input f2, input [15:0] d2,
input f3, input [15:0] d3,
input f4, input [15:0] d4,
input f5, input [15:0] d5,
input f6, input [15:0] d6,
input f7, input [15:0] d7
);

assign o =
f0 ? d0 :
f1 ? d1 :
f2 ? d2 :
f3 ? d3 :
f4 ? d4 :
f5 ? d5 :
f6 ? d6 :
f7 ? d7 :
16'h0 ;

endmodule

971 changes: 971 additions & 0 deletions HD63701_MCODE.i

Large diffs are not rendered by default.

113 changes: 113 additions & 0 deletions HD63701_MCROM.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/***************************************************************************
This file is part of "HD63701V0 Compatible Processor Core".
****************************************************************************/
`include "HD63701_defs.i"

module HD63701_MCROM
(
input CLK,
input [5:0] PHASE,
input [7:0] OPCODE,

output `mcwidth mcode
);

`include "HD63701_MCODE.i"

reg [5:0] p;
always @( posedge CLK ) p <= PHASE;

wire `mcwidth mc0,mc1,mc2,mc3,mc4,mc5,mc6,mc7,mc8,mc9;
HD63701_MCROM_S0 r0(CLK,OPCODE,mc0);
HD63701_MCROM_S1 r1(CLK,OPCODE,mc1);
HD63701_MCROM_S2 r2(CLK,OPCODE,mc2);
HD63701_MCROM_S3 r3(CLK,OPCODE,mc3);
HD63701_MCROM_S4 r4(CLK,OPCODE,mc4);
HD63701_MCROM_S5 r5(CLK,OPCODE,mc5);
HD63701_MCROM_S6 r6(CLK,OPCODE,mc6);
HD63701_MCROM_S7 r7(CLK,OPCODE,mc7);
HD63701_MCROM_S8 r8(CLK,OPCODE,mc8);
HD63701_MCROM_S9 r9(CLK,OPCODE,mc9);

assign mcode =
(p==`phRST ) ? {`mcLDV, `vaRST, `mcrn,`mcpN,`amE0,`pcN}: //(Load Reset Vector)

(p==`phVECT ) ? {`mcLDN,`mcrM,`mcrn,`mcrU,`mcpN,`amE0,`pcN}: //(Load VectorH)
(p==`phVEC1 ) ? {`mcLDN,`mcrM,`mcrn,`mcrV,`mcpN,`amE1,`pcN}: //(Load VectorL)
(p==`phVEC2 ) ? {`mcLDN,`mcrT,`mcrn,`mcrP,`mcp0,`amPC,`pcN}: //(Load to PC)

(p==`phEXEC ) ? mc0 :
(p==`phEXEC1) ? mc1 :
(p==`phEXEC2) ? mc2 :
(p==`phEXEC3) ? mc3 :
(p==`phEXEC4) ? mc4 :
(p==`phEXEC5) ? mc5 :
(p==`phEXEC6) ? mc6 :
(p==`phEXEC7) ? mc7 :
(p==`phEXEC8) ? mc8 :
(p==`phEXEC9) ? mc9 :

(p==`phINTR ) ? {`mcLDN,`mcrC,`mcrn,`mcrT,`mcpN,`amPC,`pcN}: //(T=C)
(p==`phINTR1) ? {`mcPSH,`mcrP,`mcrn,`mcrM,`mcpN,`amSP,`pcN}: //[PUSH PL]
(p==`phINTR2) ? {`mcPSH,`mcrP,`mcrn,`mcrN,`mcpN,`amSP,`pcN}: //[PUSH PH]
(p==`phINTR3) ? {`mcPSH,`mcrX,`mcrn,`mcrM,`mcpN,`amSP,`pcN}: //[PUSH XL]
(p==`phINTR4) ? {`mcPSH,`mcrX,`mcrn,`mcrN,`mcpN,`amSP,`pcN}: //[PUSH XH]
(p==`phINTR5) ? {`mcPSH,`mcrA,`mcrn,`mcrM,`mcpN,`amSP,`pcN}: //[PUSH A]
(p==`phINTR6) ? {`mcPSH,`mcrB,`mcrn,`mcrM,`mcpN,`amSP,`pcN}: //[PUSH B]
(p==`phINTR7) ? {`mcPSH,`mcrT,`mcrn,`mcrM,`mcpN,`amSP,`pcN}: //[PUSH T]
(p==`phINTR8) ? 0:
(p==`phINTR9) ? 0:
`MC_HALT;

endmodule

module HD63701_MCROM_S0( input CLK, input [7:0] OPCODE, output reg `mcwidth mcode );
`include "HD63701_MCODE.i"
always @( posedge CLK ) mcode <= MCODE_S0(OPCODE);
endmodule

module HD63701_MCROM_S1( input CLK, input [7:0] OPCODE, output reg `mcwidth mcode );
`include "HD63701_MCODE.i"
always @( posedge CLK ) mcode <= MCODE_S1(OPCODE);
endmodule

module HD63701_MCROM_S2( input CLK, input [7:0] OPCODE, output reg `mcwidth mcode );
`include "HD63701_MCODE.i"
always @( posedge CLK ) mcode <= MCODE_S2(OPCODE);
endmodule

module HD63701_MCROM_S3( input CLK, input [7:0] OPCODE, output reg `mcwidth mcode );
`include "HD63701_MCODE.i"
always @( posedge CLK ) mcode <= MCODE_S3(OPCODE);
endmodule

module HD63701_MCROM_S4( input CLK, input [7:0] OPCODE, output reg `mcwidth mcode );
`include "HD63701_MCODE.i"
always @( posedge CLK ) mcode <= MCODE_S4(OPCODE);
endmodule

module HD63701_MCROM_S5( input CLK, input [7:0] OPCODE, output reg `mcwidth mcode );
`include "HD63701_MCODE.i"
always @( posedge CLK ) mcode <= MCODE_S5(OPCODE);
endmodule

module HD63701_MCROM_S6( input CLK, input [7:0] OPCODE, output reg `mcwidth mcode );
`include "HD63701_MCODE.i"
always @( posedge CLK ) mcode <= MCODE_S6(OPCODE);
endmodule

module HD63701_MCROM_S7( input CLK, input [7:0] OPCODE, output reg `mcwidth mcode );
`include "HD63701_MCODE.i"
always @( posedge CLK ) mcode <= MCODE_S7(OPCODE);
endmodule

module HD63701_MCROM_S8( input CLK, input [7:0] OPCODE, output reg `mcwidth mcode );
`include "HD63701_MCODE.i"
always @( posedge CLK ) mcode <= MCODE_S8(OPCODE);
endmodule

module HD63701_MCROM_S9( input CLK, input [7:0] OPCODE, output reg `mcwidth mcode );
`include "HD63701_MCODE.i"
always @( posedge CLK ) mcode <= MCODE_S9(OPCODE);
endmodule

167 changes: 167 additions & 0 deletions HD63701_SEQ.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/***************************************************************************
This file is part of "HD63701V0 Compatible Processor Core".
****************************************************************************/
`timescale 1ps / 1ps

`include "HD63701_defs.i"

module HD63701_SEQ
(
input CLK,
input RST,

input NMI,
input IRQ,

input IRQ2,
input [3:0] IRQ2V,

input [7:0] DI,

output `mcwidth mcout,
input [7:0] vect,
input inte,
output fncu,

output [5:0] PH
);

`define MC_SEI {`mcSCB, `bfI ,`mcrC,`mcpN,`amPC,`pcN}
`define MC_YLD {`mcNOP,`mcrn,`mcrn,`mcrn,`mcpK,`amPC,`pcN}

reg [7:0] opcode;
reg `mcwidth mcode;
reg mcside;


reg pNMI, pIRQ, pIR2;

reg [2:0] fINT;
wire bIRQ = fINT[1] & inte;
wire bIRQ2 = fINT[0] & inte;

wire bINT = fINT[2]|bIRQ|bIRQ2;
wire [7:0] vINT = fINT[2] ? `vaNMI :
bIRQ ? `vaIRQ :
bIRQ2 ? {4'hF,IRQ2V} :
0;

function [2:0] INTUpd;
input [2:0] n;
case(n)
3'b000: INTUpd = 3'b000;
3'b001: INTUpd = 3'b000;
3'b010: INTUpd = 3'b000;
3'b011: INTUpd = 3'b001;
3'b100: INTUpd = 3'b000;
3'b101: INTUpd = 3'b001;
3'b110: INTUpd = 3'b010;
3'b111: INTUpd = 3'b011;
endcase
endfunction


reg [5:0] PHASE;
always @( posedge CLK or posedge RST ) begin
if (RST) begin
fINT <= 0;
pIRQ <= 0;
pNMI <= 0;
pIR2 <= 0;

opcode <= 0;
mcode <= 0;
mcside <= 0;
end
else begin

// Capture Interrupt signal edge
if ((pNMI^NMI)&NMI) fINT[2] <= 1'b1; pNMI <= NMI;
if ((pIRQ^IRQ)&IRQ) fINT[1] <= 1'b1; pIRQ <= IRQ;
if ((pIR2^IRQ2)&IRQ2) fINT[0] <= 1'b1; pIR2 <= IRQ2;


case (PHASE)

// Reset
`phRST : mcside <= 1;

// Load Vector
`phVECT: mcside <= 1;

// Execute
`phEXEC: begin
opcode <= DI;
if ( bINT & (opcode[7:1]!=7'b0000111) ) begin
mcside <= 0;
mcode <= {`mcINT,vINT,`mcrn,`mcpI,`amPC,`pcN};
fINT <= INTUpd(fINT);
end
else mcside <= 1;
end

// Interrupt (TRAP/IRQ/NMI/SWI/WAI)
`phINTR: mcside <= 1;
`phINTR8: begin
mcside <= 0;
if (vect==`vaWAI) begin
if (bINT) begin
mcode <= `MC_SEI;
opcode <= vINT;
fINT <= INTUpd(fINT);
end
else mcode <= `MC_YLD;
end
else begin
opcode <= vect;
mcode <= `MC_SEI;
end
end
`phINTR9: mcode <= {`mcLDV, opcode,`mcrn,`mcpV,`amE0,`pcN}; //(Load Vector)

// Sleep
`phSLEP: begin
mcside <= 0;
if (bINT) begin
mcode <= {`mcINT,vINT,`mcrn,`mcpI,`amPC,`pcN};
fINT <= INTUpd(fINT);
end
else mcode <= `MC_YLD;
end

// HALT (Bug in MicroCode)
`phHALT: $stop;

default:;
endcase
end
end

// Update Phase
wire [2:0] mcph = mcout[6:4];
always @( negedge CLK or posedge RST ) begin
if (RST) PHASE <= 0;
else begin
case (mcph)
`mcpN: PHASE <= PHASE+6'h1;
`mcp0: PHASE <=`phEXEC;
`mcpI: PHASE <=`phINTR;
`mcpV: PHASE <=`phVECT;
`mcpH: PHASE <=`phHALT;
`mcpS: PHASE <=`phSLEP;
default: PHASE <= PHASE;
endcase
end
end
assign PH = PHASE;

// Output MicroCode
wire `mcwidth mcoder;
HD63701_MCROM mcr( CLK, PHASE, (PHASE==`phEXEC) ? DI : opcode, mcoder );
assign mcout = mcside ? mcoder : mcode;

assign fncu = ( opcode[7:4]==4'h2)|
((opcode[7:4]==4'h3)&(opcode[3:0]!=4'hD));

endmodule

155 changes: 155 additions & 0 deletions HD63701_defs.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/***************************************************************************
This file is part of "HD63701V0 Compatible Processor Core".
( DON'T ADD TO PROJECT, Because this file is include file. )
****************************************************************************/
`define vaRST 8'hFE // RESET Vector $FFFE
`define vaTRP 8'hEE // TRAP Vector $FFEE
`define vaNMI 8'hFC // NMI Vector $FFFC (NMI signal)
`define vaSWI 8'hFA // SWI Vector $FFFA (Software Interrupt)
`define vaIRQ 8'hF8 // IRQ Vector $FFF8 (IRQ signal)
`define vaICF 8'hF6 // ICF Vector $FFF6 (Timer Input Capture)
`define vaOCF 8'hF4 // OCF Vector $FFF4 (Timer Output Compare)
`define vaTOF 8'hF2 // TOF Vector $FFF2 (Timer OverFlow)
`define vaSCI 8'hF0 // SCI Vector $FFF0 (Serial)
`define vaWAI 8'h00 // WAI Vector (Special)


`define phRST 0
//------------------
`define phVECT 1
`define phVEC1 2
`define phVEC2 3
//------------------
`define phEXEC 16
`define phEXEC1 17
`define phEXEC2 18
`define phEXEC3 19
`define phEXEC4 20
`define phEXEC5 21
`define phEXEC6 22
`define phEXEC7 23
`define phEXEC8 24
`define phEXEC9 25
//------------------
`define phINTR 32
`define phINTR1 33
`define phINTR2 34
`define phINTR3 35
`define phINTR4 36
`define phINTR5 37
`define phINTR6 38
`define phINTR7 39
`define phINTR8 40
`define phINTR9 41
//------------------
`define phSLEP 62
`define phHALT 63


`define mcNOP `mcLDN
`define mcLDN 5'd0
`define mcINC 5'd1
`define mcADD 5'd2
`define mcADC 5'd3
`define mcDEC 5'd4
`define mcSUB 5'd5
`define mcSBC 5'd6
`define mcMUL 5'd7
`define mcNEG 5'd8
`define mcNOT 5'd9
`define mcAND 5'd10
`define mcLOR 5'd11
`define mcEOR 5'd12
`define mcASL 5'd13
`define mcASR 5'd14
`define mcLSR 5'd15
`define mcROL 5'd16
`define mcROR 5'd17
`define mcCCB 5'd18
`define mcSCB 5'd19
`define mcLDR 5'd20
`define mcTST 5'd21
//---------------------
`define mcINT 5'd25
`define mcPSH 5'd26
`define mcPUL 5'd27
`define mcXTD 5'd28
`define mcDAA 5'd29
`define mcAPC 5'd30
`define mcLDV 5'd31


// [2] : 0=byte,1=word
`define mcrn 4'd0 // none
`define mcrA 4'd1
`define mcrB 4'd2
`define mcrC 4'd3

`define mcrD 4'd4 // {A,B}
`define mcrX 4'd5
`define mcrS 4'd6
`define mcrP 4'd7

`define mcrU 4'd8
`define mcrV 4'd9
`define mcrN 4'd10 // x.H <-> (rE)
`define mcrM 4'd11 // x.L <-> (rE)

`define mcrT 4'd12 // {U,V} Temporary
`define mcrE 4'd13 // Effective Address
`define mcrI 4'd14 // Immidiate
//---------------------


`define mcpK 3'd0 // Keep
`define mcpN 3'd1 // Next
`define mcp0 3'd2 // To Stage0
`define mcpI 3'd3 // To Interrupt
`define mcpV 3'd4 // To Vector
//------------------------------------------
`define mcpH 3'd6 // To HALT
`define mcpS 3'd7 // To SLEEP


`define amPC 3'd0
`define amP1 3'd1
`define amSP 3'd2
`define amS1 3'd3
`define amX0 3'd4
`define amXT 3'd5
`define amE0 3'd6
`define amE1 3'd7


`define pcN 1'b0 // PC=PC
`define pcI 1'b1 // PC=PC+1


// +- N^V
// |
`define bfRA 8'b00000000
`define bfRN 8'b10000000
`define bfHI 8'b00000101
`define bfLS 8'b10000101
`define bfCC 8'b00000001
`define bfCS 8'b10000001
`define bfNE 8'b00000100
`define bfEQ 8'b10000100
`define bfVC 8'b00000010
`define bfVS 8'b10000010
`define bfPL 8'b00001000
`define bfMI 8'b10001000
`define bfGE 8'b01000000
`define bfLT 8'b11000000
`define bfGT 8'b01000100
`define bfLE 8'b11000100

`define bfC 8'b00000001
`define bfV 8'b00000010
`define bfZ 8'b00000100
`define bfN 8'b00001000
`define bfI 8'b00010000
`define bfH 8'b00100000


`define mcwidth [23:0]
1,028 changes: 1,028 additions & 0 deletions mcode.txt

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions mkmc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
./mkmcode > HD63701_MCODE.i

153 changes: 153 additions & 0 deletions mkmcode
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#!/usr/bin/ruby
#-------------------------------------------------------------------------
# MicroCode source generator for "HD63701 Compatible Processor Core"
#-------------------------------------------------------------------------
def deepcopy(obj)
Marshal.load(Marshal.dump(obj))
end

def line_split(text)

if (text == nil) then return nil end

t = text.split(nil)
s = Array.new
for n in 0..(t.length-1) do
cs = t[n].split(//)
if (cs[0]=="\"") then
s[n] = text.slice(/\".+\"/)
break
else
s[n] = t[n]
end
end
return s
end

def parser(inname)

$parsed = Array.new

nowop = -1;
rawout = 0;

open(inname){|infile|
while !infile.eof? do
rtext = infile.gets
text = rtext.strip
chrs = text.split(//)

if (chrs[0] == "%") then
rawout = rawout^1
next
end
if (rawout != 0) then
print rtext
next
end

if (chrs[0] == "#") then next end

words = line_split(text)
if (chrs[0] == "$") then
nowop = (chrs[1]+chrs[2]).hex
$parsed[nowop] = Array.new
$parsed[nowop][0] = words
else
if (words.length > 0) then $parsed[nowop] << words end
end
end
}
end

def get_maxstage

n = 0;
$parsed.each{|opc|
if (opc == nil) then next end
if (n < opc.length) then n = opc.length end
}
return n-1
end


def out_stage_header(stage)

printf("\nfunction `mcwidth MCODE_S%d;\n", stage-1);
printf("input [7:0] opc;\n");
printf("begin\n")
printf("\tcase (opc)\n");
end

def out_stage_mc_sub(stage,opcode,nemonic,mcode)

if (mcode == nil) then return 0 end

printf("\t\t8'h%s: MCODE_S%d = ", opcode[1,2], stage-1)
if ((mcode[0].split(//))[0] == "\"") then
raw = (mcode[0])[1..((mcode[0]).length-2)]
if ( raw.length > 16 ) then
printf("%s;\t\t// %s\n", raw, nemonic);
else
printf("%s;\t\t\t\t\t\t\t\t\t\t\t\t\t// %s\n", raw, nemonic);
end
else
mrs = mcode[1].split(//)
printf("{\`mc%s,\`mcr%s,\`mcr%s,\`mcr%s,\`mcp%s,\`am%s,\`pc%s};\t\t// %s\n",
mcode[0], mrs[0], mrs[1], mrs[2], mcode[2], mcode[3], mcode[4], nemonic)
end
return 1
end

def out_stage_mc(stage,parsed_op)

if (parsed_op == nil) then return 0 end

if (stage == 1 && parsed_op[0].length > 2) then
mcode = deepcopy( parsed_op[0] )
2.times{ mcode.shift }
else
mcode = parsed_op[stage]
end

return out_stage_mc_sub(stage,parsed_op[0][0],parsed_op[0][1],mcode)
end

def out_stage_footer(stage)

printf("\t default: MCODE_S%d = `MC_%s;\n", stage-1, (stage>1) ? "HALT" : "TRAP" )
printf("\tendcase\n")
printf("end\n")
printf("endfunction\n\n");
end

def generate_stage_mcode(stage)

separator = "//-----------------------------------------------------------------------------------------\n"
flg = 1

out_stage_header(stage)
for op in 0x00..0xFF do
if (op % 16 == 0 && flg != 0) then
printf(separator)
flg = 0
end
flg |= out_stage_mc(stage,$parsed[op])
end
if (flg != 0) then printf(separator) end
out_stage_footer(stage)
end

def generate_mcode
stages = get_maxstage
for stage in 1..stages do generate_stage_mcode(stage) end
printf("\n")
end


def doit
parser("mcode.txt")
generate_mcode
end

doit

0 comments on commit a97c732

Please sign in to comment.