Line 62... |
Line 62... |
// Creator: Dan Gisselquist, Ph.D.
|
// Creator: Dan Gisselquist, Ph.D.
|
// Gisselquist Technology, LLC
|
// Gisselquist Technology, LLC
|
//
|
//
|
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Copyright (C) 2015, Gisselquist Technology, LLC
|
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
|
//
|
//
|
// This program is free software (firmware): you can redistribute it and/or
|
// This program is free software (firmware): you can redistribute it and/or
|
// modify it under the terms of the GNU General Public License as published
|
// modify it under the terms of the GNU General Public License as published
|
// by the Free Software Foundation, either version 3 of the License, or (at
|
// by the Free Software Foundation, either version 3 of the License, or (at
|
// your option) any later version.
|
// your option) any later version.
|
Line 171... |
Line 171... |
`endif
|
`endif
|
);
|
);
|
parameter RESET_ADDRESS=24'h0100000, ADDRESS_WIDTH=24,
|
parameter RESET_ADDRESS=24'h0100000, ADDRESS_WIDTH=24,
|
LGICACHE=10, START_HALTED=1, EXTERNAL_INTERRUPTS=1,
|
LGICACHE=10, START_HALTED=1, EXTERNAL_INTERRUPTS=1,
|
`ifdef OPT_MULTIPLY
|
`ifdef OPT_MULTIPLY
|
IMPLEMENT_MPY = 1,
|
IMPLEMENT_MPY = `OPT_MULTIPLY,
|
`else
|
`else
|
IMPLEMENT_MPY = 0,
|
IMPLEMENT_MPY = 0,
|
`endif
|
`endif
|
`ifdef OPT_DIVIDE
|
`ifdef OPT_DIVIDE
|
IMPLEMENT_DIVIDE=1,
|
IMPLEMENT_DIVIDE=1,
|
Line 367... |
Line 367... |
//
|
//
|
// The WATCHDOG Timer
|
// The WATCHDOG Timer
|
//
|
//
|
wire wdt_ack, wdt_stall, wdt_reset;
|
wire wdt_ack, wdt_stall, wdt_reset;
|
wire [31:0] wdt_data;
|
wire [31:0] wdt_data;
|
ziptimer watchdog(i_clk, cpu_reset, ~cmd_halt,
|
ziptimer #(32,31,0)
|
|
watchdog(i_clk, cpu_reset, ~cmd_halt,
|
sys_cyc, ((sys_stb)&&(sys_addr == `WATCHDOG)), sys_we,
|
sys_cyc, ((sys_stb)&&(sys_addr == `WATCHDOG)), sys_we,
|
sys_data,
|
sys_data,
|
wdt_ack, wdt_stall, wdt_data, wdt_reset);
|
wdt_ack, wdt_stall, wdt_data, wdt_reset);
|
|
|
//
|
//
|
Line 521... |
Line 522... |
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]);
|
`ifdef INCLUDE_DMA_CONTROLLER
|
`ifdef INCLUDE_DMA_CONTROLLER
|
wbdmac #(AW) dma_controller(i_clk,
|
wbdmac #(AW) dma_controller(i_clk, cpu_reset,
|
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,
|
Line 533... |
Line 534... |
// External device interrupts
|
// External device interrupts
|
{ 1'b0, alt_int_vector, 1'b0,
|
{ 1'b0, alt_int_vector, 1'b0,
|
main_int_vector[14:1], 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, and
|
|
// 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 675... |
Line 670... |
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, IMPLEMENT_MPY,
|
zipcpu #(
|
IMPLEMENT_DIVIDE, IMPLEMENT_FPU, IMPLEMENT_LOCK)
|
.RESET_ADDRESS(RESET_ADDRESS),
|
|
.ADDRESS_WIDTH(ADDRESS_WIDTH),
|
|
.LGICACHE(LGICACHE),
|
|
.IMPLEMENT_MPY(IMPLEMENT_MPY),
|
|
.IMPLEMENT_DIVIDE(IMPLEMENT_DIVIDE),
|
|
.IMPLEMENT_FPU(IMPLEMENT_FPU),
|
|
.IMPLEMENT_LOCK(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 724... |
Line 726... |
// Return debug response values
|
// Return debug response values
|
assign dbg_odata = (~dbg_addr)?cmd_data
|
assign dbg_odata = (~dbg_addr)?cmd_data
|
:((~cmd_addr[5])?cpu_dbg_data : wb_data);
|
:((~cmd_addr[5])?cpu_dbg_data : wb_data);
|
initial dbg_ack = 1'b0;
|
initial dbg_ack = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
dbg_ack <= (dbg_cyc)&&(~dbg_stall);
|
dbg_ack <= (dbg_cyc)&&(dbg_stb)&&(~dbg_stall);
|
assign dbg_stall=(dbg_cyc)&&((~sys_dbg_cyc)||(sys_stall))&&(dbg_addr);
|
assign dbg_stall=(dbg_cyc)&&((~sys_dbg_cyc)||(sys_stall))&&(dbg_addr);
|
|
|
// Now for the external wishbone bus
|
// Now for the external wishbone bus
|
// Need to arbitrate between the flash cache and the CPU
|
// Need to arbitrate between the flash cache and the CPU
|
// The way this works, though, the CPU will stall once the flash
|
// The way this works, though, the CPU will stall once the flash
|