OpenCores
URL https://opencores.org/ocsvn/xulalx25soc/xulalx25soc/trunk

Subversion Repositories xulalx25soc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /xulalx25soc
    from Rev 116 to Rev 117
    Reverse comparison

Rev 116 → Rev 117

/trunk/Makefile
33,7 → 33,7
##
##
.PHONY: all
all: datestamp verilated sw bench bit
all: datestamp verilated sw bench
# Could also depend upon load, if desired, but not necessary
BENCH := `find bench -name Makefile` `find bench -name "*.cpp"` `find bench -name "*.h"`
RTL := `find rtl -name "*.v"` `find rtl -name Makefile`
65,8 → 65,8
cd rtl ; $(MAKE) --no-print-directory
 
.PHONY: bench
bench:
cd bench ; $(MAKE) --no-print-directory
bench: rtl
cd bench/cpp ; $(MAKE) --no-print-directory
 
.PHONY: sw
sw:
/trunk/README.md
0,0 → 1,59
# Description
 
This project attempts to take two separate projects, the ZipCPU and Xess.com's XuLA2-LX25, and merge them together into a single system on a chip implementation. As currently implemented, this SoC offers the following peripherals to the ZipCPU within:
 
- External peripherals
 
- 14 GPIO inputs, 15 GPIO outputs
- PWM output (can be swapped for an FM transmitter ...)
- Rx and Tx UART ports
- 1MB SPI flash, together with a read/write controller
- 32MB SDRAM capable of non-stop pipeline reads and writes
- SD Card, sharing the SPI wires of the flash
 
- Internal peripherals
 
- Real-time clock and date4
- Access to the FPGA configuration port, for unattended updates
- ZipCPU debug/configuration port access from JTAG
 
- ZipCPU peripherals
 
- 3x timers, each of which can be programmed either in a one shot mode or as a repeating interval timer
- A watchdog timer, and a wishbone bus watchdog timer
- Two interrupt controllers
- Direct Memory Access (DMA) controller for unattended memory movement
 
# Current Status
 
The SoC is fully functional. Keeping the project from being complete, however,
is the lack of an integrated specification document. (Specification documents
do exist, however, for many of the peripheral components.)
 
# Unique Features
 
This System on a Chip (SoC) controller has some unique features associated with
it, above and beyond the peripherals listed above. Primary among those is the
JTAG to 32-bit wishbone master conversion. This makes it possible for an
external entity to read from or write to the wishbone bus. Uses include
verifying whether or not peripherals work, as well as configuring the CPU,
memory and flash for whatever purpose one might have. This particular
capability was designed so that host (i.e. FPGA control) programs (external
to the FPGA) can call a common set of bus interface functions to communicate
with the FPGA, regardless of how the bus was implemented.
 
A second unique feature is a PWM driver that spreads its digital energy into
higher (non-auditory) frequencies which can then be filtered out easier
with a simple low-pass filter. As an example, sending a zero, or half-pulse
width, will result in alternating digital ones and zeros from the driver. While
I expect this will have a pleasing effect on the ear, especially since these
transactions will be outside of the normal hearing range, this is the first time
I have tried it and the jury's still out regarding whether or not it works or
even works well.
 
Finally, while it may not really be that unique, this core does feature a fully
functional SDRAM controller capable of sustaining one read cycle (or write
cycle) every two clocks when pipelined. Unlike many other dynamic memory
controllers, this one was _not_ created from a proprietary, closed source,
memory interface generation facility--so it is available for anyone to examine,
study, and even comment upon and improve--subject to the conditions of the GPL.
/trunk/bench/cpp/Makefile
46,7 → 46,7
OBJDIR := obj-pc
YYMMDD := `date +%Y%m%d`
VOBJDR := ../../rtl/obj_dir
VROOT := /usr/share/verilator
VROOT ?= $(shell bash -c 'verilator -V|grep VERILATOR_ROOT | head -1 | sed -e " s/^.*=\s*//"')
VINC := -I$(VROOT)/include -I$(VOBJDR)
CFLAGS := -c -g -Wall -I. $(VINC)
# Now return to the "all" target, and fill in some details
/trunk/bench/cpp/busmaster_tb.cpp
116,6 → 116,8
#ifdef XULA25
sdcard_miso = m_sdcard(m_core->o_sd_cs_n, m_core->o_spi_sck,
m_core->o_spi_mosi);
#else
sdcard_miso = 1;
#endif
 
if ((m_core->o_sf_cs_n)&&(m_core->o_sd_cs_n))
138,7 → 140,7
m_core->v__DOT__serialport__DOT__r_setup);
PIPECMDR::tick();
 
// #define DEBUGGING_OUTPUT
#define DEBUGGING_OUTPUT
#ifdef DEBUGGING_OUTPUT
bool writeout = false;
/*
154,8 → 156,8
writeout = true;
*/
 
if ((m_core->v__DOT__wbu_cyc)&&(!m_core->v__DOT__wbu_we))
writeout = true;
// if ((m_core->v__DOT__wbu_cyc)&&(!m_core->v__DOT__wbu_we))
// writeout = true;
/*
if ((m_core->v__DOT__wbu_cyc)&&(!m_core->v__DOT__wbu_we))
writeout = true;
163,10 → 165,10
writeout = true;
*/
 
