URL
https://opencores.org/ocsvn/rtf65002/rtf65002/trunk
Subversion Repositories rtf65002
Compare Revisions
- This comparison shows the changes necessary to convert path
/rtf65002/trunk
- from Rev 34 to Rev 35
- ↔ Reverse comparison
Rev 34 → Rev 35
/rtl/verilog/rtf65002_defines.v
24,9 → 24,14
// |
// ============================================================================ |
// |
`ifndef RTF65002_DEFINES |
`define RTF65002_DEFINES 1'b1 |
|
`define TRUE 1'b1 |
`define FALSE 1'b0 |
|
`define DEBUG 1'b1 |
|
`define SUPPORT_ICACHE 1'b1 |
`define ICACHE_4K 1'b1 |
//`define ICACHE_16K 1'b1 |
410,8 → 415,9
`define STS 9'h64 |
`define EXEC 9'hEB |
`define ATNI 9'h4B |
`define MDR 9'h3C |
|
// Page Two Oproces |
// Page Two Opcodes |
`define PG2 9'h42 |
|
`define TOFF 9'h118 |
471,12 → 477,11
`define STW_SR 6'd7 |
`define STW_RFA 6'd8 |
`define STW_RFA8 6'd9 |
`define STW_RFA 6'd10 |
`define STW_RFA8 6'd11 |
`define STW_A 6'd12 |
`define STW_B 6'd13 |
`define STW_CALC 6'd14 |
`define STW_OPC 6'd15 |
`define STW_A 6'd10 |
`define STW_B 6'd11 |
`define STW_CALC 6'd12 |
`define STW_OPC 6'd13 |
|
`define STW_ACC8 6'd16 |
`define STW_X8 6'd17 |
`define STW_Y8 6'd18 |
486,3 → 491,6
`define STW_PC70 6'd22 |
`define STW_SR70 6'd23 |
`define STW_Z8 6'd24 |
`define STW_DEF8 6'd25 |
|
`endif |
/rtl/verilog/byte_ifetch.v
23,6 → 23,7
BYTE_IFETCH: |
begin |
vect <= `BYTE_IRQ_VECT; |
vect[31:16] <= abs8[31:16]; |
suppress_pcinc <= 4'hF; // default: no suppression of increment |
opc <= pc; |
hwi <= `FALSE; |
29,7 → 30,7
isBusErr <= `FALSE; |
pg2 <= `FALSE; |
store_what <= `STW_DEF; |
if (nmi_edge & gie) begin // imiss indicates cache controller is active and this state is in a waiting loop |
if (nmi_edge & gie) begin |
ir[7:0] <= `BRK; |
nmi_edge <= 1'b0; |
wai <= 1'b0; |
36,11 → 37,12
hwi <= `TRUE; |
if (nmoi) begin |
vect <= `NMI_VECT; |
state <= DECODE; |
next_state(DECODE); |
end |
else begin |
vect <= `BYTE_NMI_VECT; |
state <= BYTE_DECODE; |
vect[31:16] <= abs8[31:16]; |
next_state(BYTE_DECODE); |
end |
end |
else if (irq_i & gie) begin |
49,7 → 51,7
if (unCachedInsn) begin |
if (bhit) begin |
ir <= ibuf; |
state <= BYTE_DECODE; |
next_state(BYTE_DECODE); |
end |
else |
state <= LOAD_IBUF1; |
57,7 → 59,7
else begin |
if (ihit) begin |
ir <= insn; |
state <= BYTE_DECODE; |
next_state(BYTE_DECODE); |
end |
else |
state <= ICACHE1; |
68,10 → 70,10
hwi <= `TRUE; |
if (nmoi) begin |
vect <= {vbr[31:9],irq_vect,2'b00}; |
state <= DECODE; |
next_state(DECODE); |
end |
else begin |
state <= BYTE_DECODE; |
next_state(BYTE_DECODE); |
end |
end |
end |
79,7 → 81,7
if (unCachedInsn) begin |
if (bhit) begin |
ir <= ibuf; |
state <= BYTE_DECODE; |
next_state(BYTE_DECODE); |
end |
else |
state <= LOAD_IBUF1; |
87,24 → 89,26
else begin |
if (ihit) begin |
ir <= insn; |
state <= BYTE_DECODE; |
next_state(BYTE_DECODE); |
end |
else |
state <= ICACHE1; |
end |
end |
`ifdef DEBUG |
if (hist_capture) begin |
history_buf[history_ndx] <= pc; |
history_ndx <= history_ndx+7'd1; |
end |
`endif |
case(ir[7:0]) |
`TAY,`TXY,`DEY,`INY: begin y[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`TAX,`TYX,`TSX,`DEX,`INX: begin x[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`TSA,`TYA,`TXA,`INA,`DEA: begin acc[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`TAY,`TXY,`DEY,`INY: begin y[7:0] <= res8[7:0]; nf <= resn8; zf <= resz8; end |
`TAX,`TYX,`TSX,`DEX,`INX: begin x[7:0] <= res8[7:0]; nf <= resn8; zf <= resz8; end |
`TSA,`TYA,`TXA,`INA,`DEA: begin acc[7:0] <= res8[7:0]; nf <= resn8; zf <= resz8; end |
`TAS,`TXS: begin sp <= res8[7:0]; end |
`ADC_IMM: |
begin |
acc[7:0] <= df ? bcaio : res8; |
acc[7:0] <= df ? bcaio : res8[7:0]; |
cf <= df ? bcaico : resc8; |
// vf <= resv8; |
vf <= (res8[7] ^ b8[7]) & (1'b1 ^ acc[7] ^ b8[7]); |
113,7 → 117,7
end |
`ADC_ZP,`ADC_ZPX,`ADC_IX,`ADC_IY,`ADC_ABS,`ADC_ABSX,`ADC_ABSY,`ADC_I: |
begin |
acc[7:0] <= df ? bcao : res8; |
acc[7:0] <= df ? bcao : res8[7:0]; |
cf <= df ? bcaco : resc8; |
vf <= (res8[7] ^ b8[7]) & (1'b1 ^ acc[7] ^ b8[7]); |
nf <= df ? bcao[7] : resn8; |
121,7 → 125,7
end |
`SBC_IMM: |
begin |
acc[7:0] <= df ? bcsio : res8; |
acc[7:0] <= df ? bcsio : res8[7:0]; |
cf <= ~(df ? bcsico : resc8); |
vf <= (1'b1 ^ res8[7] ^ b8[7]) & (acc[7] ^ b8[7]); |
nf <= df ? bcsio[7] : resn8; |
129,7 → 133,7
end |
`SBC_ZP,`SBC_ZPX,`SBC_IX,`SBC_IY,`SBC_ABS,`SBC_ABSX,`SBC_ABSY,`SBC_I: |
begin |
acc[7:0] <= df ? bcso : res8; |
acc[7:0] <= df ? bcso : res8[7:0]; |
vf <= (1'b1 ^ res8[7] ^ b8[7]) & (acc[7] ^ b8[7]); |
cf <= ~(df ? bcsco : resc8); |
nf <= df ? bcso[7] : resn8; |
147,11 → 151,11
`AND_IMM,`AND_ZP,`AND_ZPX,`AND_IX,`AND_IY,`AND_ABS,`AND_ABSX,`AND_ABSY,`AND_I, |
`ORA_IMM,`ORA_ZP,`ORA_ZPX,`ORA_IX,`ORA_IY,`ORA_ABS,`ORA_ABSX,`ORA_ABSY,`ORA_I, |
`EOR_IMM,`EOR_ZP,`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_ABS,`EOR_ABSX,`EOR_ABSY,`EOR_I: |
begin acc[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`ASL_ACC: begin acc[7:0] <= res8; cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROL_ACC: begin acc[7:0] <= res8; cf <= resc8; nf <= resn8; zf <= resz8; end |
`LSR_ACC: begin acc[7:0] <= res8; cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROR_ACC: begin acc[7:0] <= res8; cf <= resc8; nf <= resn8; zf <= resz8; end |
begin acc[7:0] <= res8[7:0]; nf <= resn8; zf <= resz8; end |
`ASL_ACC: begin acc[7:0] <= res8[7:0]; cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROL_ACC: begin acc[7:0] <= res8[7:0]; cf <= resc8; nf <= resn8; zf <= resz8; end |
`LSR_ACC: begin acc[7:0] <= res8[7:0]; cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROR_ACC: begin acc[7:0] <= res8[7:0]; cf <= resc8; nf <= resn8; zf <= resz8; end |
`ASL_ZP,`ASL_ZPX,`ASL_ABS,`ASL_ABSX: begin cf <= resc8; nf <= resn8; zf <= resz8; end |
`ROL_ZP,`ROL_ZPX,`ROL_ABS,`ROL_ABSX: begin cf <= resc8; nf <= resn8; zf <= resz8; end |
`LSR_ZP,`LSR_ZPX,`LSR_ABS,`LSR_ABSX: begin cf <= resc8; nf <= resn8; zf <= resz8; end |
158,10 → 162,10
`ROR_ZP,`ROR_ZPX,`ROR_ABS,`ROR_ABSX: begin cf <= resc8; nf <= resn8; zf <= resz8; end |
`INC_ZP,`INC_ZPX,`INC_ABS,`INC_ABSX: begin nf <= resn8; zf <= resz8; end |
`DEC_ZP,`DEC_ZPX,`DEC_ABS,`DEC_ABSX: begin nf <= resn8; zf <= resz8; end |
`PLA: begin acc[7:0] <= res8; zf <= resz8; nf <= resn8; end |
`PLX: begin x[7:0] <= res8; zf <= resz8; nf <= resn8; end |
`PLY: begin y[7:0] <= res8; zf <= resz8; nf <= resn8; end |
`LDX_IMM,`LDX_ZP,`LDX_ZPY,`LDX_ABS,`LDX_ABSY: begin x[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`LDY_IMM,`LDY_ZP,`LDY_ZPX,`LDY_ABS,`LDY_ABSX: begin y[7:0] <= res8; nf <= resn8; zf <= resz8; end |
`PLA: begin acc[7:0] <= res8[7:0]; zf <= resz8; nf <= resn8; end |
`PLX: begin x[7:0] <= res8[7:0]; zf <= resz8; nf <= resn8; end |
`PLY: begin y[7:0] <= res8[7:0]; zf <= resz8; nf <= resn8; end |
`LDX_IMM,`LDX_ZP,`LDX_ZPY,`LDX_ABS,`LDX_ABSY: begin x[7:0] <= res8[7:0]; nf <= resn8; zf <= resz8; end |
`LDY_IMM,`LDY_ZP,`LDY_ZPX,`LDY_ABS,`LDY_ABSX: begin y[7:0] <= res8[7:0]; nf <= resn8; zf <= resz8; end |
endcase |
end |
/rtl/verilog/rtf65002_alu.v
100,7 → 100,9
4'd7: res <= abs8; |
4'h8: res <= {vbr[31:1],nmoi}; |
4'h9: res <= derr_address; |
`ifdef DEBUG |
4'hA: res <= history_buf; |
`endif |
4'hE: res <= {spage[31:8],sp}; |
4'hF: res <= isp; |
default: res <= 33'd0; |
/rtl/verilog/rtf65002_itagmem4k.v
44,7 → 44,7
syncRam512x32_1rw1r ram0 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11), |
.wce(1'b1), |
.we(wr), |
.wadr({1'b0,adr[11:4]}), |
.i(adr[31:0]), |
60,7 → 60,7
syncRam512x32_1rw1r ram1 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11), |
.wce(1'b1), |
.we(wr), |
.wadr({1'b0,adr[11:4]}), |
.i(adr[31:0]), |
/rtl/verilog/rtf65002_pcinc8.v
27,7 → 27,7
input [3:0] suppress_pcinc; |
output reg [3:0] inc; |
|
always @(opcode) |
always @(opcode,suppress_pcinc) |
if (suppress_pcinc==4'hF) |
case(opcode) |
`BRK: inc <= 4'd0; |
/rtl/verilog/rtf65002d.v
26,7 → 26,7
// |
`include "rtf65002_defines.v" |
|
module rtf65002d(rst_md, rst_i, clk_i, nmi_i, irq_i, irq_vect, bte_o, cti_o, bl_o, lock_o, cyc_o, stb_o, ack_i, err_i, we_o, sel_o, adr_o, dat_i, dat_o, km_o); |
module rtf65002d(rst_md, rst_i, clk_i, nmi_i, irq_i, irq_vect, bte_o, cti_o, bl_o, lock_o, cyc_o, stb_o, ack_i, rty_i, err_i, we_o, sel_o, adr_o, dat_i, dat_o, km_o); |
parameter RESET1 = 6'd0; |
parameter IFETCH = 6'd1; |
parameter DECODE = 6'd2; |
46,23 → 46,22
parameter BYTE_DECODE = 6'd16; |
parameter BYTE_CALC = 6'd17; |
parameter BUS_ERROR = 6'd18; |
parameter INSN_BUS_ERROR = 6'd19; |
parameter LOAD_MAC1 = 6'd20; |
parameter LOAD_MAC2 = 6'd21; |
parameter LOAD_MAC3 = 6'd22; |
parameter MVN3 = 6'd23; |
parameter PUSHA1 = 6'd24; |
parameter POPA1 = 6'd25; |
parameter BYTE_IFETCH = 6'd26; |
parameter LOAD_DCACHE = 6'd27; |
parameter LOAD_ICACHE = 6'd28; |
parameter LOAD_IBUF1 = 6'd29; |
parameter LOAD_IBUF2 = 6'd30; |
parameter LOAD_IBUF3 = 6'd31; |
parameter ICACHE1 = 6'd32; |
parameter IBUF1 = 6'd33; |
parameter DCACHE1 = 6'd34; |
parameter CMPS1 = 6'd35; |
parameter LOAD_MAC1 = 6'd19; |
parameter LOAD_MAC2 = 6'd20; |
parameter LOAD_MAC3 = 6'd21; |
parameter MVN3 = 6'd22; |
parameter PUSHA1 = 6'd23; |
parameter POPA1 = 6'd24; |
parameter BYTE_IFETCH = 6'd25; |
parameter LOAD_DCACHE = 6'd26; |
parameter LOAD_ICACHE = 6'd27; |
parameter LOAD_IBUF1 = 6'd28; |
parameter LOAD_IBUF2 = 6'd29; |
parameter LOAD_IBUF3 = 6'd30; |
parameter ICACHE1 = 6'd31; |
parameter IBUF1 = 6'd32; |
parameter DCACHE1 = 6'd33; |
parameter CMPS1 = 6'd34; |
|
input rst_md; // reset mode, 1=emulation mode, 0=native mode |
input rst_i; |
77,6 → 76,7
output reg cyc_o; |
output reg stb_o; |
input ack_i; |
input rty_i; |
input err_i; |
output reg we_o; |
output reg [3:0] sel_o; |
93,6 → 93,7
reg [31:0] bufadr; |
reg [63:0] exbuf; |
|
integer n; |
reg cf,nf,zf,vf,bf,im,df,em; |
reg tf; // trace mode flag |
reg ttrig; // trace trigger |
113,6 → 114,7
wire [7:0] x8 = x[7:0]; |
wire [7:0] y8 = y[7:0]; |
reg [31:0] isp; // interrupt stack pointer |
reg [31:0] oisp; // original isp for bus retry |
wire [63:0] prod; |
wire [31:0] q,r; |
reg [31:0] tick; |
123,7 → 125,8
reg [3:0] suppress_pcinc; |
reg [31:0] pc; |
reg [31:0] opc; |
wire [3:0] pc_inc,pc_inc8; |
wire [3:0] pc_inc; |
wire [3:0] pc_inc8; |
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] pcp8 = pc + 32'd8; // cache controller needs this |
130,6 → 133,7
reg [31:0] abs8; // 8 bit mode absolute address register |
reg [31:0] vbr; // vector table base register |
wire bhit=pc==bufadr; |
reg [2:0] bcnt; // burst count for cache controller |
reg [31:0] regfile [15:0]; |
reg [63:0] ir; |
reg pg2; |
179,7 → 183,7
wire resn8 = res8[7]; |
wire resn32 = res[31]; |
|
reg [31:0] vect; |
reg [33:0] vect; |
reg [31:0] ia; // temporary reg to hold indirect address |
reg isInsnCacheLoad; |
reg isDataCacheLoad; |
203,6 → 207,7
wire [31:0] rdat; |
reg [4:0] load_what; |
reg [5:0] store_what; |
reg [8:0] intno; // interrupt number to take |
reg [31:0] derr_address; |
reg imiss; |
reg dmiss; |
224,12 → 229,17
wire [1:0] whichrd; |
wire whichwr=clfsr[0]; |
`endif |
reg [31:0] ilfsr; |
wire ilfsr_fb; |
xnor(ilfsr_fb,ilfsr[0],ilfsr[1],ilfsr[21],ilfsr[31]); |
reg km; // kernel mode indicator |
assign km_o = km; |
|
`ifdef DEBUG |
reg [31:0] history_buf [127:0]; |
reg [6:0] history_ndx; |
reg hist_capture; |
`endif |
|
reg isBusErr; |
reg isBrk,isMove,isSts; |
281,7 → 291,9
isSts <= ir9==`STS; |
isJsrIndx <= ir9==`JSR_INDX; |
isJsrInd <= ir9==`JSR_IND; |
ldMuldiv <= ir9==`MUL_IMM8 || ir9==`DIV_IMM8 || ir9==`MOD_IMM8 || (ir9==`RR && ( |
ldMuldiv <= ir9==`MUL_IMM8 || ir9==`MUL_IMM16 || ir9==`MUL_IMM32 || |
ir9==`DIV_IMM8 || ir9==`MOD_IMM8 || ir9==`DIV_IMM16 || ir9==`DIV_IMM32 || ir9==`MOD_IMM16 || ir9==`MOD_IMM32 || |
(ir9==`RR && ( |
ir[23:20]==`MUL_RR || ir[23:20]==`MULS_RR || ir[23:20]==`DIV_RR || ir[23:20]==`DIVS_RR || ir[23:20]==`MOD_RR || ir[23:20]==`MODS_RR)); |
isPusha <= ir9==`PUSHA; |
isPopa <= ir9==`POPA; |
313,7 → 325,7
.suppress_pcinc(suppress_pcinc), |
.inc(pc_inc8) |
); |
|
|
mult_div umd1 |
( |
.rst(rst_i), |
369,7 → 381,7
rtf65002_itagmem4k tgm0 ( |
.wclk(clk), |
.wr((ack_i & isInsnCacheLoad)|isCacheReset), |
.adr({adr_o[31:1],!isCacheReset}), |
.adr({adr_o[33:1],!isCacheReset}), |
.rclk(~clk), |
.pc(pc), |
.hit0(hit0), |
390,7 → 402,7
rtf65002_itagmem8k tgm0 ( |
.wclk(clk), |
.wr((ack_i & isInsnCacheLoad)|isCacheReset), |
.adr({adr_o[31:1],!isCacheReset}), |
.adr({adr_o[33:1],!isCacheReset}), |
.rclk(~clk), |
.pc(pc), |
.hit0(hit0), |
487,6 → 499,7
2'd2: dati <= dat_i[23:16]; |
2'd3: dati <= dat_i[31:24]; |
endcase |
`ifdef SUPPORT_DCACHE |
reg [7:0] rdat8; |
always @(radr2LSB or rdat) |
case(radr2LSB) |
495,6 → 508,7
2'd2: rdat8 <= rdat[23:16]; |
2'd3: rdat8 <= rdat[31:24]; |
endcase |
`endif |
|
// Evaluate branches |
// |
604,7 → 618,6
dat_o <= 32'd0; |
nmi_edge <= 1'b0; |
wai <= 1'b0; |
first_ifetch <= `TRUE; |
cf <= 1'b0; |
ir <= 64'hEAEAEAEAEAEAEAEA; |
imiss <= `FALSE; |
635,8 → 648,10
tick <= 32'd0; |
isIY <= 1'b0; |
load_what <= `NOTHING; |
`ifdef DEBUG |
hist_capture <= `TRUE; |
history_ndx <= 6'd0; |
`endif |
pg2 <= `FALSE; |
tf <= `FALSE; |
km <= `TRUE; |
643,6 → 658,7
end |
else begin |
tick <= tick + 32'd1; |
ilfsr <= {ilfsr,ilfsr_fb}; |
if (nmi_i & !nmi1) |
nmi_edge <= 1'b1; |
if (nmi_i|nmi1) |
715,35 → 731,18
begin |
pg2 <= `FALSE; |
ir <= {8{`BRK}}; |
`ifdef DEBUG |
hist_capture <= `FALSE; |
`endif |
radr <= isp_dec; |
wadr <= isp_dec; |
isp <= isp_dec; |
store_what <= `STW_OPC; |
if (em | isOrb | isStb) |
derr_address <= adr_o[31:0]; |
else |
derr_address <= adr_o[33:2]; |
vect <= {vbr[31:9],9'd508,2'b00}; |
vect <= {vbr[31:9],intno,2'b00}; |
hwi <= `TRUE; |
isBusErr <= `TRUE; |
state <= STORE1; |
end |
INSN_BUS_ERROR: |
begin |
pg2 <= `FALSE; |
ir <= {8{`BRK}}; |
hist_capture <= `FALSE; |
radr <= isp_dec; |
wadr <= isp_dec; |
isp <= isp_dec; |
store_what <= `STW_OPC; |
derr_address <= 34'd0; |
vect <= {vbr[31:9],9'd509,2'b00}; |
hwi <= `TRUE; |
isBusErr <= `TRUE; |
state <= STORE1; |
end |
`endif |
|
`include "rtf65002_string.v" |
754,5 → 753,13
`include "decode.v" |
`include "calc.v" |
`include "load_tsk.v" |
`include "wb_task.v" |
|
task next_state; |
input [5:0] nxt; |
begin |
state <= nxt; |
end |
endtask |
|
endmodule |
/rtl/verilog/store.v
26,46 → 26,33
// there was a write hit. |
STORE1: |
begin |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
if (em || isStb) begin |
case(wadr2LSB) |
2'd0: sel_o <= 4'b0001; |
2'd1: sel_o <= 4'b0010; |
2'd2: sel_o <= 4'b0100; |
2'd3: sel_o <= 4'b1000; |
endcase |
end |
else |
sel_o <= 4'hf; |
adr_o <= {wadr,2'b00}; |
case(store_what) |
`STW_ACC: dat_o <= acc; |
`STW_X: dat_o <= x; |
`STW_Y: dat_o <= y; |
`STW_PC: dat_o <= pc; |
`STW_PC2: dat_o <= pc + 32'd2; |
`STW_PCHWI: dat_o <= pc+{30'b0,~hwi,1'b0}; |
`STW_OPC: dat_o <= opc; |
`STW_SR: dat_o <= sr; |
`STW_RFA: dat_o <= rfoa; |
`STW_RFA8: dat_o <= {4{rfoa[7:0]}}; |
`STW_A: dat_o <= a; |
`STW_B: dat_o <= b; |
`STW_CALC: dat_o <= res; |
`STW_ACC: wb_write(0,acc); |
`STW_X: wb_write(0,x); |
`STW_Y: wb_write(0,y); |
`STW_PC: wb_write(0,pc); |
`STW_PC2: wb_write(0,pc + 32'd2); |
`STW_PCHWI: wb_write(0,pc+{30'b0,~hwi,1'b0}); |
`STW_OPC: wb_write(0,opc); |
`STW_SR: wb_write(0,sr); |
`STW_RFA: wb_write(0,rfoa); |
`STW_RFA8: wb_write(1,{4{rfoa[7:0]}}); |
`STW_A: wb_write(0,a); |
`STW_B: wb_write(0,b); |
`STW_CALC: wb_write(0,res[31:0]); |
`ifdef SUPPORT_EM8 |
`STW_ACC8: dat_o <= {4{acc8}}; |
`STW_X8: dat_o <= {4{x8}}; |
`STW_Y8: dat_o <= {4{y8}}; |
`STW_Z8: dat_o <= {4{8'h00}}; |
`STW_PC3124: dat_o <= {4{pc[31:24]}}; |
`STW_PC2316: dat_o <= {4{pc[23:16]}}; |
`STW_PC158: dat_o <= {4{pc[15:8]}}; |
`STW_PC70: dat_o <= {4{pc[7:0]}}; |
`STW_SR70: dat_o <= {4{sr8}}; |
`STW_ACC8: wb_write(1,{4{acc8}}); |
`STW_X8: wb_write(1,{4{x8}}); |
`STW_Y8: wb_write(1,{4{y8}}); |
`STW_Z8: wb_write(1,{4{8'h00}}); |
`STW_PC3124: wb_write(1,{4{pc[31:24]}}); |
`STW_PC2316: wb_write(1,{4{pc[23:16]}}); |
`STW_PC158: wb_write(1,{4{pc[15:8]}}); |
`STW_PC70: wb_write(1,{4{pc[7:0]}}); |
`STW_SR70: wb_write(1,{4{sr8}}); |
`STW_DEF8: wb_write(1,wdat); |
`endif |
default: dat_o <= wdat; |
default: wb_write(0,wdat); |
endcase |
`ifdef SUPPORT_DCACHE |
radr <= wadr; // Do a cache read to test the hit |
76,7 → 63,15
// Terminal state for stores. Update the data cache if there was a cache hit. |
// Clear any previously set lock status |
STORE2: |
if (ack_i) begin |
// On a retry operation, restore the stack pointer which may have been |
// modified, then go back to the decode state to pick up original |
// addresses and data. This doesn't work for block move/store |
if (rty_i) begin |
wb_nack(); |
isp <= oisp; |
state <= DECODE; |
end |
else if (ack_i) begin |
wdat <= dat_o; |
if (isMove|isSts) begin |
state <= MVN3; |
93,12 → 88,7
end |
end |
lock_o <= 1'b0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'h0; |
dat_o <= 32'h0; |
wb_nack(); |
case(store_what) |
`STW_PC,`STW_PC2,`STW_PCHWI,`STW_OPC: |
if (isBrk|isBusErr) begin |
114,7 → 104,7
load_what <= `PC_310; |
state <= LOAD_MAC1; |
retstate <= LOAD_MAC1; |
radr <= vect[31:2]; |
radr <= vect[33:2]; |
ttrig <= 1'b0; |
tf <= 1'b0; // turn off trace mode |
im <= 1'b1; |
144,6 → 134,7
wadr2LSB <= sp[1:0]; |
store_what <= `STW_PC2316; |
sp <= sp_dec; |
retstate <= STORE1; |
state <= STORE1; |
end |
`STW_PC2316: |
154,6 → 145,7
wadr2LSB <= sp[1:0]; |
sp <= sp_dec; |
store_what <= `STW_PC158; |
retstate <= STORE1; |
state <= STORE1; |
end |
`STW_PC158: |
164,6 → 156,7
wadr2LSB <= sp[1:0]; |
sp <= sp_dec; |
store_what <= `STW_PC70; |
retstate <= STORE1; |
state <= STORE1; |
end |
`STW_PC70: |
176,11 → 169,11
wadr2LSB <= sp[1:0]; |
sp <= sp_dec; |
store_what <= `STW_SR70; |
retstate <= STORE1; |
state <= STORE1; |
end |
`JSR: begin |
pc <= ir[23:8]; |
$display("setting pc=%h", ir[23:8]); |
pc[15:0] <= ir[23:8]; |
end |
`JSL: begin |
pc <= ir[39:8]; |
202,7 → 195,7
state <= LOAD_MAC1; |
retstate <= LOAD_MAC1; |
pc[31:16] <= abs8[31:16]; |
radr <= vect[31:2]; |
radr <= vect[33:2]; |
radr2LSB <= vect[1:0]; |
im <= hwi; |
end |
231,13 → 224,12
`ifdef SUPPORT_BERR |
else if (err_i) begin |
lock_o <= 1'b0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'h0; |
dat_o <= 32'h0; |
wb_nack(); |
if (em | isStb) |
derr_address <= adr_o[31:0]; |
else |
derr_address <= adr_o[33:2]; |
intno <= 9'd508; |
state <= BUS_ERROR; |
end |
`endif |
|
|
/rtl/verilog/rtf65002_itagmem2way.v
47,7 → 47,7
syncRam512x32_1rw1r ram0 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11 && !whichwr), |
.wce(!whichwr), |
.we(wr), |
.wadr(adr[12:4]), |
.i(adr[31:0]), |
63,7 → 63,7
syncRam512x32_1rw1r ram1 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11 && !whichwr), |
.wce(!whichwr), |
.we(wr), |
.wadr(adr[12:4]), |
.i(adr[31:0]), |
79,7 → 79,7
syncRam512x32_1rw1r ram2 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11 && whichwr), |
.wce(whichwr), |
.we(wr), |
.wadr(adr[12:4]), |
.i(adr[31:0]), |
95,7 → 95,7
syncRam512x32_1rw1r ram3 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11 && whichwr), |
.wce(whichwr), |
.we(wr), |
.wadr(adr[12:4]), |
.i(adr[31:0]), |
/rtl/verilog/rtf65002_itagmem8k.v
43,7 → 43,7
syncRam512x32_1rw1r ram0 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11), |
.wce(1'b1), |
.we(wr), |
.wadr(adr[12:4]), |
.i(adr[31:0]), |
59,7 → 59,7
syncRam512x32_1rw1r ram1 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11), |
.wce(1'b1), |
.we(wr), |
.wadr(adr[12:4]), |
.i(adr[31:0]), |
/rtl/verilog/load_tsk.v
42,7 → 42,7
radr <= y; |
wadr <= y; |
store_what <= `STW_B; |
x <= res; |
x <= res[31:0]; |
acc <= acc - 32'd1; |
state <= STORE1; |
end |
51,7 → 51,7
a <= dat; |
radr <= y; |
load_what <= `WORD_314; |
x <= res; |
x <= res[31:0]; |
state <= LOAD_MAC1; |
end |
`WORD_314: |
162,7 → 162,9
load_what <= `NOTHING; |
if (isRTI) begin |
km <= `FALSE; |
`ifdef DEBUG |
hist_capture <= `TRUE; |
`endif |
end |
state <= em ? BYTE_IFETCH : IFETCH; |
end |
/rtl/verilog/cache_controller.v
2,7 → 2,7
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// \/_// robfinch<remove>@finitron.ca |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
23,65 → 23,6
// Cache controller |
// Also takes care of loading the instruction buffer for non-cached access |
// |
|
//IDLE: |
// begin |
// if (!cyc_o) begin |
//`ifdef SUPPORT_DCACHE |
// // A write to a cacheable address does not cause a cache load |
// if (dmiss) begin |
// isDataCacheLoad <= `TRUE; |
// if (isRMW) |
// lock_o <= 1'b1; |
// cti_o <= 3'b001; |
// bl_o <= 6'd3; |
// cyc_o <= 1'b1; |
// stb_o <= 1'b1; |
// sel_o <= 4'hF; |
// adr_o <= {radr[31:2],4'h0}; |
// cstate <= LOAD_DCACHE; |
// end |
// else |
//`endif |
//`ifdef SUPPORT_ICACHE |
// if (!unCachedInsn && imiss && !hit0) begin |
// isInsnCacheLoad <= `TRUE; |
// bte_o <= 2'b00; |
// cti_o <= 3'd001; |
// bl_o <= 6'd3; |
// cyc_o <= 1'b1; |
// stb_o <= 1'b1; |
// sel_o <= 4'hF; |
// adr_o <= {pc[31:4],4'h0}; |
// cstate <= LOAD_ICACHE; |
// end |
// else if (!unCachedInsn && imiss && !hit1) begin |
// isInsnCacheLoad <= `TRUE; |
// bte_o <= 2'b00; |
// cti_o <= 3'd001; |
// bl_o <= 6'd3; |
// cyc_o <= 1'b1; |
// stb_o <= 1'b1; |
// sel_o <= 4'hF; |
// adr_o <= {pcp8[31:4],4'h0}; |
// cstate <= LOAD_ICACHE; |
// end |
// else |
//`endif |
// if (unCachedInsn && imiss) begin |
// bte_o <= 2'b00; |
// cti_o <= 3'b001; |
// bl_o <= 6'd2; |
// cyc_o <= 1'b1; |
// stb_o <= 1'b1; |
// sel_o <= 4'hf; |
// adr_o <= {pc[31:2],2'b00}; |
// cstate <= LOAD_IBUF1; |
// end |
// end |
// end |
|
|
`ifdef SUPPORT_DCACHE |
DCACHE1: |
begin |
88,25 → 29,17
isDataCacheLoad <= `TRUE; |
if (isRMW) |
lock_o <= 1'b1; |
cti_o <= 3'b001; |
bl_o <= 6'd3; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {radr[31:2],4'h0}; |
wb_burst(6'd3,{radr[31:2],4'h0}); |
state <= LOAD_DCACHE; |
end |
LOAD_DCACHE: |
if (ack_i) begin |
if (adr_o[3:2]==2'b10) |
cti_o <= 3'b111; |
if (adr_o[3:2]==2'b11) begin |
dmiss <= `FALSE; |
isDataCacheLoad <= `FALSE; |
cti_o <= 3'b000; |
bl_o <= 6'd0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'h0; |
wb_nack(); |
state <= retstate; |
end |
adr_o[3:2] <= adr_o[3:2] + 2'd1; |
113,19 → 46,18
end |
`ifdef SUPPORT_BERR |
else if (err_i) begin |
if (adr_o[3:2]==2'b10) |
cti_o <= 3'b111; |
if (adr_o[3:2]==2'b11) begin |
dmiss <= `FALSE; |
isDataCacheLoad <= `FALSE; |
cti_o <= 3'b000; |
bl_o <= 6'd0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'h0; |
wb_nack(); |
// The state machine will be waiting for a dhit. |
// Override the next state and send the processor to the bus error state. |
intno <= 9'd508; |
state <= BUS_ERROR; |
end |
derr_address <= adr_o[33:2]; |
adr_o[3:2] <= adr_o[3:2] + 2'd1; |
end |
`endif |
134,24 → 66,12
ICACHE1: |
if (!hit0) begin |
isInsnCacheLoad <= `TRUE; |
bte_o <= 2'b00; |
cti_o <= 3'b001; |
bl_o <= 6'd3; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {pc[31:4],4'h0}; |
wb_burst(6'd3,{pc[31:4],4'h0}); |
state <= LOAD_ICACHE; |
end |
else if (!hit1) begin |
isInsnCacheLoad <= `TRUE; |
bte_o <= 2'b00; |
cti_o <= 3'b001; |
bl_o <= 6'd3; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {pcp8[31:4],4'h0}; |
wb_burst(6'd3,{pcp8[31:4],4'h0}); |
state <= LOAD_ICACHE; |
end |
else |
158,14 → 78,11
state <= em ? BYTE_IFETCH : IFETCH; |
LOAD_ICACHE: |
if (ack_i) begin |
if (adr_o[3:2]==2'b10) |
cti_o <= 3'b111; |
if (adr_o[3:2]==2'b11) begin |
isInsnCacheLoad <= `FALSE; |
cti_o <= 3'b000; |
bl_o <= 6'd0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'd0; |
wb_nack(); |
`ifdef ICACHE_2WAY |
clfsr <= {clfsr,clfsr_fb}; |
`endif |
175,15 → 92,14
end |
`ifdef SUPPORT_BERR |
else if (err_i) begin |
if (adr_o[3:2]==2'b10) |
cti_o <= 3'b111; |
if (adr_o[3:2]==2'b11) begin |
isInsnCacheLoad <= `FALSE; |
cti_o <= 3'b000; |
bl_o <= 6'd0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'd0; |
state <= INSN_BUS_ERROR; |
wb_nack(); |
derr_address <= 32'd0; |
intno <= 9'd509; |
state <= BUS_ERROR; |
`ifdef ICACHE_2WAY |
clfsr <= {clfsr,clfsr_fb}; |
`endif |
192,28 → 108,16
end |
`endif |
`endif |
//IBUF1: |
// begin |
// bte_o <= 2'b00; |
// cti_o <= 3'b001; |
// bl_o <= 6'd2; |
// cyc_o <= 1'b1; |
// stb_o <= 1'b1; |
// sel_o <= 4'hf; |
// adr_o <= {pc[31:2],2'b00}; |
// state <= LOAD_IBUF1; |
// end |
|
LOAD_IBUF1: |
if (!cyc_o) begin |
bte_o <= 2'b00; |
cti_o <= 3'b001; |
bl_o <= 6'd2; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {pc[31:2],2'b00}; |
// Emulation mode never needs to read more than two words. |
// Native mode might need up to three words. |
wb_burst((em ? 6'd1: 6'd2),{pc[31:2],2'b00}); |
end |
else if (ack_i|err_i) begin |
if (em) |
cti_o <= 3'b111; |
case(pc[1:0]) |
2'd0: ibuf <= dat_i; |
2'd1: ibuf <= dat_i[31:8]; |
221,13 → 125,10
2'd3: ibuf <= dat_i[31:24]; |
endcase |
state <= LOAD_IBUF2; |
adr_o <= adr_o + 34'd4; |
end |
LOAD_IBUF2: |
if (ack_i|err_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
state <= em ? BYTE_IFETCH : LOAD_IBUF3; |
case(pc[1:0]) |
2'd0: ibuf[55:32] <= dat_i[23:0]; |
2'd1: ibuf[55:24] <= dat_i; |
234,15 → 135,21
2'd2: ibuf[47:16] <= dat_i; |
2'd3: ibuf[39:8] <= dat_i; |
endcase |
state <= LOAD_IBUF3; |
adr_o <= adr_o + 34'd4; |
if (em) begin |
wb_nack(); |
if (err_i) begin |
derr_address <= 32'd0; |
intno <= 9'd509; |
state <= BUS_ERROR; |
end |
bufadr <= pc; // clears the miss |
end |
else |
cti_o <= 3'b111; |
end |
LOAD_IBUF3: |
if (ack_i) begin |
cti_o <= 3'b000; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
wb_nack(); |
case(pc[1:0]) |
2'd0: ; |
2'd1: ; |
249,12 → 156,12
2'd2: ibuf[55:48] <= dat_i[7:0]; |
2'd3: ibuf[55:40] <= dat_i[15:0]; |
endcase |
adr_o <= 34'd0; |
state <= IFETCH; |
bufadr <= pc; // clears the miss |
end |
`ifdef SUPPORT_BERR |
else if (err_i) begin |
wb_nack(); |
case(pc[1:0]) |
2'd0: ; |
2'd1: ; |
261,12 → 168,9
2'd2: ibuf[55:48] <= dat_i[7:0]; |
2'd3: ibuf[55:40] <= dat_i[15:0]; |
endcase |
cti_o <= 3'b000; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'd0; |
state <= INSN_BUS_ERROR; |
derr_address <= 32'd0; |
intno <= 9'd509; |
state <= BUS_ERROR; |
bufadr <= pc; // clears the miss |
end |
`endif |
/rtl/verilog/decode.v
29,6 → 29,7
a <= rfoa; |
res <= alu_out; |
ttrig <= tf; |
oisp <= isp; // for bus retry |
// This case statement should include all opcodes or the opcode |
// will end up being treated as an undefined operation. |
case(ir9) |
103,7 → 104,9
4'd7: ; |
4'h8: ; |
4'h9: ; |
`ifdef DEBUG |
4'hA: history_ndx <= history_ndx + 6'd1; |
`endif |
4'hE: ; |
4'hF: ; |
default: ; |
490,7 → 493,9
begin |
bf <= !hwi; |
km <= `TRUE; |
`ifdef DEBUG |
hist_capture <= `FALSE; |
`endif |
radr <= isp_dec; |
wadr <= isp_dec; |
isp <= isp_dec; |
/rtl/verilog/mult_div.v
27,9 → 27,11
|
module mult_div(rst, clk, ld, op, fn, a, b, p, q, r, done); |
parameter IDLE=3'd0; |
parameter MULT=3'd1; |
parameter FIX_SIGN=3'd2; |
parameter DIV=3'd3; |
parameter MULT1=3'd1; |
parameter MULT2=3'd2; |
parameter MULT3=3'd3; |
parameter FIX_SIGN=3'd4; |
parameter DIV=3'd5; |
input rst; |
input clk; |
input ld; |
50,6 → 52,7
assign done = state==IDLE; |
wire [31:0] diff = r - bb; |
wire [31:0] pa = a[31] ? -a : a; |
wire [63:0] p1 = aa * bb; |
reg [5:0] cnt; |
|
always @(posedge clk) |
66,7 → 69,7
aa <= a; |
bb <= b; |
res_sgn <= 1'b0; |
state <= MULT; |
state <= MULT1; |
end |
`ifdef SUPPORT_DIVMOD |
`DIV_IMM8,`DIV_IMM16,`DIV_IMM32, |
87,7 → 90,7
aa <= a; |
bb <= b; |
res_sgn <= 1'b0; |
state <= MULT; |
state <= MULT1; |
end |
`MULS_RR: |
begin |
94,7 → 97,7
aa <= a[31] ? -a : a; |
bb <= b[31] ? -b : b; |
res_sgn <= a[31] ^ b[31]; |
state <= MULT; |
state <= MULT1; |
end |
`ifdef SUPPORT_DIVMOD |
`DIV_RR,`MOD_RR: |
121,11 → 124,16
endcase |
endcase |
end |
MULT: |
begin |
state <= res_sgn ? FIX_SIGN : IDLE; |
p <= aa * bb; |
end |
// Three waut states for the multiply to take effect. These are needed at |
// higher clock frequencies. The multipler is a multi-cycle path that |
// requires a timing constraint. |
MULT1: state <= MULT2; |
MULT2: state <= MULT3; |
MULT3: begin |
p <= p1; |
state <= res_sgn ? FIX_SIGN : IDLE; |
end |
|
`ifdef SUPPORT_DIVMOD |
DIV: |
begin |
/rtl/verilog/byte_calc.v
26,7 → 26,7
state <= BYTE_IFETCH; |
wadr <= radr; |
wadr2LSB <= radr2LSB; |
store_what <= `STW_DEF; |
store_what <= `STW_DEF8; |
case(ir[7:0]) |
`ADC_IMM,`ADC_ZP,`ADC_ZPX,`ADC_IX,`ADC_IY,`ADC_ABS,`ADC_ABSX,`ADC_ABSY,`ADC_I: begin res8 <= acc8 + b8 + {7'b0,cf}; end |
`SBC_IMM,`SBC_ZP,`SBC_ZPX,`SBC_IX,`SBC_IY,`SBC_ABS,`SBC_ABSX,`SBC_ABSY,`SBC_I: begin res8 <= acc8 - b8 - {7'b0,~cf}; end |
/rtl/verilog/rtf65002_dtagmem.v
36,7 → 36,7
( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(wadr[1:0]==2'b11), |
.wce(1'b1), |
.we(wr), |
.wadr(wadr[10:2]), |
.i({wadr[31:1],cr}), |
/rtl/verilog/wb_task.v
0,0 → 1,80
// ============================================================================ |
// __ |
// \\__/ o\ (C) 2013 Robert Finch, Stratford |
// \ __ / All rights reserved. |
// \/_// robfinch<remove>@opencores.org |
// || |
// |
// This source file is free software: you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or |
// (at your option) any later version. |
// |
// This source file is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
// |
// ============================================================================ |
// |
task wb_burst; |
input [5:0] len; |
input [33:0] adr; |
begin |
bte_o <= 2'b00; |
cti_o <= 3'b001; |
bl_o <= len; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= adr; |
end |
endtask |
|
task wb_read; |
input [33:0] adr; |
begin |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= adr; |
end |
endtask |
|
task wb_write; |
input byt; |
input [31:0] dat; |
begin |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
we_o <= 1'b1; |
if (byt) begin |
case(wadr2LSB) |
2'd0: sel_o <= 4'b0001; |
2'd1: sel_o <= 4'b0010; |
2'd2: sel_o <= 4'b0100; |
2'd3: sel_o <= 4'b1000; |
endcase |
end |
else |
sel_o <= 4'hf; |
adr_o <= {wadr,2'b00}; |
dat_o <= dat; |
end |
endtask |
|
task wb_nack; |
begin |
cti_o <= 3'b000; |
bl_o <= 6'd0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
we_o <= 1'b0; |
adr_o <= 34'd0; |
dat_o <= 32'd0; |
end |
endtask |
/rtl/verilog/rtf65002_itagmem.v
43,7 → 43,7
syncRam1kx32_1rw1r ram0 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11), |
.wce(1'b1), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[13:4]), |
60,7 → 60,7
syncRam1kx32_1rw1r ram1 ( |
.wrst(1'b0), |
.wclk(wclk), |
.wce(adr[3:2]==2'b11), |
.wce(1'b1), |
.we(wr), |
.wsel(4'hF), |
.wadr(adr[13:4]), |
/rtl/verilog/load_mac.v
27,10 → 27,7
begin |
if (isRMW) |
lock_o <= 1'b1; |
cyc_o <= 1'b1; |
stb_o <= 1'b1; |
sel_o <= 4'hF; |
adr_o <= {radr,2'b00}; |
wb_read({radr,2'b00}); |
state <= LOAD_MAC2; |
end |
`ifdef SUPPORT_DCACHE |
43,30 → 40,28
`endif |
LOAD_MAC2: |
if (ack_i) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
adr_o <= 34'h0; |
wb_nack(); |
load_tsk(dat_i,dati); |
end |
`ifdef SUPPORT_BERR |
else if (err_i) begin |
lock_o <= 1'b0; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'h0; |
dat_o <= 32'h0; |
wb_nack(); |
if (em | isOrb) |
derr_address <= adr_o[31:0]; |
else |
derr_address <= adr_o[33:2]; |
intno <= 9'd508; |
state <= BUS_ERROR; |
end |
`endif |
LOAD_MAC3: |
begin |
regfile[Rt] <= res; |
regfile[Rt] <= res[31:0]; |
case(Rt) |
4'h1: acc <= res; |
4'h2: x <= res; |
4'h3: y <= res; |
4'h1: acc <= res[31:0]; |
4'h2: x <= res[31:0]; |
4'h3: y <= res[31:0]; |
default: ; |
endcase |
// Rt will be zero by the time the IFETCH stage is entered because of |
/rtl/verilog/ifetch.v
29,12 → 29,12
isBusErr <= `FALSE; |
pg2 <= `FALSE; |
store_what <= `STW_DEF; |
if (nmi_edge & gie & !isExec & !isAtni) begin // imiss indicates cache controller is active and this state is in a waiting loop |
if (nmi_edge & gie & !isExec & !isAtni) begin |
ir[7:0] <= `BRK; |
nmi_edge <= 1'b0; |
wai <= 1'b0; |
hwi <= `TRUE; |
state <= DECODE; |
next_state(DECODE); |
vect <= `NMI_VECT; |
end |
else if (irq_i & gie & !isExec & !isAtni) begin |
43,31 → 43,35
if (ttrig) begin |
ir[7:0] <= `BRK; |
vect <= {vbr[31:9],9'd490,2'b00}; |
state <= DECODE; |
next_state(DECODE); |
end |
else if (isExec) begin |
ir <= exbuf; |
exbuf <= 64'd0; |
suppress_pcinc <= 4'h0; |
state <= DECODE; |
next_state(DECODE); |
end |
else if (unCachedInsn) begin |
if (bhit) begin |
ir <= ibuf + exbuf; |
exbuf <= 64'd0; |
state <= DECODE; |
next_state(DECODE); |
end |
else |
else begin |
pg2 <= pg2; |
state <= LOAD_IBUF1; |
end |
end |
else begin |
if (ihit) begin |
ir <= insn + exbuf; |
exbuf <= 64'd0; |
state <= DECODE; |
next_state(DECODE); |
end |
else |
else begin |
pg2 <= pg2; |
state <= ICACHE1; |
end |
end |
end |
else begin |
74,7 → 78,7
ir[7:0] <= `BRK; |
hwi <= `TRUE; |
vect <= {vbr[31:9],irq_vect,2'b00}; |
state <= DECODE; |
next_state(DECODE); |
end |
end |
else if (!wai) begin |
81,50 → 85,56
if (ttrig) begin |
ir[7:0] <= `BRK; |
vect <= {vbr[31:9],9'd490,2'b00}; |
state <= DECODE; |
next_state(DECODE); |
end |
else if (isExec) begin |
ir <= exbuf; |
exbuf <= 64'd0; |
suppress_pcinc <= 4'h0; |
state <= DECODE; |
next_state(DECODE); |
end |
else if (unCachedInsn) begin |
if (bhit) begin |
ir <= ibuf + exbuf; |
exbuf <= 64'd0; |
state <= DECODE; |
next_state(DECODE); |
end |
else |
else begin |
pg2 <= pg2; |
state <= LOAD_IBUF1; |
end |
end |
else begin |
if (ihit) begin |
ir <= insn + exbuf; |
exbuf <= 64'd0; |
state <= DECODE; |
next_state(DECODE); |
end |
else |
state <= ICACHE1; |
else begin |
pg2 <= pg2; |
next_state(ICACHE1); |
end |
end |
end |
// During a cache miss all these assignments will repeat. It's not a |
// problem. The history buffer will be stuffed with the same pc address |
// for several cycles until the cache load is complete. |
`ifdef DEBUG |
if (hist_capture) begin |
history_buf[history_ndx] <= pc; |
history_ndx <= history_ndx+7'd1; |
end |
regfile[Rt] <= res; |
`endif |
regfile[Rt] <= res[31:0]; |
case(Rt) |
4'h1: acc <= res; |
4'h2: x <= res; |
4'h3: y <= res; |
4'h1: acc <= res[31:0]; |
4'h2: x <= res[31:0]; |
4'h3: y <= res[31:0]; |
default: ; |
endcase |
case(ir9) |
`TAS,`TXS: begin isp <= res; gie <= 1'b1; end |
`SUB_SP8,`SUB_SP16,`SUB_SP32: isp <= res; |
`TAS,`TXS: begin isp <= res[31:0]; gie <= 1'b1; end |
`SUB_SP8,`SUB_SP16,`SUB_SP32: isp <= res[31:0]; |
`TRS: |
begin |
case(ir[15:12]) |
138,11 → 148,11
write_allocate <= res[2]; |
`endif |
end |
4'h5: lfsr <= res; |
4'h7: abs8 <= res; |
4'h5: lfsr <= res[31:0]; |
4'h7: abs8 <= res[31:0]; |
4'h8: begin vbr <= {res[31:9],9'h000}; nmoi <= res[0]; end |
4'hE: begin sp <= res[7:0]; spage[31:8] <= res[31:8]; end |
4'hF: begin isp <= res; gie <= 1'b1; end |
4'hF: begin isp <= res[31:0]; gie <= 1'b1; end |
endcase |
end |
`RR: |
/rtl/verilog/rtf65002_pcinc.v
28,7 → 28,7
input [3:0] suppress_pcinc; |
output reg [3:0] inc; |
|
always @(opcode) |
always @(opcode,suppress_pcinc) |
if (suppress_pcinc==4'hF) |
case(opcode) |
`BRK: inc <= 4'd0; |