Line 58... |
Line 58... |
// brown-out-reset(s), real-time-clocks, temperature sensors, USB ports,
|
// brown-out-reset(s), real-time-clocks, temperature sensors, USB ports,
|
// Spi-Bi-Wire, UART Boot-strap Loader (BSL), programmable digital I/O,
|
// Spi-Bi-Wire, UART Boot-strap Loader (BSL), programmable digital I/O,
|
// watchdog-timers,
|
// watchdog-timers,
|
//
|
//
|
// Creator: Dan Gisselquist, Ph.D.
|
// Creator: Dan Gisselquist, Ph.D.
|
// Gisselquist Tecnology, LLC
|
// Gisselquist Technology, LLC
|
//
|
//
|
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Copyright (C) 2015, Gisselquist Technology, LLC
|
// Copyright (C) 2015, Gisselquist Technology, LLC
|
//
|
//
|
Line 106... |
Line 106... |
// Without this flag, Slice LUT count is 3315 (ZipSystem),2432 (ZipCPU)
|
// Without this flag, Slice LUT count is 3315 (ZipSystem),2432 (ZipCPU)
|
// When including counters,
|
// When including counters,
|
// Slice LUTs ZipSystem ZipCPU
|
// Slice LUTs ZipSystem ZipCPU
|
// With Counters 3315 2432
|
// With Counters 3315 2432
|
// Without Counters 2796 2046
|
// Without Counters 2796 2046
|
`define INCLUDE_ACCOUNTING_COUNTERS
|
|
|
|
//
|
//
|
// Now, where am I placing all of my peripherals?
|
// Now, where am I placing all of my peripherals?
|
`define PERIPHBASE 32'hc0000000
|
`define PERIPHBASE 32'hc0000000
|
`define INTCTRL 5'h0 //
|
`define INTCTRL 5'h0 //
|
Line 171... |
Line 170... |
, o_cpu_debug
|
, o_cpu_debug
|
`endif
|
`endif
|
);
|
);
|
parameter RESET_ADDRESS=24'h0100000, ADDRESS_WIDTH=24,
|
parameter RESET_ADDRESS=24'h0100000, ADDRESS_WIDTH=24,
|
LGICACHE=12, START_HALTED=1, EXTERNAL_INTERRUPTS=1,
|
LGICACHE=12, START_HALTED=1, EXTERNAL_INTERRUPTS=1,
|
|
`ifdef OPT_MULTIPLY
|
|
IMPLEMENT_MPY = 1,
|
|
`else
|
|
IMPLEMENT_MPY = 0,
|
|
`endif
|
|
`ifdef OPT_DIVIDE
|
|
IMPLEMENT_DIVIDE=1,
|
|
`else
|
|
IMPLEMENT_DIVIDE=0,
|
|
`endif
|
|
`ifdef OPT_IMPLEMENT_FPU
|
|
IMPLEMENT_FPU=0,
|
|
`else
|
|
IMPLEMENT_FPU=1,
|
|
`endif
|
|
IMPLEMENT_LOCK=1,
|
// Derived parameters
|
// Derived parameters
|
AW=ADDRESS_WIDTH;
|
AW=ADDRESS_WIDTH;
|
input i_clk, i_rst;
|
input i_clk, i_rst;
|
// Wishbone master
|
// Wishbone master
|
output wire o_wb_cyc, o_wb_stb, o_wb_we;
|
output wire o_wb_cyc, o_wb_stb, o_wb_we;
|
Line 198... |
Line 213... |
output wire [31:0] o_cpu_debug;
|
output wire [31:0] o_cpu_debug;
|
`endif
|
`endif
|
|
|
wire [31:0] ext_idata;
|
wire [31:0] ext_idata;
|
|
|
|
// Handle our interrupt vector generation/coordination
|
|
wire [14:0] main_int_vector, alt_int_vector;
|
|
wire ctri_int, tma_int, tmb_int, tmc_int, jif_int, dmac_int;
|
|
wire mtc_int, moc_int, mpc_int, mic_int,
|
|
utc_int, uoc_int, upc_int, uic_int;
|
|
generate
|
|
if (EXTERNAL_INTERRUPTS < 9)
|
|
assign main_int_vector = { {(9-EXTERNAL_INTERRUPTS){1'b0}},
|
|
i_ext_int, ctri_int,
|
|
tma_int, tmb_int, tmc_int,
|
|
jif_int, dmac_int };
|
|
else
|
|
assign main_int_vector = { i_ext_int[8:0], ctri_int,
|
|
tma_int, tmb_int, tmc_int,
|
|
jif_int, dmac_int };
|
|
endgenerate
|
|
generate
|
|
if (EXTERNAL_INTERRUPTS <= 9)
|
|
`ifdef INCLUDE_ACCOUNTING_COUNTERS
|
|
assign alt_int_vector = { 7'h00,
|
|
mtc_int, moc_int, mpc_int, mic_int,
|
|
utc_int, uoc_int, upc_int, uic_int };
|
|
`else
|
|
assign alt_int_vector = { 15'h00 };
|
|
`endif
|
|
else
|
|
`ifdef INCLUDE_ACCOUNTING_COUNTERS
|
|
assign alt_int_vector = { {(7-(EXTERNAL_INTERRUPTS-9)){1'b0}},
|
|
i_ext_int[(EXTERNAL_INTERRUPTS-1):9],
|
|
mtc_int, moc_int, mpc_int, mic_int,
|
|
utc_int, uoc_int, upc_int, uic_int };
|
|
`else
|
|
assign alt_int_vector = { {(15-(EXTERNAL_INTERRUPTS-9)){1'b0}},
|
|
i_ext_int[(EXTERNAL_INTERRUPTS-1):9] };
|
|
`endif
|
|
endgenerate
|
|
|
|
|
// Delay the debug port by one clock, to meet timing requirements
|
// Delay the debug port by one clock, to meet timing requirements
|
wire dbg_cyc, dbg_stb, dbg_we, dbg_addr, dbg_stall;
|
wire dbg_cyc, dbg_stb, dbg_we, dbg_addr, dbg_stall;
|
wire [31:0] dbg_idata, dbg_odata;
|
wire [31:0] dbg_idata, dbg_odata;
|
reg dbg_ack;
|
reg dbg_ack;
|
`ifdef DELAY_DBG_BUS
|
`ifdef DELAY_DBG_BUS
|
Line 284... |
Line 337... |
wire [31:0] pic_data;
|
wire [31:0] pic_data;
|
wire [31:0] cmd_data;
|
wire [31:0] cmd_data;
|
// Values:
|
// Values:
|
// 0x0003f -> cmd_addr mask
|
// 0x0003f -> cmd_addr mask
|
// 0x00040 -> reset
|
// 0x00040 -> reset
|
// 0x00080 -> PIC interrrupts enabled
|
// 0x00080 -> PIC interrrupt pending
|
// 0x00100 -> cmd_step
|
// 0x00100 -> cmd_step
|
// 0x00200 -> cmd_stall
|
// 0x00200 -> cmd_stall
|
// 0x00400 -> cmd_halt
|
// 0x00400 -> cmd_halt
|
// 0x00800 -> cmd_clear_pf_cache
|
// 0x00800 -> cmd_clear_pf_cache
|
// 0x01000 -> cc.sleep
|
// 0x01000 -> cc.sleep
|
// 0x02000 -> cc.gie
|
// 0x02000 -> cc.gie
|
// 0x10000 -> External interrupt line is high
|
// 0x04000 -> External (PIC) interrupt line is high
|
assign cmd_data = { 7'h00, {(9-EXTERNAL_INTERRUPTS){1'b0}}, i_ext_int,
|
// Other external interrupts follow
|
cpu_dbg_cc,
|
generate
|
|
if (EXTERNAL_INTERRUPTS < 16)
|
|
assign cmd_data = { {(16-EXTERNAL_INTERRUPTS){1'b0}},
|
|
i_ext_int,
|
|
cpu_dbg_cc, // 4 bits
|
1'b0, cmd_halt, (~cpu_dbg_stall), 1'b0,
|
1'b0, cmd_halt, (~cpu_dbg_stall), 1'b0,
|
pic_data[15], cpu_reset, cmd_addr };
|
pic_data[15], cpu_reset, cmd_addr };
|
|
else
|
|
assign cmd_data = { i_ext_int[15:0], cpu_dbg_cc,
|
|
1'b0, cmd_halt, (~cpu_dbg_stall), 1'b0,
|
|
pic_data[15], cpu_reset, cmd_addr };
|
|
endgenerate
|
|
|
wire cpu_gie;
|
wire cpu_gie;
|
assign cpu_gie = cpu_dbg_cc[1];
|
assign cpu_gie = cpu_dbg_cc[1];
|
|
|
`ifdef USE_TRAP
|
`ifdef USE_TRAP
|
//
|
//
|
Line 331... |
Line 394... |
//
|
//
|
reg wdbus_ack;
|
reg wdbus_ack;
|
reg [(AW-1):0] r_wdbus_data;
|
reg [(AW-1):0] r_wdbus_data;
|
wire [31:0] wdbus_data;
|
wire [31:0] wdbus_data;
|
wire [14:0] wdbus_ignored_data;
|
wire [14:0] wdbus_ignored_data;
|
wire reset_wdbus_timer, wdbus_int, wdbus_ack_ignored, wdbus_stall;
|
wire reset_wdbus_timer, wdbus_int;
|
assign reset_wdbus_timer = ((o_wb_cyc)&&((o_wb_stb)||(i_wb_ack)));
|
assign reset_wdbus_timer = ((o_wb_cyc)&&((o_wb_stb)||(i_wb_ack)));
|
// o_wb_cyc, o_wb_stb, o_wb_we, o_wb_addr, o_wb_data,
|
wbwatchdog #(14) watchbus(i_clk,(cpu_reset)||(reset_wdbus_timer),
|
// i_wb_ack, i_wb_stall, i_wb_data, i_wb_err,
|
o_wb_cyc, 14'h2000, wdbus_int);
|
ziptimer #(15) watchbus(i_clk, (cpu_reset), o_wb_cyc,
|
|
reset_wdbus_timer, reset_wdbus_timer, 1'b1, 15'h2000,
|
|
wdbus_ack_ignored, wdbus_stall, wdbus_ignored_data,
|
|
wdbus_int);
|
|
initial r_wdbus_data = 0;
|
initial r_wdbus_data = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (wdbus_int)
|
if ((wdbus_int)||(cpu_ext_err))
|
r_wdbus_data = o_wb_addr;
|
r_wdbus_data = o_wb_addr;
|
assign wdbus_data = { {(32-AW){1'b0}}, r_wdbus_data };
|
assign wdbus_data = { {(32-AW){1'b0}}, r_wdbus_data };
|
initial wdbus_ack = 1'b0;
|
initial wdbus_ack = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
wdbus_ack <= ((sys_cyc)&&(sys_stb)&&(sys_addr == 5'h02));
|
wdbus_ack <= ((sys_cyc)&&(sys_stb)&&(sys_addr == 5'h02));
|
Line 360... |
Line 419... |
//
|
//
|
// The master counters will, in general, not be reset. They'll be used
|
// The master counters will, in general, not be reset. They'll be used
|
// for an overall counter.
|
// for an overall counter.
|
//
|
//
|
// Master task counter
|
// Master task counter
|
wire mtc_ack, mtc_stall, mtc_int;
|
wire mtc_ack, mtc_stall;
|
wire [31:0] mtc_data;
|
wire [31:0] mtc_data;
|
zipcounter mtask_ctr(i_clk, (~cpu_halt), sys_cyc,
|
zipcounter mtask_ctr(i_clk, (~cpu_halt), sys_cyc,
|
(sys_stb)&&(sys_addr == `MSTR_TASK_CTR),
|
(sys_stb)&&(sys_addr == `MSTR_TASK_CTR),
|
sys_we, sys_data,
|
sys_we, sys_data,
|
mtc_ack, mtc_stall, mtc_data, mtc_int);
|
mtc_ack, mtc_stall, mtc_data, mtc_int);
|
|
|
// Master Operand Stall counter
|
// Master Operand Stall counter
|
wire moc_ack, moc_stall, moc_int;
|
wire moc_ack, moc_stall;
|
wire [31:0] moc_data;
|
wire [31:0] moc_data;
|
zipcounter mmstall_ctr(i_clk,(cpu_op_stall), sys_cyc,
|
zipcounter mmstall_ctr(i_clk,(cpu_op_stall), sys_cyc,
|
(sys_stb)&&(sys_addr == `MSTR_MSTL_CTR),
|
(sys_stb)&&(sys_addr == `MSTR_MSTL_CTR),
|
sys_we, sys_data,
|
sys_we, sys_data,
|
moc_ack, moc_stall, moc_data, moc_int);
|
moc_ack, moc_stall, moc_data, moc_int);
|
|
|
// Master PreFetch-Stall counter
|
// Master PreFetch-Stall counter
|
wire mpc_ack, mpc_stall, mpc_int;
|
wire mpc_ack, mpc_stall;
|
wire [31:0] mpc_data;
|
wire [31:0] mpc_data;
|
zipcounter mpstall_ctr(i_clk,(cpu_pf_stall), sys_cyc,
|
zipcounter mpstall_ctr(i_clk,(cpu_pf_stall), sys_cyc,
|
(sys_stb)&&(sys_addr == `MSTR_PSTL_CTR),
|
(sys_stb)&&(sys_addr == `MSTR_PSTL_CTR),
|
sys_we, sys_data,
|
sys_we, sys_data,
|
mpc_ack, mpc_stall, mpc_data, mpc_int);
|
mpc_ack, mpc_stall, mpc_data, mpc_int);
|
|
|
// Master Instruction counter
|
// Master Instruction counter
|
wire mic_ack, mic_stall, mic_int;
|
wire mic_ack, mic_stall;
|
wire [31:0] mic_data;
|
wire [31:0] mic_data;
|
zipcounter mins_ctr(i_clk,(cpu_i_count), sys_cyc,
|
zipcounter mins_ctr(i_clk,(cpu_i_count), sys_cyc,
|
(sys_stb)&&(sys_addr == `MSTR_INST_CTR),
|
(sys_stb)&&(sys_addr == `MSTR_INST_CTR),
|
sys_we, sys_data,
|
sys_we, sys_data,
|
mic_ack, mic_stall, mic_data, mic_int);
|
mic_ack, mic_stall, mic_data, mic_int);
|
Line 396... |
Line 455... |
//
|
//
|
// The user counters are different from those of the master. They will
|
// The user counters are different from those of the master. They will
|
// be reset any time a task is given control of the CPU.
|
// be reset any time a task is given control of the CPU.
|
//
|
//
|
// User task counter
|
// User task counter
|
wire utc_ack, utc_stall, utc_int;
|
wire utc_ack, utc_stall;
|
wire [31:0] utc_data;
|
wire [31:0] utc_data;
|
zipcounter utask_ctr(i_clk,(~cpu_halt)&&(cpu_gie), sys_cyc,
|
zipcounter utask_ctr(i_clk,(~cpu_halt)&&(cpu_gie), sys_cyc,
|
(sys_stb)&&(sys_addr == `USER_TASK_CTR),
|
(sys_stb)&&(sys_addr == `USER_TASK_CTR),
|
sys_we, sys_data,
|
sys_we, sys_data,
|
utc_ack, utc_stall, utc_data, utc_int);
|
utc_ack, utc_stall, utc_data, utc_int);
|
|
|
// User Op-Stall counter
|
// User Op-Stall counter
|
wire uoc_ack, uoc_stall, uoc_int;
|
wire uoc_ack, uoc_stall;
|
wire [31:0] uoc_data;
|
wire [31:0] uoc_data;
|
zipcounter umstall_ctr(i_clk,(cpu_op_stall)&&(cpu_gie), sys_cyc,
|
zipcounter umstall_ctr(i_clk,(cpu_op_stall)&&(cpu_gie), sys_cyc,
|
(sys_stb)&&(sys_addr == `USER_MSTL_CTR),
|
(sys_stb)&&(sys_addr == `USER_MSTL_CTR),
|
sys_we, sys_data,
|
sys_we, sys_data,
|
uoc_ack, uoc_stall, uoc_data, uoc_int);
|
uoc_ack, uoc_stall, uoc_data, uoc_int);
|
|
|
// User PreFetch-Stall counter
|
// User PreFetch-Stall counter
|
wire upc_ack, upc_stall, upc_int;
|
wire upc_ack, upc_stall;
|
wire [31:0] upc_data;
|
wire [31:0] upc_data;
|
zipcounter upstall_ctr(i_clk,(cpu_pf_stall)&&(cpu_gie), sys_cyc,
|
zipcounter upstall_ctr(i_clk,(cpu_pf_stall)&&(cpu_gie), sys_cyc,
|
(sys_stb)&&(sys_addr == `USER_PSTL_CTR),
|
(sys_stb)&&(sys_addr == `USER_PSTL_CTR),
|
sys_we, sys_data,
|
sys_we, sys_data,
|
upc_ack, upc_stall, upc_data, upc_int);
|
upc_ack, upc_stall, upc_data, upc_int);
|
|
|
// User instruction counter
|
// User instruction counter
|
wire uic_ack, uic_stall, uic_int;
|
wire uic_ack, uic_stall;
|
wire [31:0] uic_data;
|
wire [31:0] uic_data;
|
zipcounter uins_ctr(i_clk,(cpu_i_count)&&(cpu_gie), sys_cyc,
|
zipcounter uins_ctr(i_clk,(cpu_i_count)&&(cpu_gie), sys_cyc,
|
(sys_stb)&&(sys_addr == `USER_INST_CTR),
|
(sys_stb)&&(sys_addr == `USER_INST_CTR),
|
sys_we, sys_data,
|
sys_we, sys_data,
|
uic_ack, uic_stall, uic_data, uic_int);
|
uic_ack, uic_stall, uic_data, uic_int);
|
Line 467... |
Line 526... |
`endif // INCLUDE_ACCOUNTING_COUNTERS
|
`endif // INCLUDE_ACCOUNTING_COUNTERS
|
|
|
//
|
//
|
// The DMA Controller
|
// The DMA Controller
|
//
|
//
|
wire dmac_int, dmac_stb, dc_err;
|
wire dmac_stb, dc_err;
|
wire [31:0] dmac_data;
|
wire [31:0] dmac_data;
|
wire dmac_ack, dmac_stall;
|
wire dmac_ack, dmac_stall;
|
wire dc_cyc, dc_stb, dc_we, dc_ack, dc_stall;
|
wire dc_cyc, dc_stb, dc_we, dc_ack, dc_stall;
|
wire [31:0] dc_data;
|
wire [31:0] dc_data;
|
wire [(AW-1):0] dc_addr;
|
wire [(AW-1):0] dc_addr;
|
wire cpu_gbl_cyc;
|
wire cpu_gbl_cyc;
|
assign dmac_stb = (sys_stb)&&(sys_addr[4]);
|
assign dmac_stb = (sys_stb)&&(sys_addr[4]);
|
`define INCLUDE_DMA_CONTROLLER
|
|
`ifdef INCLUDE_DMA_CONTROLLER
|
`ifdef INCLUDE_DMA_CONTROLLER
|
wbdmac #(AW) dma_controller(i_clk,
|
wbdmac #(AW) dma_controller(i_clk,
|
sys_cyc, dmac_stb, sys_we,
|
sys_cyc, dmac_stb, sys_we,
|
sys_addr[1:0], sys_data,
|
sys_addr[1:0], sys_data,
|
dmac_ack, dmac_stall, dmac_data,
|
dmac_ack, dmac_stall, dmac_data,
|
// Need the outgoing DMAC wishbone bus
|
// Need the outgoing DMAC wishbone bus
|
dc_cyc, dc_stb, dc_we, dc_addr, dc_data,
|
dc_cyc, dc_stb, dc_we, dc_addr, dc_data,
|
dc_ack, dc_stall, ext_idata, dc_err,
|
dc_ack, dc_stall, ext_idata, dc_err,
|
// External device interrupts
|
// External device interrupts
|
{ {(32-EXTERNAL_INTERRUPTS){1'b0}}, i_ext_int },
|
{ 1'b0, alt_int_vector, 1'b0,
|
|
main_int_vector[14:1], 1'b0 },
|
// DMAC interrupt, for upon completion
|
// DMAC interrupt, for upon completion
|
dmac_int,
|
dmac_int);
|
// Whether or not the CPU wants the bus
|
// Whether or not the CPU wants the bus, and
|
cpu_gbl_cyc);
|
// thus we must kick the DMAC off.
|
|
// However, the logic required for this
|
|
// override never worked well, so here
|
|
// we just don't use it.
|
|
// cpu_gbl_cyc);
|
`else
|
`else
|
reg r_dmac_ack;
|
reg r_dmac_ack;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
r_dmac_ack <= (sys_cyc)&&(dmac_stb);
|
r_dmac_ack <= (sys_cyc)&&(dmac_stb);
|
assign dmac_ack = r_dmac_ack;
|
assign dmac_ack = r_dmac_ack;
|
Line 507... |
Line 570... |
assign dc_data = 32'h00;
|
assign dc_data = 32'h00;
|
|
|
assign dmac_int = 1'b0;
|
assign dmac_int = 1'b0;
|
`endif
|
`endif
|
|
|
|
wire ctri_sel;
|
|
reg ctri_ack;
|
|
assign ctri_sel = (sys_cyc)&&(sys_stb)&&(sys_addr == `CTRINT);
|
|
always @(posedge i_clk)
|
|
ctri_ack <= ctri_sel;
|
`ifdef INCLUDE_ACCOUNTING_COUNTERS
|
`ifdef INCLUDE_ACCOUNTING_COUNTERS
|
//
|
//
|
// Counter Interrupt controller
|
// Counter Interrupt controller
|
//
|
//
|
reg ctri_ack;
|
wire ctri_stall;
|
wire ctri_stall, ctri_int, ctri_sel;
|
|
wire [7:0] ctri_vector;
|
|
wire [31:0] ctri_data;
|
wire [31:0] ctri_data;
|
assign ctri_sel = (sys_cyc)&&(sys_stb)&&(sys_addr == `CTRINT);
|
|
assign ctri_vector = { mtc_int, moc_int, mpc_int, mic_int,
|
generate
|
utc_int, uoc_int, upc_int, uic_int };
|
if (EXTERNAL_INTERRUPTS <= 9)
|
icontrol #(8) ctri(i_clk, cpu_reset, (ctri_sel)&&(sys_addr==`CTRINT),
|
begin
|
sys_data, ctri_data, ctri_vector, ctri_int);
|
icontrol #(8) ctri(i_clk, cpu_reset, (ctri_sel),
|
always @(posedge i_clk)
|
sys_data, ctri_data, alt_int_vector[7:0],
|
ctri_ack <= ctri_sel;
|
ctri_int);
|
|
end else begin
|
|
icontrol #(8+(EXTERNAL_INTERRUPTS-9))
|
|
ctri(i_clk, cpu_reset, (ctri_sel),
|
|
sys_data, ctri_data,
|
|
alt_int_vector[(EXTERNAL_INTERRUPTS-1):0],
|
|
ctri_int);
|
|
end endgenerate
|
|
|
assign ctri_stall = 1'b0;
|
assign ctri_stall = 1'b0;
|
`else // INCLUDE_ACCOUNTING_COUNTERS
|
`else // INCLUDE_ACCOUNTING_COUNTERS
|
reg ctri_ack;
|
|
|
generate
|
|
if (EXTERNAL_INTERRUPTS <= 9)
|
|
begin
|
wire ctri_stall, ctri_int;
|
wire ctri_stall, ctri_int;
|
wire [31:0] ctri_data;
|
wire [31:0] ctri_data;
|
assign ctri_stall = 1'b0;
|
assign ctri_stall = 1'b0;
|
assign ctri_data = 32'h0000;
|
assign ctri_data = 32'h0000;
|
assign ctri_int = 1'b0;
|
assign ctri_int = 1'b0;
|
|
end else begin
|
always @(posedge i_clk)
|
icontrol #(EXTERNAL_INTERRUPTS-9)
|
ctri_ack <= (sys_cyc)&&(sys_stb)&&(sys_addr == `CTRINT);
|
ctri(i_clk, cpu_reset, (ctri_sel),
|
|
sys_data, ctri_data,
|
|
alt_int_vector[(EXTERNAL_INTERRUPTS-10):0],
|
|
ctri_int);
|
|
end endgenerate
|
`endif // INCLUDE_ACCOUNTING_COUNTERS
|
`endif // INCLUDE_ACCOUNTING_COUNTERS
|
|
|
|
|
//
|
//
|
// Timer A
|
// Timer A
|
//
|
//
|
wire tma_ack, tma_stall, tma_int;
|
wire tma_ack, tma_stall;
|
wire [31:0] tma_data;
|
wire [31:0] tma_data;
|
ziptimer timer_a(i_clk, cpu_reset, ~cmd_halt,
|
ziptimer timer_a(i_clk, cpu_reset, ~cmd_halt,
|
sys_cyc, (sys_stb)&&(sys_addr == `TIMER_A), sys_we,
|
sys_cyc, (sys_stb)&&(sys_addr == `TIMER_A), sys_we,
|
sys_data,
|
sys_data,
|
tma_ack, tma_stall, tma_data, tma_int);
|
tma_ack, tma_stall, tma_data, tma_int);
|
|
|
//
|
//
|
// Timer B
|
// Timer B
|
//
|
//
|
wire tmb_ack, tmb_stall, tmb_int;
|
wire tmb_ack, tmb_stall;
|
wire [31:0] tmb_data;
|
wire [31:0] tmb_data;
|
ziptimer timer_b(i_clk, cpu_reset, ~cmd_halt,
|
ziptimer timer_b(i_clk, cpu_reset, ~cmd_halt,
|
sys_cyc, (sys_stb)&&(sys_addr == `TIMER_B), sys_we,
|
sys_cyc, (sys_stb)&&(sys_addr == `TIMER_B), sys_we,
|
sys_data,
|
sys_data,
|
tmb_ack, tmb_stall, tmb_data, tmb_int);
|
tmb_ack, tmb_stall, tmb_data, tmb_int);
|
|
|
//
|
//
|
// Timer C
|
// Timer C
|
//
|
//
|
wire tmc_ack, tmc_stall, tmc_int;
|
wire tmc_ack, tmc_stall;
|
wire [31:0] tmc_data;
|
wire [31:0] tmc_data;
|
ziptimer timer_c(i_clk, cpu_reset, ~cmd_halt,
|
ziptimer timer_c(i_clk, cpu_reset, ~cmd_halt,
|
sys_cyc, (sys_stb)&&(sys_addr == `TIMER_C), sys_we,
|
sys_cyc, (sys_stb)&&(sys_addr == `TIMER_C), sys_we,
|
sys_data,
|
sys_data,
|
tmc_ack, tmc_stall, tmc_data, tmc_int);
|
tmc_ack, tmc_stall, tmc_data, tmc_int);
|
|
|
//
|
//
|
// JIFFIES
|
// JIFFIES
|
//
|
//
|
wire jif_ack, jif_stall, jif_int;
|
wire jif_ack, jif_stall;
|
wire [31:0] jif_data;
|
wire [31:0] jif_data;
|
zipjiffies jiffies(i_clk, ~cmd_halt,
|
zipjiffies jiffies(i_clk, ~cmd_halt,
|
sys_cyc, (sys_stb)&&(sys_addr == `JIFFIES), sys_we,
|
sys_cyc, (sys_stb)&&(sys_addr == `JIFFIES), sys_we,
|
sys_data,
|
sys_data,
|
jif_ack, jif_stall, jif_data, jif_int);
|
jif_ack, jif_stall, jif_data, jif_int);
|
|
|
//
|
//
|
// The programmable interrupt controller peripheral
|
// The programmable interrupt controller peripheral
|
//
|
//
|
wire pic_interrupt;
|
wire pic_interrupt;
|
wire [(5+EXTERNAL_INTERRUPTS):0] int_vector;
|
generate
|
assign int_vector = { i_ext_int, ctri_int, tma_int, tmb_int, tmc_int,
|
if (EXTERNAL_INTERRUPTS < 9)
|
jif_int, dmac_int };
|
begin
|
icontrol #(6+EXTERNAL_INTERRUPTS) pic(i_clk, cpu_reset,
|
icontrol #(6+EXTERNAL_INTERRUPTS) pic(i_clk, cpu_reset,
|
(sys_cyc)&&(sys_stb)&&(sys_we)
|
(sys_cyc)&&(sys_stb)&&(sys_we)
|
&&(sys_addr==`INTCTRL),
|
&&(sys_addr==`INTCTRL),
|
sys_data, pic_data,
|
sys_data, pic_data,
|
int_vector, pic_interrupt);
|
main_int_vector[(6+EXTERNAL_INTERRUPTS-1):0], pic_interrupt);
|
|
end else begin
|
|
icontrol #(15) pic(i_clk, cpu_reset,
|
|
(sys_cyc)&&(sys_stb)&&(sys_we)
|
|
&&(sys_addr==`INTCTRL),
|
|
sys_data, pic_data,
|
|
main_int_vector[14:0], pic_interrupt);
|
|
end endgenerate
|
|
|
wire pic_stall;
|
wire pic_stall;
|
assign pic_stall = 1'b0;
|
assign pic_stall = 1'b0;
|
reg pic_ack;
|
reg pic_ack;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
pic_ack <= (sys_cyc)&&(sys_stb)&&(sys_addr == `INTCTRL);
|
pic_ack <= (sys_cyc)&&(sys_stb)&&(sys_addr == `INTCTRL);
|
Line 605... |
Line 693... |
wire [31:0] cpu_data, wb_data;
|
wire [31:0] cpu_data, wb_data;
|
wire cpu_ack, cpu_stall, cpu_err;
|
wire cpu_ack, cpu_stall, cpu_err;
|
wire [31:0] cpu_dbg_data;
|
wire [31:0] cpu_dbg_data;
|
assign cpu_dbg_we = ((dbg_cyc)&&(dbg_stb)&&(~cmd_addr[5])
|
assign cpu_dbg_we = ((dbg_cyc)&&(dbg_stb)&&(~cmd_addr[5])
|
&&(dbg_we)&&(dbg_addr));
|
&&(dbg_we)&&(dbg_addr));
|
zipcpu #(RESET_ADDRESS,ADDRESS_WIDTH,LGICACHE)
|
zipcpu #(RESET_ADDRESS,ADDRESS_WIDTH,LGICACHE, IMPLEMENT_MPY,
|
|
IMPLEMENT_DIVIDE, IMPLEMENT_FPU, IMPLEMENT_LOCK)
|
thecpu(i_clk, cpu_reset, pic_interrupt,
|
thecpu(i_clk, cpu_reset, pic_interrupt,
|
cpu_halt, cmd_clear_pf_cache, cmd_addr[4:0], cpu_dbg_we,
|
cpu_halt, cmd_clear_pf_cache, cmd_addr[4:0], cpu_dbg_we,
|
dbg_idata, cpu_dbg_stall, cpu_dbg_data,
|
dbg_idata, cpu_dbg_stall, cpu_dbg_data,
|
cpu_dbg_cc, cpu_break,
|
cpu_dbg_cc, cpu_break,
|
cpu_gbl_cyc, cpu_gbl_stb,
|
cpu_gbl_cyc, cpu_gbl_stb,
|
Line 706... |
Line 795... |
:((pic_ack|ctri_ack)?((pic_ack)?pic_data:ctri_data)
|
:((pic_ack|ctri_ack)?((pic_ack)?pic_data:ctri_data)
|
:((wdbus_ack)?wdbus_data:(ext_idata))));
|
:((wdbus_ack)?wdbus_data:(ext_idata))));
|
|
|
assign sys_stall = (tma_stall | tmb_stall | tmc_stall | jif_stall
|
assign sys_stall = (tma_stall | tmb_stall | tmc_stall | jif_stall
|
| wdt_stall | ctri_stall | actr_stall
|
| wdt_stall | ctri_stall | actr_stall
|
| pic_stall | dmac_stall | wdbus_stall);
|
| pic_stall | dmac_stall);
|
assign cpu_stall = (sys_stall)|(cpu_ext_stall);
|
assign cpu_stall = (sys_stall)|(cpu_ext_stall);
|
assign sys_ack = (tmr_ack|wdt_ack|ctri_ack|actr_ack|pic_ack|dmac_ack|wdbus_ack);
|
assign sys_ack = (tmr_ack|wdt_ack|ctri_ack|actr_ack|pic_ack|dmac_ack|wdbus_ack);
|
assign cpu_ack = (sys_ack)||(cpu_ext_ack);
|
assign cpu_ack = (sys_ack)||(cpu_ext_ack);
|
assign cpu_err = (cpu_ext_err)&&(cpu_gbl_cyc);
|
assign cpu_err = (cpu_ext_err)&&(cpu_gbl_cyc);
|
|
|