if ((m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_early_branch)
&&(m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction == 0x7883ffff))
m_busy+=2;
else if (m_busy > 0) m_busy--;
// if ((m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_early_branch)
// &&(m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction == 0x7883ffff))
// m_busy+=2;
// else if (m_busy > 0) m_busy--;
#define v__DOT__wb_addr v__DOT__dwb_addr
#define v__DOT__dwb_stall v__DOT__wb_stall
#define v__DOT__dwb_ack v__DOT__wb_ack
200,8 → 202,10
|((m_core->v__DOT__serialport__DOT__txmod__DOT__lcl_data)<<8)
|((m_core->v__DOT__serialport__DOT__txmod__DOT__baud_counter&0x0f)<<4)
|(m_core->v__DOT__serialport__DOT__txmod__DOT__state);
/*
if (tx_state != m_last_tx_state)
writeout = true;
*/
int bus_owner = m_core->v__DOT__wbu_zip_arbiter__DOT__r_a_owner;
bus_owner |= (m_core->v__DOT__wbu_cyc)?2:0;
bus_owner |= (m_core->v__DOT__dwb_cyc)?4:0;
214,8 → 218,10
#ifdef XULA25
bus_owner |= (m_core->v__DOT__zippy__DOT__ext_cyc)?512:0;
#endif
/*
if (bus_owner != m_last_bus_owner)
writeout = true;
*/
/*
writeout = (writeout)||(m_core->i_rx_stb)
||((m_core->o_tx_stb)&&(!m_core->i_tx_busy));
359,17 → 365,17
(m_core->v__DOT__zippy__DOT__thecpu__DOT__op_ce)?"k":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__op_stall)?"s":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__op_illegal)?"i":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__op_break)?"B":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__r_op_break)?"B":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__genblk5__DOT__r_op_lock)?"L":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__r_op_pipe)?"P":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__break_pending)?"p":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__op_gie)?"G":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__r_break_pending)?"p":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__r_op_gie)?"G":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__opvalid_alu)?"A":"-");
printf("|%s%s%s%s%s",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__alu_ce)?"a":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__alu_stall)?"s":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__doalu__DOT__genblk2__DOT__r_busy)?"B":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__alu_gie)?"G":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__r_alu_gie)?"G":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__r_alu_illegal)?"i":"-");
printf("|%s%s%s%2x %s%s%s %2d %2d",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__opvalid_mem)?"M":"-",
408,9 → 414,9
(m_core->v__DOT__zippy__DOT__thecpu__DOT__opvalid)?'O':'-',
m_core->v__DOT__zippy__DOT__thecpu__DOT__op_pc,
(m_core->v__DOT__zippy__DOT__thecpu__DOT__alu_valid)?'A':'-',
m_core->v__DOT__zippy__DOT__thecpu__DOT__alu_pc);
#ifdef XULA25
m_core->v__DOT__zippy__DOT__thecpu__DOT__r_alu_pc);
/*
// Prefetch debugging
printf(" [PC%08x,LST%08x]->[%d%s%s](%d,%08x/%08x)->%08x@%08x",
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf_pc,
427,23 → 433,16
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__r_last_cache,
m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction,
m_core->v__DOT__zippy__DOT__thecpu__DOT__instruction_pc);
#else
printf(" [PC%08x,R%08x]%s%s%s",
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf_pc,
m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__r_addr,
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__w_pc_out_of_bounds)?"OOB":" ",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__w_running_out_of_cache)?"RUN":" ",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__pf__DOT__w_ran_off_end_of_cache)?"END":" ");
#endif
*/
 
// Decode Stage debugging
// (nothing)
 
// Op Stage debugging
printf(" Op(%02x,%02x->%02x)",
m_core->v__DOT__zippy__DOT__thecpu__DOT__dcdOp,
m_core->v__DOT__zippy__DOT__thecpu__DOT__opn,
m_core->v__DOT__zippy__DOT__thecpu__DOT__opR);
// printf(" Op(%02x,%02x->%02x)",
// m_core->v__DOT__zippy__DOT__thecpu__DOT__dcdOp,
// m_core->v__DOT__zippy__DOT__thecpu__DOT__opn,
// m_core->v__DOT__zippy__DOT__thecpu__DOT__opR);
 
printf(" %s[%02x]=%08x(%08x)",
m_core->v__DOT__zippy__DOT__thecpu__DOT__wr_reg_ce?"WR":"--",
466,6 → 465,7
m_core->v__DOT__zippy__DOT__thecpu__DOT__mem_wreg);
 
// domem, the pipelined memory unit debugging
/*
printf(" M[%s@0x%08x]",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__opvalid_mem)
?((m_core->v__DOT__zippy__DOT__thecpu__DOT__opn&1)?"W":"R")
476,20 → 476,33
0
#endif
);
*/
 
/*
printf("%s%s",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__domem__DOT__cyc)?"B":"-",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__mem_rdbusy)?"r":"-");
/*
*/
#ifdef XULA25
printf(" %s-%s %04x/%04x",
(m_core->v__DOT__zippy__DOT__genblk10__DOT__pic__DOT__r_any)?"PIC":"pic",
(m_core->v__DOT__zippy__DOT__genblk10__DOT__pic__DOT__r_gie)?"INT":"( )",
m_core->v__DOT__zippy__DOT__genblk10__DOT__pic__DOT__r_int_enable,
m_core->v__DOT__zippy__DOT__genblk10__DOT__pic__DOT__r_int_state);
*/
#else
printf(" %s-%s %04x/%04x",
(m_core->v__DOT__runio__DOT__intcontroller__DOT__r_any)?"PIC":"pic",
(m_core->v__DOT__runio__DOT__intcontroller__DOT__r_gie)?"INT":"( )",
m_core->v__DOT__runio__DOT__intcontroller__DOT__r_int_enable,
m_core->v__DOT__runio__DOT__intcontroller__DOT__r_int_state);
#endif
 
/*
printf(" %s",
(m_core->v__DOT__zippy__DOT__thecpu__DOT__cc_invalid_for_dcd)?"CCI":" ");
*/
 
