Line 1... |
Line 1... |
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
// ============================================================================
|
// ============================================================================
|
// __
|
// __
|
// \\__/ o\ (C) 2013 Robert Finch, Stratford
|
// \\__/ o\ (C) 2013, 2014 Robert Finch, Stratford
|
// \ __ / All rights reserved.
|
// \ __ / All rights reserved.
|
// \/_// robfinch<remove>@opencores.org
|
// \/_// robfinch<remove>@opencores.org
|
// ||
|
// ||
|
//
|
//
|
// rtf65002.v
|
// rtf65002.v
|
Line 60... |
Line 60... |
parameter LOAD_IBUF3 = 6'd30;
|
parameter LOAD_IBUF3 = 6'd30;
|
parameter ICACHE1 = 6'd31;
|
parameter ICACHE1 = 6'd31;
|
parameter IBUF1 = 6'd32;
|
parameter IBUF1 = 6'd32;
|
parameter DCACHE1 = 6'd33;
|
parameter DCACHE1 = 6'd33;
|
parameter CMPS1 = 6'd34;
|
parameter CMPS1 = 6'd34;
|
|
parameter HALF_CALC = 6'd35;
|
|
parameter MVN816 = 6'd36;
|
|
|
|
parameter SPIN_CYCLES = 8'd30;
|
|
|
input rst_md; // reset mode, 1=emulation mode, 0=native mode
|
input rst_md; // reset mode, 1=emulation mode, 0=native mode
|
input rst_i;
|
input rst_i;
|
input clk_i;
|
input clk_i;
|
input nmi_i;
|
input nmi_i;
|
Line 99... |
Line 103... |
reg ttrig; // trace trigger
|
reg ttrig; // trace trigger
|
reg em1;
|
reg em1;
|
reg gie; // global interrupt enable (set when sp is loaded)
|
reg gie; // global interrupt enable (set when sp is loaded)
|
reg hwi; // hardware interrupt indicator
|
reg hwi; // hardware interrupt indicator
|
reg nmoi; // native mode on interrupt
|
reg nmoi; // native mode on interrupt
|
wire [31:0] sr = {nf,vf,em,tf,23'b0,bf,df,im,zf,cf};
|
wire [31:0] sr = {nf,vf,em,tf,17'b0,m816,m_bit,x_bit,3'b0,bf,df,im,zf,cf};
|
wire [7:0] sr8 = {nf,vf,1'b0,bf,df,im,zf,cf};
|
reg m_bit; // acc/mem is 16 bit
|
|
reg x_bit; // index regs are 16 bit
|
|
reg m816; // 816 mode
|
|
wire m16 = m816 & ~m_bit;
|
|
wire xb16 = m816 & ~x_bit;
|
|
wire [7:0] sr8 = m816 ? {nf,vf,m_bit,x_bit,df,im,zf,cf} : {nf,vf,1'b0,bf,df,im,zf,cf};
|
reg nmi1,nmi_edge;
|
reg nmi1,nmi_edge;
|
reg wai;
|
reg wai;
|
|
reg spi; // spinlock interrupt
|
|
reg [7:0] spi_cnt;
|
reg wrrf; // write register file
|
reg wrrf; // write register file
|
reg [31:0] acc;
|
reg [31:0] acc;
|
reg [31:0] x;
|
reg [31:0] x;
|
reg [31:0] y;
|
reg [31:0] y;
|
reg [7:0] sp;
|
reg [15:0] sp;
|
|
reg [15:0] dpr; // direct page register
|
|
reg [7:0] dbr; // data bank register
|
reg [31:0] spage; // stack page
|
reg [31:0] spage; // stack page
|
wire [7:0] acc8 = acc[7:0];
|
wire [7:0] acc8 = acc[7:0];
|
wire [7:0] x8 = x[7:0];
|
wire [7:0] x8 = x[7:0];
|
wire [7:0] y8 = y[7:0];
|
wire [7:0] y8 = y[7:0];
|
|
wire [15:0] acc16 = acc[15:0];
|
|
wire [15:0] x16 = x[15:0];
|
|
wire [15:0] y16 = y[15:0];
|
|
wire [31:0] x_dec = x - 32'd1;
|
|
wire [31:0] x_inc = x + 32'd1;
|
|
wire [31:0] y_dec = y - 32'd1;
|
|
wire [31:0] y_inc = y + 32'd1;
|
|
wire [31:0] acc_dec = acc - 32'd1;
|
|
wire [31:0] acc_inc = acc + 32'd1;
|
reg [31:0] isp; // interrupt stack pointer
|
reg [31:0] isp; // interrupt stack pointer
|
reg [31:0] oisp; // original isp for bus retry
|
reg [31:0] oisp; // original isp for bus retry
|
wire [63:0] prod;
|
wire [63:0] prod;
|
|
reg [15:0] tmp16;
|
wire [31:0] q,r;
|
wire [31:0] q,r;
|
reg [31:0] tick;
|
reg [31:0] tick;
|
wire [7:0] sp_dec = sp - 8'd1;
|
wire [15:0] sp_dec = sp - 16'd1;
|
wire [7:0] sp_inc = sp + 8'd1;
|
wire [15:0] sp_inc = sp + 16'd1;
|
|
wire [15:0] sp_dec2 = sp - 16'd2;
|
wire [31:0] isp_dec = isp - 32'd1;
|
wire [31:0] isp_dec = isp - 32'd1;
|
wire [31:0] isp_inc = isp + 32'd1;
|
wire [31:0] isp_inc = isp + 32'd1;
|
reg [3:0] suppress_pcinc;
|
reg [3:0] suppress_pcinc;
|
reg [31:0] pc;
|
reg [31:0] pc;
|
reg [31:0] opc;
|
reg [31:0] opc;
|
wire [3:0] pc_inc;
|
wire [3:0] pc_inc;
|
|
reg [3:0] pc_inc2;
|
wire [3:0] pc_inc8;
|
wire [3:0] pc_inc8;
|
wire [31:0] pcp2 = pc + (32'd2 & suppress_pcinc); // for branches
|
wire [31:0] pcp2 = pc + (32'd2 & suppress_pcinc); // for branches
|
wire [31:0] pcp4 = pc + (32'd4 & suppress_pcinc); // for branches
|
wire [31:0] pcp4 = pc + (32'd4 & suppress_pcinc); // for branches
|
wire [31:0] pcp8 = pc + 32'd8; // cache controller needs this
|
wire [31:0] pcp8 = pc + 32'd8; // cache controller needs this
|
reg [31:0] abs8; // 8 bit mode absolute address register
|
reg [31:0] abs8; // 8 bit mode absolute address register
|
Line 160... |
Line 185... |
default: rfob <= regfile[Rb];
|
default: rfob <= regfile[Rb];
|
endcase
|
endcase
|
reg [3:0] Rt;
|
reg [3:0] Rt;
|
reg [33:0] ea;
|
reg [33:0] ea;
|
reg first_ifetch;
|
reg first_ifetch;
|
|
reg [5:0] ic_whence;
|
reg [31:0] lfsr;
|
reg [31:0] lfsr;
|
wire lfsr_fb;
|
wire lfsr_fb;
|
xnor(lfsr_fb,lfsr[0],lfsr[1],lfsr[21],lfsr[31]);
|
xnor(lfsr_fb,lfsr[0],lfsr[1],lfsr[21],lfsr[31]);
|
reg [31:0] a, b;
|
reg [31:0] a, b;
|
wire signed [31:0] as = a;
|
wire signed [31:0] as = a;
|
Line 171... |
Line 197... |
wire lt = as < bs;
|
wire lt = as < bs;
|
wire eq = a==b;
|
wire eq = a==b;
|
wire ltu = a < b;
|
wire ltu = a < b;
|
|
|
reg [7:0] b8;
|
reg [7:0] b8;
|
|
reg [15:0] b16;
|
wire [32:0] alu_out;
|
wire [32:0] alu_out;
|
reg [32:0] res;
|
reg [32:0] res;
|
|
reg [16:0] res16;
|
reg [8:0] res8;
|
reg [8:0] res8;
|
wire resv8,resv32;
|
wire resv8,resv16,resv32;
|
wire resc8 = res8[8];
|
wire resc8 = res8[8];
|
|
wire resc16 = res16[16];
|
wire resc32 = res[32];
|
wire resc32 = res[32];
|
wire resz8 = res8[7:0]==8'h00;
|
wire resz8 = ~|res8[7:0];
|
wire resz32 = res[31:0]==32'd0;
|
wire resz16 = ~|res16[15:0];
|
|
wire resz32 = ~|res[31:0];
|
wire resn8 = res8[7];
|
wire resn8 = res8[7];
|
|
wire resn16 = res16[15];
|
wire resn32 = res[31];
|
wire resn32 = res[31];
|
|
|
reg [33:0] vect;
|
reg [33:0] vect;
|
reg [31:0] ia; // temporary reg to hold indirect address
|
reg [31:0] ia; // temporary reg to hold indirect address
|
reg isInsnCacheLoad;
|
reg isInsnCacheLoad;
|
Line 242... |
Line 273... |
reg hist_capture;
|
reg hist_capture;
|
`endif
|
`endif
|
|
|
reg isBusErr;
|
reg isBusErr;
|
reg isBrk,isMove,isSts;
|
reg isBrk,isMove,isSts;
|
|
reg isMove816;
|
reg isRTI,isRTL,isRTS;
|
reg isRTI,isRTL,isRTS;
|
reg isOrb,isStb;
|
reg isOrb,isStb;
|
reg isRMW;
|
reg isRMW;
|
reg isSub,isSub8;
|
reg isSub,isSub8;
|
reg isJsrIndx,isJsrInd;
|
reg isJsrIndx,isJsrInd;
|
Line 310... |
Line 342... |
wire isAtni = 1'b0;
|
wire isAtni = 1'b0;
|
`endif
|
`endif
|
wire md_done;
|
wire md_done;
|
wire clk;
|
wire clk;
|
reg isIY;
|
reg isIY;
|
|
reg isIY24;
|
|
reg isI24;
|
|
|
rtf65002_pcinc upci1
|
rtf65002_pcinc upci1
|
(
|
(
|
.opcode(ir9),
|
.opcode(ir9),
|
.suppress_pcinc(suppress_pcinc),
|
.suppress_pcinc(suppress_pcinc),
|
Line 322... |
Line 356... |
|
|
rtf65002_pcinc8 upci2
|
rtf65002_pcinc8 upci2
|
(
|
(
|
.opcode(ir[7:0]),
|
.opcode(ir[7:0]),
|
.suppress_pcinc(suppress_pcinc),
|
.suppress_pcinc(suppress_pcinc),
|
.inc(pc_inc8)
|
.inc(pc_inc8),
|
|
.m16(m16),
|
|
.xb16(xb16)
|
);
|
);
|
|
|
mult_div umd1
|
mult_div umd1
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
Line 477... |
Line 513... |
.b(b8[7]),
|
.b(b8[7]),
|
.s(res8[7]),
|
.s(res8[7]),
|
.v(resv8)
|
.v(resv8)
|
);
|
);
|
|
|
wire [7:0] bcaio;
|
wire [15:0] bcaio;
|
wire [7:0] bcao;
|
wire [15:0] bcao;
|
wire [7:0] bcsio;
|
wire [15:0] bcsio;
|
wire [7:0] bcso;
|
wire [15:0] bcso;
|
wire bcaico,bcaco,bcsico,bcsco;
|
wire bcaico,bcaco,bcsico,bcsco;
|
|
wire bcaico8,bcaco8,bcsico8,bcsco8;
|
|
|
`ifdef SUPPORT_BCD
|
`ifdef SUPPORT_BCD
|
BCDAdd ubcdai1 (.ci(cf),.a(acc8),.b(ir[15:8]),.o(bcaio),.c(bcaico));
|
BCDAdd4 ubcdai1 (.ci(cf),.a(acc16),.b(ir[23:8]),.o(bcaio),.c(bcaico),.c8(bcaico8));
|
BCDAdd ubcda2 (.ci(cf),.a(acc8),.b(b8),.o(bcao),.c(bcaco));
|
BCDAdd4 ubcda2 (.ci(cf),.a(acc16),.b(b8),.o(bcao),.c(bcaco),.c8(bcaco8));
|
BCDSub ubcdsi1 (.ci(cf),.a(acc8),.b(ir[15:8]),.o(bcsio),.c(bcsico));
|
BCDSub4 ubcdsi1 (.ci(cf),.a(acc16),.b(ir[23:8]),.o(bcsio),.c(bcsico),.c8(bcsico8));
|
BCDSub ubcds2 (.ci(cf),.a(acc8),.b(b8),.o(bcso),.c(bcsco));
|
BCDSub4 ubcds2 (.ci(cf),.a(acc16),.b(b8),.o(bcso),.c(bcsco),.c8(bcsco8));
|
`endif
|
`endif
|
|
|
reg [7:0] dati;
|
reg [7:0] dati;
|
always @(radr2LSB or dat_i)
|
always @(radr2LSB or dat_i)
|
case(radr2LSB)
|
case(radr2LSB)
|
Line 533... |
Line 570... |
`BGT: takb <= (nf & vf & !zf) + (!nf & !vf & !zf);
|
`BGT: takb <= (nf & vf & !zf) + (!nf & !vf & !zf);
|
`BLE: takb <= zf | (nf & !vf)|(!nf & vf);
|
`BLE: takb <= zf | (nf & !vf)|(!nf & vf);
|
default: takb <= 1'b0;
|
default: takb <= 1'b0;
|
endcase
|
endcase
|
|
|
wire [31:0] iapy8 = ia + y8; // Don't add in abs8, already included with ia
|
wire [31:0] mvnsrc_address = {abs8[31:24],ir[23:16],x16};
|
wire [31:0] zp_address = {abs8[31:16],8'h00,ir[15:8]};
|
wire [31:0] mvndst_address = {abs8[31:24],ir[15: 8],y16};
|
wire [31:0] zpx_address = {abs8[31:16],8'h00,ir[15:8]} + x8;
|
wire [31:0] iapy8 = ia + y16; // Don't add in abs8, already included with ia
|
wire [31:0] zpy_address = {abs8[31:16],8'h00,ir[15:8]} + y8;
|
wire [31:0] zp_address = {abs8[31:16],8'h00,ir[15:8]} + dpr;
|
wire [31:0] abs_address = {abs8[31:16],ir[23:8]};
|
wire [31:0] zpx_address = {abs8[31:16],{8'h00,ir[15:8]} + x16} + dpr;
|
wire [31:0] absx_address = {abs8[31:16],ir[23:8] + {8'h0,x8}}; // simulates 64k bank wrap-around
|
wire [31:0] zpy_address = {abs8[31:16],{8'h00,ir[15:8]} + y16} + dpr;
|
wire [31:0] absy_address = {abs8[31:16],ir[23:8] + {8'h0,y8}};
|
wire [31:0] abs_address = {abs8[31:24],dbr,ir[23:8]};
|
|
wire [31:0] absx_address = {abs8[31:24],dbr,ir[23:8] + x16}; // simulates 64k bank wrap-around
|
|
wire [31:0] absy_address = {abs8[31:24],dbr,ir[23:8] + y16};
|
|
wire [31:0] al_address = {abs8[31:24],ir[31:8]};
|
|
wire [31:0] alx_address = {abs8[31:24],ir[31:8] + x16};
|
wire [31:0] zpx32xy_address = ir[23:12] + rfoa;
|
wire [31:0] zpx32xy_address = ir[23:12] + rfoa;
|
wire [31:0] absx32xy_address = ir[47:16] + rfob;
|
wire [31:0] absx32xy_address = ir[47:16] + rfob;
|
wire [31:0] zpx32_address = ir[31:20] + rfob;
|
wire [31:0] zpx32_address = ir[31:20] + rfob;
|
wire [31:0] absx32_address = ir[55:24] + rfob;
|
wire [31:0] absx32_address = ir[55:24] + rfob;
|
|
|
|
wire [31:0] dsp_address = m816 ? {abs8[31:24],8'h00,sp + ir[15:8]} : {abs8[31:16],8'h01,sp[7:0]+ir[15:8]};
|
|
|
rtf65002_alu ualu1
|
rtf65002_alu ualu1
|
(
|
(
|
.clk(clk),
|
.clk(clk),
|
.state(state),
|
.state(state),
|
.resin(res),
|
.resin(res),
|
Line 617... |
Line 660... |
sel_o <= 4'h0;
|
sel_o <= 4'h0;
|
adr_o <= 34'd0;
|
adr_o <= 34'd0;
|
dat_o <= 32'd0;
|
dat_o <= 32'd0;
|
nmi_edge <= 1'b0;
|
nmi_edge <= 1'b0;
|
wai <= 1'b0;
|
wai <= 1'b0;
|
|
spi <= 1'b0;
|
|
spi_cnt <= SPIN_CYCLES;
|
cf <= 1'b0;
|
cf <= 1'b0;
|
ir <= 64'hEAEAEAEAEAEAEAEA;
|
ir <= 64'hEAEAEAEAEAEAEAEA;
|
imiss <= `FALSE;
|
imiss <= `FALSE;
|
dmiss <= `FALSE;
|
dmiss <= `FALSE;
|
dcacheOn <= 1'b0;
|
dcacheOn <= 1'b0;
|
icacheOn <= 1'b1;
|
icacheOn <= 1'b1;
|
write_allocate <= 1'b0;
|
write_allocate <= 1'b0;
|
nmoi <= 1'b1;
|
nmoi <= 1'b1;
|
state <= RESET1;
|
state <= RESET1;
|
|
m816 <= 1'b0;
|
|
m_bit <= 1'b1;
|
|
x_bit <= 1'b1;
|
if (rst_md) begin
|
if (rst_md) begin
|
pc <= 32'h0000FFF0; // set high-order pc to zero
|
pc <= 32'h0000FFF0; // set high-order pc to zero
|
vect <= `BYTE_RST_VECT;
|
vect <= `BYTE_RST_VECT;
|
em <= 1'b1;
|
em <= 1'b1;
|
end
|
end
|
Line 638... |
Line 686... |
em <= 1'b0;
|
em <= 1'b0;
|
pc <= 32'hFFFFFFF0;
|
pc <= 32'hFFFFFFF0;
|
end
|
end
|
suppress_pcinc <= 4'hF;
|
suppress_pcinc <= 4'hF;
|
exbuf <= 64'd0;
|
exbuf <= 64'd0;
|
|
dbr <= 8'h00;
|
|
dpr <= 16'h0000;
|
spage <= 32'h00000100;
|
spage <= 32'h00000100;
|
bufadr <= 32'd0;
|
bufadr <= 32'd0;
|
abs8 <= 32'd0;
|
abs8 <= 32'd0;
|
clk_en <= 1'b1;
|
clk_en <= 1'b1;
|
isCacheReset <= `TRUE;
|
isCacheReset <= `TRUE;
|
gie <= 1'b0;
|
gie <= 1'b0;
|
tick <= 32'd0;
|
tick <= 32'd0;
|
isIY <= 1'b0;
|
isIY <= 1'b0;
|
|
isIY24 <= 1'b0;
|
|
isI24 <= `FALSE;
|
load_what <= `NOTHING;
|
load_what <= `NOTHING;
|
`ifdef DEBUG
|
`ifdef DEBUG
|
hist_capture <= `TRUE;
|
hist_capture <= `TRUE;
|
history_ndx <= 6'd0;
|
history_ndx <= 6'd0;
|
`endif
|
`endif
|
Line 689... |
Line 741... |
`include "ifetch.v"
|
`include "ifetch.v"
|
`ifdef SUPPORT_EM8
|
`ifdef SUPPORT_EM8
|
`include "byte_ifetch.v"
|
`include "byte_ifetch.v"
|
`include "byte_decode.v"
|
`include "byte_decode.v"
|
`include "byte_calc.v"
|
`include "byte_calc.v"
|
|
`ifdef SUPPORT_816
|
|
`include "half_calc.v"
|
|
`endif
|
`endif
|
`endif
|
|
|
`include "load_mac.v"
|
`include "load_mac.v"
|
`include "store.v"
|
`include "store.v"
|
|
|
Line 742... |
Line 797... |
isp <= isp_dec;
|
isp <= isp_dec;
|
store_what <= `STW_OPC;
|
store_what <= `STW_OPC;
|
vect <= {vbr[31:9],intno,2'b00};
|
vect <= {vbr[31:9],intno,2'b00};
|
hwi <= `TRUE;
|
hwi <= `TRUE;
|
isBusErr <= `TRUE;
|
isBusErr <= `TRUE;
|
state <= STORE1;
|
next_state(STORE1);
|
end
|
end
|
`endif
|
`endif
|
|
|
`include "rtf65002_string.v"
|
`include "rtf65002_string.v"
|
`include "cache_controller.v"
|
`include "cache_controller.v"
|
Line 768... |
Line 823... |
|
|
`include "decode.v"
|
`include "decode.v"
|
`include "calc.v"
|
`include "calc.v"
|
`include "load_tsk.v"
|
`include "load_tsk.v"
|
`include "wb_task.v"
|
`include "wb_task.v"
|
|
`include "misc_task.v"
|
|
|
task next_state;
|
task next_state;
|
input [5:0] nxt;
|
input [5:0] nxt;
|
begin
|
begin
|
state <= nxt;
|
state <= nxt;
|
Line 812... |
Line 868... |
LOAD_IBUF3: fnStateName = "LOAD_IBUF3 ";
|
LOAD_IBUF3: fnStateName = "LOAD_IBUF3 ";
|
ICACHE1: fnStateName = "ICACHE1 ";
|
ICACHE1: fnStateName = "ICACHE1 ";
|
IBUF1: fnStateName = "IBUF1 ";
|
IBUF1: fnStateName = "IBUF1 ";
|
DCACHE1: fnStateName = "DCACHE1 ";
|
DCACHE1: fnStateName = "DCACHE1 ";
|
CMPS1: fnStateName = "CMPS1 ";
|
CMPS1: fnStateName = "CMPS1 ";
|
|
HALF_CALC: fnStateName = "HALF_CALC ";
|
default: fnStateName = "UNKNOWN ";
|
default: fnStateName = "UNKNOWN ";
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
endmodule
|
endmodule
|