/*
// Illegal instruction debugging
printf(" ILL[%s%s%s%s%s%s]",
581,12 → 594,16
 
 
/*
printf(" DMAC[%d]: %08x/%08x/%08x(%03x) -- (%d,%d,%c)%c%c:@%08x-[%4d,%4d/%4d,%4d-#%4d]%08x",
printf(" DMAC[%d]: %08x/%08x/%08x(%03x)%d%d%d%d -- (%d,%d,%c)%c%c:@%08x-[%4d,%4d/%4d,%4d-#%4d]%08x",
m_core->v__DOT__zippy__DOT__dma_controller__DOT__dma_state,
m_core->v__DOT__zippy__DOT__dma_controller__DOT__cfg_waddr,
m_core->v__DOT__zippy__DOT__dma_controller__DOT__cfg_raddr,
m_core->v__DOT__zippy__DOT__dma_controller__DOT__cfg_len,
m_core->v__DOT__zippy__DOT__dma_controller__DOT__cfg_blocklen_sub_one,
m_core->v__DOT__zippy__DOT__dma_controller__DOT__last_read_request,
m_core->v__DOT__zippy__DOT__dma_controller__DOT__last_read_ack,
m_core->v__DOT__zippy__DOT__dma_controller__DOT__last_write_request,
m_core->v__DOT__zippy__DOT__dma_controller__DOT__last_write_ack,
m_core->v__DOT__zippy__DOT__dc_cyc,
// m_core->v__DOT__zippy__DOT__dc_stb,
(m_core->v__DOT__zippy__DOT__dma_controller__DOT__dma_state == 2)?1:0,
604,12 → 621,16
m_core->v__DOT__zippy__DOT__dma_controller__DOT__nwacks,
m_core->v__DOT__zippy__DOT__dma_controller__DOT__nwritten,
m_core->v__DOT__zippy__DOT__dc_data);
*/
 
#ifdef OPT_ZIPSYSTEM
printf(" %08x-PIC%08x",
m_core->v__DOT__zippy__DOT__main_int_vector,
m_core->v__DOT__zippy__DOT__pic_data);
*/
#endif
 
printf(" R0 = %08x", m_core->v__DOT__zippy__DOT__thecpu__DOT__regset[0]);
 
printf("\n"); fflush(stdout);
} m_last_writeout = writeout;
 
628,13 → 649,15
#endif // DEBUGGING_OUTPUT
}
 
#ifdef DEBUGGING_OUTPUT
bool dcd_ce(void) {
if (!m_core->v__DOT__zippy__DOT__thecpu__DOT__r_dcdvalid)
return true;
if (!m_core->v__DOT__zippy__DOT__thecpu__DOT__op_stall)
return true;
// if (!m_core->v__DOT__zippy__DOT__thecpu__DOT__op_stall)
// return true;
return false;
}
#endif
 
};
 
/trunk/doc/wishbone.html
45,6 → 45,32
<TR><TD><TT>1100_0000_0000_0000_0000_0000_0000_1111</TT></TD><TH align=right>1</TH><TD>User Instruction Counter</TD></TR>
<TR><TD><TT>1100_0000_0000_0000_0000_0000_0001_00xx</TT></TD><TH align=right>1</TH><TD>DMA Controller</TD></TR>
</TABLE>
<!--
<TABLE align=center>
<TR><TD><TT>1xxxxxx</TT></TD><TD>SDRAM</TD></TR>
<TR><TD><TT>01xxxxx</TT></TD><TD>Flash</TD></TR>
<TR><TD><TT>001xxxx</TT></TD><TD>Block RAM</TD></TR>
<TR><TD><TT>00011xx</TT></TD><TD>ICAPE</TD></TR>
<TR><TD><TT>000101x</TT></TD><TD>SD Card control</TD></TR>
<TR><TD><TT>00010011</TT></TD><TD>Scope</TD></TR>
<TR><TD><TT>00010010xxx</TT></TD><TD>RTC</TD></TR>
<TR><TD><TT>00010001xxx</TT></TD><TD>PWM/UART/Flash Control</TD></TR>
<TR><TD><TT>00010000xxx</TT></TD><TD>Other I/O</TD></TR>
<TR><TD><TT>0000xxxxxxx</TT></TD><TD>Bus Error</TD></TR>
</TABLE>
<TABLE align=center>
<TR><TD><TT>1xxxxxx</TT></TD><TD>SDRAM</TD></TR>
<TR><TD><TT>01xxxxx</TT></TD><TD>Flash</TD></TR>
<TR><TD><TT>00111xx</TT></TD><TD>Block RAM</TD></TR>
<TR><TD><TT>00110xx_xxxx</TT></TD><TD>ICAPE</TD></TR>
<TR><TD><TT>00101xx_xxx</TT></TD><TD>SD Card control</TD></TR>
<TR><TD><TT>00100yy_yyxx</TT></TD><TD>Scope</TD></TR>
<TR><TD><TT>00011yy_yxxx</TT></TD><TD>RTC</TD></TR>
<TR><TD><TT>00010yy_yfux</TT></TD><TD>PWM/UART/Flash Control</TD></TR>
<TR><TD><TT>00001yy_yxxx</TT></TD><TD>Other I/O</TD></TR>
<TR><TD><TT>00000</TT></TD><TD>Bus Error</TD></TR>
</TABLE>
-->
 
<h1 align=center>Primary (ZipSystem) Interrupt Controller Assignments</H1>
<TABLE align=center>
/trunk/rtl/builddate.v File deleted \ No newline at end of file
trunk/rtl/builddate.v Property changes : Deleted: svn:special ## -1 +0,0 ## -* \ No newline at end of property Index: trunk/rtl/Makefile =================================================================== --- trunk/rtl/Makefile (revision 116) +++ trunk/rtl/Makefile (revision 117) @@ -41,7 +41,7 @@ test: $(VDIRFB)/Vbusmaster__ALL.a CPUDR := cpu -CPUSOURCESnD := zipcpu.v cpuops.v pipefetch.v \ +CPUSOURCESnD := zipcpu.v cpuops.v cpudefs.v pipefetch.v \ pfcache.v idecode.v \ pipemem.v prefetch.v wbpriarbiter.v \ zipsystem.v zipcounter.v zipjiffies.v ziptimer.v zipbones.v \
/trunk/rtl/busmaster.v
89,10 → 89,10
//
`ifdef XULA25
`ifdef FANCY_ICAP_ACCESS
`define CFG_SCOPE // Only defined if we have the access ...
// `define CFG_SCOPE // Only defined if we have the access ...
`else
`ifdef SDCARD_ACCESS
`define SDCARD_SCOPE
// `define SDCARD_SCOPE
`endif
`endif
`endif
109,7 → 109,7
`define ZIP_SCOPE
`else // VERILATOR
`ifdef XULA25
`define ZIP_SCOPE
// `define ZIP_SCOPE
`endif // XULA25
`endif // VERILATOR
`endif // INCLUDE_ZIPCPU
234,7 → 234,7
`endif
);
`else
zipbones #(24'h2000,ZA,8,1)
zipbones #(24'h2000,ZA,10,1)
zippy(i_clk, 1'b0,
// Zippys wishbone interface
zip_cyc, zip_stb, zip_we, w_zip_addr, zip_data,
333,6 → 333,11
assign dwb_we = wbu_we;
assign dwb_stb = (wbu_stb);
assign dwb_cyc = (wbu_cyc);
assign wb_cyc = dwb_cyc;
assign wb_stb = dwb_stb;
assign wb_we = dwb_we;
assign wb_addr = dwb_addr;
assign wb_data = dwb_odata;
assign wbu_ack = dwb_ack;
assign wbu_stall = dwb_stall;
assign dwb_idata = wb_idata;
/trunk/rtl/cpu/cpudefs.v
63,8 → 63,8
// illegal instructions are quietly ignored and their behaviour is ...
// undefined. (Many get treated like NOOPs ...)
//
// I recommend setting this flag, although it can be taken out if area is
// critical ...
// I recommend setting this flag so highly, that I'm likely going to remove
// the option to turn this off in future versions of this CPU.
//
`define OPT_ILLEGAL_INSTRUCTION
//
191,9 → 191,7
//
// If you have the fabric to support this option, I recommend including it.
//
`ifdef XULA25
`define OPT_TRADITIONAL_PFCACHE
`endif
//
//
//
/trunk/rtl/cpu/wbarbiter.v
56,7 → 56,7
//
`define WBA_ALTERNATING
module wbarbiter(i_clk, i_rst,
// Bus A
// Bus A -- gets priority when not alternating
i_a_adr, i_a_dat, i_a_we, i_a_stb, i_a_cyc, o_a_ack, o_a_stall, o_a_err,
// Bus B
i_b_adr, i_b_dat, i_b_we, i_b_stb, i_b_cyc, o_b_ack, o_b_stall, o_b_err,
114,10 → 114,6
wire w_a_owner, w_b_owner;
`ifdef WBA_ALTERNATING
reg r_a_last_owner;
// Stall must be asserted on the same cycle the input master asserts
// the bus, if the bus isn't granted to him.
assign o_a_stall = (w_a_owner) ? i_stall : 1'b1;
assign o_b_stall = (w_b_owner) ? i_stall : 1'b1;
 
`endif
always @(posedge i_clk)
175,6 → 171,11
assign o_a_ack = (w_a_owner) ? i_ack : 1'b0;
assign o_b_ack = (w_b_owner) ? i_ack : 1'b0;
 
// Stall must be asserted on the same cycle the input master asserts
// the bus, if the bus isn't granted to him.
assign o_a_stall = (w_a_owner) ? i_stall : 1'b1;
assign o_b_stall = (w_b_owner) ? i_stall : 1'b1;
 
//
//
assign o_a_err = (w_a_owner) ? i_err : 1'b0;
/trunk/rtl/cpu/wbdmac.v
189,7 → 189,7
// When the slave wishbone writes, and we are in this
// (ready) configuration, then allow the DMA to be controlled
// and thus to start.
if ((i_swb_cyc)&&(i_swb_stb)&&(i_swb_we))
if ((i_swb_stb)&&(i_swb_we))
begin
case(i_swb_addr)
2'b00: begin
340,8 → 340,7
always @(posedge i_clk)
if (dma_state == `DMA_IDLE)
begin
if ((i_swb_cyc)&&(i_swb_stb)&&(i_swb_we)
&&(i_swb_addr==2'b00))
if ((i_swb_stb)&&(i_swb_we)&&(i_swb_addr==2'b00))
cfg_err <= 1'b0;
end else if (((i_mwb_err)&&(o_mwb_cyc))||(abort))
cfg_err <= 1'b1;
366,7 → 365,7
always @(posedge i_clk)
if ((dma_state == `DMA_READ_REQ)||(dma_state == `DMA_READ_ACK))
begin
if (i_mwb_ack)
if ((i_mwb_ack)&&((~o_mwb_stb)||(i_mwb_stall)))
last_read_ack <= (nread+2 == nracks);
else
last_read_ack <= (nread+1 == nracks);
390,7 → 389,7
always @(posedge i_clk)
if((dma_state == `DMA_WRITE_REQ)||(dma_state == `DMA_WRITE_ACK))
begin
if (i_mwb_ack)
if ((i_mwb_ack)&&((~o_mwb_stb)||(i_mwb_stall)))
last_write_ack <= (nwacks+2 == nwritten);
else
last_write_ack <= (nwacks+1 == nwritten);
457,13 → 456,13
// but ack it anyway. In other words, before writing to the device,
// double check that it isn't busy, and then write.
always @(posedge i_clk)
o_swb_ack <= (i_swb_cyc)&&(i_swb_stb);
o_swb_ack <= (i_swb_stb);
 
assign o_swb_stall = 1'b0;
 
initial abort = 1'b0;
always @(posedge i_clk)
abort <= (i_rst)||((i_swb_cyc)&&(i_swb_stb)&&(i_swb_we)
abort <= (i_rst)||((i_swb_stb)&&(i_swb_we)
&&(i_swb_addr == 2'b00)
&&(i_swb_data == 32'hffed0000));
 
/trunk/rtl/cpu/zipcounter.v
64,7 → 64,7
initial o_int = 0;
initial o_wb_data = 32'h00;
always @(posedge i_clk)
if ((i_wb_cyc)&&(i_wb_stb)&&(i_wb_we))
if ((i_wb_stb)&&(i_wb_we))
{ o_int, o_wb_data } <= { 1'b0, i_wb_data };
else if (i_ce)
{ o_int, o_wb_data } <= o_wb_data+{{(BW-1){1'b0}},1'b1};
73,6 → 73,6
 
initial o_wb_ack = 1'b0;
always @(posedge i_clk)
o_wb_ack <= (i_wb_cyc)&&(i_wb_stb);
o_wb_ack <= (i_wb_stb);
assign o_wb_stall = 1'b0;
endmodule
/trunk/rtl/cpu/zipcpu.v
7,7 → 7,9
// Purpose: This is the top level module holding the core of the Zip CPU
// together. The Zip CPU is designed to be as simple as possible.
// (actual implementation aside ...) The instruction set is about as
// RISC as you can get, there are only 16 instruction types supported.
// RISC as you can get, with only 26 instruction types currently supported.
// (There are still 8-instruction Op-Codes reserved for floating point,
// and 5 which can be used for transactions not requiring registers.)
// Please see the accompanying spec.pdf file for a description of these
// instructions.
//
26,10 → 28,11
//
// 4. Write-back Results
//
// Further information about the inner workings of this CPU may be
// found in the spec.pdf file. (The documentation within this file
// had become out of date and out of sync with the spec.pdf, so look
// to the spec.pdf for accurate and up to date information.)
// Further information about the inner workings of this CPU, such as
// what causes pipeline stalls, may be found in the spec.pdf file. (The
// documentation within this file had become out of date and out of sync
// with the spec.pdf, so look to the spec.pdf for accurate and up to date
// information.)
//
//
// In general, the pipelining is controlled by three pieces of logic
137,7 → 140,7
`endif
);
parameter RESET_ADDRESS=32'h0100000, ADDRESS_WIDTH=24,
LGICACHE=6;
LGICACHE=8;
`ifdef OPT_MULTIPLY
parameter IMPLEMENT_MPY = `OPT_MULTIPLY;
`else
206,8 → 209,8
// (BUS, TRAP,ILL,BREAKEN,STEP,GIE,SLEEP ), V, N, C, Z
reg [3:0] flags, iflags;
wire [14:0] w_uflags, w_iflags;
reg trap, break_en, step, gie, sleep, r_halted,
break_pending;
reg trap, break_en, step, gie, sleep, r_halted;
wire break_pending;
wire w_clear_icache;
`ifdef OPT_ILLEGAL_INSTRUCTION
reg ill_err_u, ill_err_i;
279,13 → 282,14
//
// Now, let's read our operands
reg [4:0] alu_reg;
reg [3:0] opn;
reg [4:0] opR;
wire [3:0] opn;
wire [4:0] opR;
reg [31:0] r_opA, r_opB;
reg [(AW-1):0] op_pc;
wire [31:0] w_opA, w_opB;
wire [31:0] opA_nowait, opB_nowait, opA, opB;
reg opR_wr, opR_cc, opF_wr, op_gie;
reg opR_wr, opF_wr;
wire op_gie, opR_cc;
wire [14:0] opFl;
reg [5:0] r_opF;
wire [7:0] opF;
301,7 → 305,7
wire op_illegal;
assign op_illegal = 1'b0;
`endif
reg op_break;
wire op_break;
wire op_lock;
 
 
311,7 → 315,7
// Variable declarations
//
//
reg [(AW-1):0] alu_pc;
wire [(AW-1):0] alu_pc;
reg r_alu_pc_valid, mem_pc_valid;
wire alu_pc_valid;
wire alu_phase;
320,9 → 324,8
wire [3:0] alu_flags;
wire alu_valid, alu_busy;
wire set_cond;
reg alu_wr, alF_wr, alu_gie;
wire alu_illegal_op;
wire alu_illegal;
reg alu_wr, alF_wr;
wire alu_gie, alu_illegal_op, alu_illegal;
 
 
 
744,14 → 747,19
`endif
 
always @(posedge i_clk)
`ifdef OPT_PIPELINED
if (op_change_data_ce)
`endif
begin
`ifdef OPT_PIPELINED
if ((wr_reg_ce)&&(wr_reg_id == dcdA))
r_opA <= wr_gpreg_vl;
else if (dcdA_pc)
else
`endif
if (dcdA_pc)
r_opA <= w_pcA_v;
else if (dcdA_cc)
r_opA <= { w_cpu_info, w_opA[22:15], (dcdA[4])?w_uflags:w_iflags };
r_opA <= { w_cpu_info, w_opA[22:16], 1'b0, (dcdA[4])?w_uflags:w_iflags };
else
r_opA <= w_opA;
`ifdef OPT_PIPELINED
775,18 → 783,22
endgenerate
 
assign w_opBnI = (~dcdB_rd) ? 32'h00
: (((wr_reg_ce)&&(wr_reg_id == dcdB)) ? wr_gpreg_vl
`ifdef OPT_PIPELINED
: ((wr_reg_ce)&&(wr_reg_id == dcdB)) ? wr_gpreg_vl
`endif
: ((dcdB_pc) ? w_pcB_v
: ((dcdB_cc) ? { w_cpu_info, w_opB[22:15], // w_opB[31:14],
(dcdB[4])?w_uflags:w_iflags}
: w_opB)));
: ((dcdB_cc) ? { w_cpu_info, w_opB[22:16], // w_opB[31:14],
1'b0, (dcdB[4])?w_uflags:w_iflags}
: w_opB));
 
always @(posedge i_clk)
`ifdef OPT_PIPELINED
if (op_change_data_ce)
r_opB <= w_opBnI + dcdI;
`ifdef OPT_PIPELINED
else if ((wr_reg_ce)&&(opB_id == wr_reg_id)&&(opB_rd))
r_opB <= wr_gpreg_vl;
`else
r_opB <= w_opBnI + dcdI;
`endif
 
// The logic here has become more complex than it should be, no thanks
799,9 → 811,11
// below, arriving at what we finally want in the (now wire net)
// opF.
always @(posedge i_clk)
`ifdef OPT_PIPELINED
if (op_ce) // Cannot do op_change_data_ce here since opF depends
// upon being either correct for a valid op, or correct
// for the last valid op
`endif
begin // Set the flag condition codes, bit order is [3:0]=VNCZ
case(dcdF[2:0])
3'h0: r_opF <= 6'h00; // Always
883,12 → 897,19
// to be, step through it, and then replace it back. In this fashion,
// a debugger can step through code.
// assign w_op_break = (dcd_break)&&(r_dcdI[15:0] == 16'h0001);
initial op_break = 1'b0;
`ifdef OPT_PIPELINED
reg r_op_break;
 
initial r_op_break = 1'b0;
always @(posedge i_clk)
if (i_rst) op_break <= 1'b0;
else if (op_ce) op_break <= (dcd_break); // &&(dcdvalid)
if (i_rst) r_op_break <= 1'b0;
else if (op_ce) r_op_break <= (dcd_break); // &&(dcdvalid)
else if ((clear_pipeline)||(~opvalid))
op_break <= 1'b0;
r_op_break <= 1'b0;
assign op_break = r_op_break;
`else
assign op_break = dcd_break;
`endif
 
`ifdef OPT_PIPELINED
generate
935,13 → 956,14
`else
op_illegal <= (dcdvalid)&&((dcd_illegal)||(dcd_lock));
`endif
`endif
else if(alu_ce)
op_illegal <= 1'b0;
`endif
 
// No generate on EARLY_BRANCHING here, since if EARLY_BRANCHING is not
// set, dcd_early_branch will simply be a wire connected to zero and
// this logic should just optimize.
`ifdef OPT_PIPELINED
always @(posedge i_clk)
if (op_ce)
begin
949,22 → 971,47
&&(~dcd_early_branch)&&(~dcd_illegal);
opR_wr <= (dcdR_wr)&&(~dcd_early_branch)&&(~dcd_illegal);
end
`else
always @(posedge i_clk)
begin
opF_wr <= (dcdF_wr)&&((~dcdR_cc)||(~dcdR_wr))
&&(~dcd_early_branch)&&(~dcd_illegal);
opR_wr <= (dcdR_wr)&&(~dcd_early_branch)&&(~dcd_illegal);
end
`endif
 
`ifdef OPT_PIPELINED
reg [3:0] r_opn;
reg [4:0] r_opR;
reg r_opR_cc;
reg r_op_gie;
always @(posedge i_clk)
if (op_change_data_ce)
begin
opn <= dcdOp; // Which ALU operation?
r_opn <= dcdOp; // Which ALU operation?
// opM <= dcdM; // Is this a memory operation?
// What register will these results be written into?
opR <= dcdR;
opR_cc <= (dcdR_cc)&&(dcdR_wr)&&(dcdR[4]==dcd_gie);
r_opR <= dcdR;
r_opR_cc <= (dcdR_cc)&&(dcdR_wr)&&(dcdR[4]==dcd_gie);
// User level (1), vs supervisor (0)/interrupts disabled
op_gie <= dcd_gie;
r_op_gie <= dcd_gie;
 
 
//
op_pc <= (dcd_early_branch)?dcd_branch_pc:dcd_pc;
end
assign opn = r_opn;
assign opR = r_opR;
assign op_gie = r_op_gie;
assign opR_cc = r_opR_cc;
`else
assign opn = dcdOp;
assign opR = dcdR;
assign op_gie = dcd_gie;
// With no pipelining, there is no early branching. We keep it
always @(posedge i_clk)
op_pc <= (dcd_early_branch)?dcd_branch_pc:dcd_pc;
`endif
assign opFl = (op_gie)?(w_uflags):(w_iflags);
 
`ifdef OPT_VLIW
1166,11 → 1213,19
assign alu_phase = 1'b0;
`endif
 
`ifdef OPT_PIPELINED
always @(posedge i_clk)
if (adf_ce_unconditional)
alu_reg <= opR;
else if ((i_halt)&&(i_dbg_we))
alu_reg <= i_dbg_reg;
`else
always @(posedge i_clk)
if ((i_halt)&&(i_dbg_we))
alu_reg <= i_dbg_reg;
else
alu_reg <= opR;
`endif
 
//
// DEBUG Register write access starts here
1182,14 → 1237,25
reg [31:0] dbg_val;
always @(posedge i_clk)
dbg_val <= i_dbg_data;
`ifdef OPT_PIPELINED
reg r_alu_gie;
 
always @(posedge i_clk)
if ((adf_ce_unconditional)||(mem_ce))
alu_gie <= op_gie;
r_alu_gie <= op_gie;
assign alu_gie = r_alu_gie;
 
reg [(AW-1):0] r_alu_pc;
always @(posedge i_clk)
if ((adf_ce_unconditional)
||((master_ce)&&(opvalid_mem)&&(~clear_pipeline)
&&(~mem_stalled)))
alu_pc <= op_pc;
r_alu_pc <= op_pc;
assign alu_pc = r_alu_pc;
`else
assign alu_gie = op_gie;
assign alu_pc = op_pc;
`endif
 
`ifdef OPT_ILLEGAL_INSTRUCTION
reg r_alu_illegal;
1329,6 → 1395,7
assign wr_write_ucc = (wr_reg_id[4:0] == {1'b1, `CPU_CC_REG});
// Are we writing to the PC?
assign wr_write_pc = (wr_reg_id[3:0] == `CPU_PC_REG);
 
// What value to write?
assign wr_gpreg_vl = ((mem_valid) ? mem_result
:((div_valid|fpu_valid))
1394,14 → 1461,21
else if ((wr_reg_ce)&&(wr_write_scc))
break_en <= wr_spreg_vl[`CPU_BREAK_BIT];
 
initial break_pending = 1'b0;
`ifdef OPT_PIPELINED
reg r_break_pending;
 
initial r_break_pending = 1'b0;
always @(posedge i_clk)
if ((i_rst)||(clear_pipeline)||(~opvalid))
break_pending <= 1'b0;
r_break_pending <= 1'b0;
else if (op_break)
break_pending <= (~alu_busy)&&(~div_busy)&&(~fpu_busy)&&(~mem_busy);
r_break_pending <= (~alu_busy)&&(~div_busy)&&(~fpu_busy)&&(~mem_busy);
else
break_pending <= 1'b0;
r_break_pending <= 1'b0;
assign break_pending = r_break_pending;
`else
assign break_pending = op_break;
`endif
 
 
assign o_break = ((break_en)||(~op_gie))&&(break_pending)
1736,6 → 1810,7
else if (i_dbg_reg[3:0] == `CPU_CC_REG)
begin
o_dbg_reg[14:0] <= (i_dbg_reg[4])?w_uflags:w_iflags;
o_dbg_reg[15] <= 1'b0;
o_dbg_reg[31:23] <= w_cpu_info;
o_dbg_reg[`CPU_GIE_BIT] <= gie;
end
1749,6 → 1824,7
else if (i_dbg_reg[3:0] == `CPU_CC_REG)
begin
o_dbg_reg[14:0] <= (i_dbg_reg[4])?w_uflags:w_iflags;
o_dbg_reg[15] <= 1'b0;
o_dbg_reg[31:23] <= w_cpu_info;
o_dbg_reg[`CPU_GIE_BIT] <= gie;
end
1758,6 → 1834,7
always @(posedge i_clk)
o_dbg_cc <= { o_break, bus_err, gie, sleep };
 
`ifdef OPT_PIPELINED
always @(posedge i_clk)
r_halted <= (i_halt)&&(
// To be halted, any long lasting instruction must
1768,6 → 1845,10
&&((opvalid)||(i_rst)||(dcd_illegal))
// Decode stage must be either valid, in reset, or ill
&&((dcdvalid)||(i_rst)||(pf_illegal)));
`else
always @(posedge i_clk)
r_halted <= (i_halt)&&((opvalid)||(i_rst));
`endif
assign o_dbg_stall = ~r_halted;
 
//
/trunk/rtl/cpu/zipsystem.v
317,7 → 317,7
else if ((cmd_step)||(cpu_break))
cmd_halt <= 1'b1;
 
initial cmd_clear_pf_cache = 1'b0;
initial cmd_clear_pf_cache = 1'b1;
always @(posedge i_clk)
cmd_clear_pf_cache = (~i_rst)&&(dbg_cmd_write)
&&((dbg_idata[11])||(dbg_idata[6]));
557,7 → 557,7
wire ctri_sel, ctri_stall;
reg ctri_ack;
wire [31:0] ctri_data;
assign ctri_sel = (sys_cyc)&&(sys_stb)&&(sys_addr == `CTRINT);
assign ctri_sel = (sys_stb)&&(sys_addr == `CTRINT);
always @(posedge i_clk)
ctri_ack <= ctri_sel;
assign ctri_stall = 1'b0;
661,7 → 661,7
assign pic_stall = 1'b0;
reg pic_ack;
always @(posedge i_clk)
pic_ack <= (sys_cyc)&&(sys_stb)&&(sys_addr == `INTCTRL);
pic_ack <= (sys_stb)&&(sys_addr == `INTCTRL);
 
//
// The CPU itself
/trunk/rtl/toplevel.v
88,7 → 88,7
.CLKFX_DIVIDE(3),
.CLKFX_MULTIPLY(20),
.CLKIN_DIVIDE_BY_2("FALSE"),
.CLKIN_PERIOD(82.0), // 12MHz clock period in ns
.CLKIN_PERIOD(83.0), // 12MHz clock period in ns
.CLKOUT_PHASE_SHIFT("NONE"),
.CLK_FEEDBACK("1X"),
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
/trunk/rtl/txuart.v
227,7 → 227,7
 
 
initial zero_baud_counter = 1'b1;
initial baud_counter = 28'd80000; // 1ms
initial baud_counter = 28'd200000; // 1ms @ 200MHz
always @(posedge i_clk)
begin
zero_baud_counter <= (baud_counter == 28'h01);
/trunk/sw/Makefile
32,7 → 32,7
##
##
.PHONY: all
PROGRAMS := $(OBJDIR) usbtst wbregs netusb wbsettime dumpflash \
PROGRAMS := $(OBJDIR) wbregs netusb wbsettime dumpflash \
dumpsdram ziprun ramscope zipstate zipdbg cfgscope loadmem \
sdcardscop uartscope
all: $(PROGRAMS)
/trunk/xilinx/Makefile
64,16 → 64,16
JTAGBUS := wbufifo.v wbubus.v wbucompactlines.v wbucompress.v \
wbudecompress.v wbudeword.v wbuexec.v wbuidleint.v wbuinput.v \
wbuoutput.v wbureadcw.v wbusixchar.v wbutohex.v
PERIPHERALS: wbgpio.v wbpwmaudio.v rxuart.v txuart.v uartdev.v \
rtcdate.v rtclight.v
PERIPHERALS:= wbgpio.v wbpwmaudio.v rxuart.v txuart.v uartdev.v \
rtcdate.v rtclight.v sdspi.v spiarbiter.v
CPUSRC := zipsystem.v \
busdelay.v wbarbiter.v wbdblpriarb.v \
busdelay.v wbarbiter.v wbdblpriarb.v icontrol.v \
zipcpu.v cpuops.v pfcache.v idecode.v pipemem.v pipefetch.v div.v \
zipcounter.v zipjiffies.v ziptimer.v wbdmac.v wbwatchdog.v
SOURCES := toplevel.v jtagser.v busmaster.v \
ioslave.v memdev.v hexmap.v icontrol.v builddate.v \
wbspiflash.v lldspi.v \
wbsdramng.v wbscope.v wbscopc.v $(JTAGBUS)
ioslave.v memdev.v builddate.v \
wbspiflash.v lldspi.v sdspi.v wbgpio.v \
wbsdram.v wbscope.v wbscopc.v $(JTAGBUS)
 
RTLFILES := $(addprefix $(SRCDIR)/,$(SOURCES)) $(addprefix $(CPUDIR)/,$(CPUSRC))
 
84,6 → 84,7
objdir:
@bash -c "if [ ! -e $(OBJDIR)/ ]; then $(MKDIR) -p $(OBJDIR)/; fi"
 
# Synthesize
$(OBJDIR)/$(PROJECT).ngc: $(RTLFILES) $(PROJECT).xst
$(MKDIR) -p xst/projnav.tmp/
xst -intstyle ise -ifn $(PROJECT).xst -ofn $(OBJDIR)/$(PROJECT).syr
90,23 → 91,24
mv $(PROJECT).ngc $(OBJDIR)/$(PROJECT).ngc
mv $(PROJECT).ngr $(OBJDIR)/$(PROJECT).ngr
 
# Translate
$(OBJDIR)/$(PROJECT).ngd: $(OBJDIR)/$(PROJECT).ngc
ngdbuild -intstyle ise -dd _ngo -nt timestamp \
-uc $(UCFFILE) -p $(PART) $(OBJDIR)/$(PROJECT).ngc $(OBJDIR)/$(PROJECT).ngd
 
# Map
MAPOPTS := -w -logic_opt on -ol high -xe n -t 1 -xt 0 -r 4 \
-global_opt speed -equivalent_register_removal on -mt 2 -detail \
-ir off -ignore_keep_hierarchy -pr off -lc area -power off
$(OBJDIR)/$(PROJECT).ncd: $(OBJDIR)/$(PROJECT).ngd
$(OBJDIR)/$(PROJECT)_map.ncd: $(OBJDIR)/$(PROJECT).ngd
map -intstyle ise -p $(PART) $(MAPOPTS) \
-o $(OBJDIR)/$(PROJECT)_map.ncd $(OBJDIR)/$(PROJECT).ngd $(OBJDIR)/$(PROJECT).pcf
 
$(OBJDIR)/$(PROJECT).ncd: $(OBJDIR)/$(PROJECT)_map.ncd
# Place and Route / Generate Programming File
$(PROJECT).bit: $(OBJDIR)/$(PROJECT)_map.ncd
par -w -intstyle ise -ol std -mt 4 $(OBJDIR)/$(PROJECT)_map.ncd $(OBJDIR)/$(PROJECT).ncd $(OBJDIR)/$(PROJECT).pcf
bitgen -f $(PROJECT).ut $(OBJDIR)/$(PROJECT).ncd $(PROJECT).bit $(OBJDIR)/$(PROJECT).pcf
 
$(PROJECT).bit: $(OBJDIR)/$(PROJECT).ncd
bitgen -f $(PROJECT).ut $(OBJDIR)/$(PROJECT).ncd $(PROJECT).bit
 
timing: $(OBJDIR)/$(PROJECT).ncd $(OBJDIR)/$(PROJECT).pcf
trce -intstyle ise -v 3 -s 2 -n 3 -fastpaths -xml $(OBJDIR)/$(PROJECT).twx -o $(OBJDIR)/$(PROJECT).ncd -o $(OBJDIR)/$(PROJECT).twr $(OBJDIR)/$(PROJECT).pcf
 
/trunk/xilinx/toplevel.bit Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/trunk/xula.ucf
140,7 → 140,7
##############################
NET "i_clk_12mhz" TNM_NET = "i_clk_12mhz";
NET "i_ram_feedback_clk" TNM_NET = "i_ram_feedback_clk";
TIMESPEC "TSi_clk_12mhz" = PERIOD "i_clk_12mhz" 82.0 ns HIGH 50%;
TIMESPEC "TSi_clk_12mhz" = PERIOD "i_clk_12mhz" 83.0 ns HIGH 50%;
# TIMESPEC "TSi_clk_12mhz" = PERIOD "i_clk_12mhz" 83.333333 ns HIGH 50%;
# TIMESPEC "TSi_ram_feedback_clk" = PERIOD "i_ram_feedback_clk" 10.0 ns HIGH 50%;
TIMESPEC "TSi_ram_feedback_clk" = PERIOD "i_ram_feedback_clk" 11.3 ns HIGH 50%;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.