- Integrated MBlite CPU

- Integrated UART
- Various bug fixes
This commit is contained in:
2013-06-03 19:36:51 +02:00
parent f501602ad6
commit 882ec0a33f
43 changed files with 3988 additions and 1679 deletions

132
Makefile
View File

@@ -26,7 +26,7 @@ ddr2_sdram/vhdl_bl4/example_design/rtl/vhdl_bl4_s3_dm_iob.vhd \
ddr2_sdram/vhdl_bl4/example_design/rtl/vhdl_bl4_s3_dqs_iob.vhd \
ddr2_sdram/vhdl_bl4/example_design/rtl/vhdl_bl4_s3_dq_iob.vhd \
src/wb_interconnect.vhd \
src/wb_rom.vhd src/wb_ram.vhd src/cpu.vhd \
src/wb_ram.vhd \
src/clk_reset.vhd src/wb_ddr_ctrl.vhd src/wb_ddr_ctrl_ddrwrap.vhd \
src/wb_ddr_ctrl_wb.vhd src/wb_ddr_ctrl_wb_dc_fsm.vhd src/wb_ddr_ctrl_wb_dc.vhd \
src/wb_ddr_ctrl_wb_sc_fe_ram.vhd src/wb_ddr_ctrl_wb_sc_fe_fsm.vhd src/wb_ddr_ctrl_wb_sc_fe.vhd \
@@ -34,10 +34,18 @@ src/wb_ddr_ctrl_wb_sc.vhd src/vga_syncgen.vhd src/vga_pixelgen.vhd \
src/vga_pixelreader.vhd src/vga.vhd \
src/bresenham_dp.vhd \
src/rasterizer_l_fsm.vhd src/rasterizer_l.vhd \
src/mblite_rom_data.vhd src/mblite_rom.vhd src/mblite_wrapper.vhd src/pio.vhd \
src/uart/fifo16x8.vhd src/uart/par2ser.vhd src/uart/pulsegen325.vhd src/uart/readctrl.vhd src/uart/ser2par.vhd \
src/uart/writectrl.vhd src/uart/uart.vhd src/uart/uart_wbc.vhd \
src/toplevel.vhd
MBLITE_INFILES=mblite/config_Pkg.vhd mblite/std_Pkg.vhd mblite/core_Pkg.vhd \
mblite/dsram.vhd mblite/gprf.vhd mblite/fetch.vhd mblite/decode.vhd mblite/execute.vhd mblite/mem.vhd \
mblite/core.vhd mblite/core_wb_adapter.vhd mblite/core_wb.vhd
SYN_INFILES=
PSMFILES=
CORES=wb_ddr_ctrl_wb_from_ddr wb_ddr_ctrl_wb_to_ddr vga_pixeldata_fifo
BMMFILE=mblite_rom.bmm
MEMFILE=test.mem
PRJNAME=2d_display_engine
NGCFILE=$(PRJNAME).ngc
XSTFILE=$(PRJNAME).xst
@@ -84,7 +92,8 @@ FUSEOPTS=-L ieee_proposed=isim/ieee_proposed
SYNALLFILES=$(COMMON_INFILES) $(SYN_INFILES)
SIMALLFILES=$(SIM_INFILES) $(COMMON_INFILES)
SIMALLFILESXDB=isim/ieee_proposed/std_logic_1164_additions.vdb \
#SIMALLFILESXDB=isim/ieee_proposed/std_logic_1164_additions.vdb \
$(addprefis isim/mblite/,$(notdir $(MBLITE_INFILES:.vhd=.vdb))) \
$(addprefix isim/work/,$(notdir $(SIMALLFILES:.vhd=.vdb))) \
$(addprefix isim/work/,$(notdir $(SIM_INFILES_VLOG:.v=.sdb)))
CORESVDB=$(addprefix isim/work/,$(addsuffix .vdb,$(CORES)))
@@ -102,6 +111,9 @@ TRCE=$(XILPATH)trce
VHPCOMP=$(XILPATH)vhpcomp
VLOGCOMP=$(XILPATH)vlogcomp
FUSE=$(XILPATH)fuse
DATA2MEM=$(XILPATH)data2mem
FWFILE=firmware/fw.elf
.SECONDARY:
@@ -113,8 +125,8 @@ impl: $(NCDFILE_R)
timing: $(TWRFILE)
#firmware/fw.elf:
# cd firmware && make fw.elf
firmware/fw.elf:
cd firmware && make fw.elf
#%.vhd: %.psm
# ../tools/picoasm/picoasm -t ../tools/picoasm/ROM_form.vhd -i $<
@@ -122,6 +134,9 @@ timing: $(TWRFILE)
src/wb_interconnect.vhd: src/wishbone.defines tools/wishbone.pl
cd src && dos2unix wishbone.defines && ../tools/wishbone.pl -nogui wishbone.defines
src/mblite_rom_data.vhd: $(BMMFILE) $(FWFILE)
$(DATA2MEM) -bm $(BMMFILE) -bd $(FWFILE) -o h $@
coregen/%.vhd coregen/%.ngc: coregen/%.xco coregen/coregen.cgp
$(COREGEN) -p coregen/coregen.cgp -b $< -r
@@ -145,16 +160,17 @@ planahead_postimpl: planahead_postimpl.tcl $(NCDFILE) $(UCF) $(NCDFILE_R) $(TWXF
planAhead -source planahead_postimpl.tcl
$(PRJFILE): Makefile
rm -f $(PRJFILE); for i in $(SYNALLFILES); do echo "vhdl work" $$i >> $(PRJFILE); done
rm -f $(PRJFILE); for i in $(SYNALLFILES); do echo "vhdl work" $$i >> $(PRJFILE); done;
for i in $(MBLITE_INFILES); do echo "vhdl mblite" $$i >> $(PRJFILE); done;
$(XSTFILE): Makefile
rm -f $@; echo "run $(XSTOPTS)" > $@
$(NGCFILE): $(SYNALLFILES) $(PRJFILE) $(XSTFILE) $(XCF) $(CORESNGC)
$(NGCFILE): $(SYNALLFILES) $(MBLITE_INFILES) $(PRJFILE) $(XSTFILE) $(XCF) $(CORESNGC)
$(XST) -ifn $(XSTFILE)
$(NGDFILE): $(NGCFILE) $(UCF) $(CORESNGC)
$(NGDBUILD) $(NGDOPTS) $(NGCFILE) $(NGDFILE)
$(NGDFILE): $(NGCFILE) $(UCF) $(CORESNGC) $(BMMFILE)
$(NGDBUILD) $(NGDOPTS) -bm $(BMMFILE) $(NGCFILE) $(NGDFILE)
$(PCFFILE) $(NCDFILE) : $(NGDFILE)
$(MAP) $(MAPOPTS) -o $(NCDFILE) $(NGDFILE) $(PCFFILE)
@@ -163,7 +179,8 @@ $(NCDFILE_R): $(PCFFILE) $(NCDFILE)
$(PAR) -w $(PAROPTS) $(NCDFILE) $(NCDFILE_R) $(PCFFILE)
$(BITFILE): $(NCDFILE_R) $(PCFFILE)
$(BITGEN) -w $(BITGENOPTS) $(NCDFILE_R) $(BITFILE) $(PCFFILE)
$(BITGEN) -w $(BITGENOPTS) $(NCDFILE_R) $(BITFILE) $(PCFFILE)
#-bd $(MEMFILE)
$(TWRFILE) $(TWXFILE): $(NCDFILE_R) $(PCFFILE)
$(TRCE) $(TRACEOPTS) -o $(TWRFILE) $(NCDFILE_R) $(PCFFILE)
@@ -171,9 +188,21 @@ $(TWRFILE) $(TWXFILE): $(NCDFILE_R) $(PCFFILE)
isim/ieee_proposed/std_logic_1164_additions.vdb: tools/std_logic_1164_additions.vhdl
$(VHPCOMP) --work ieee_proposed=isim/ieee_proposed $< $(VHPCOMPOPTS)
isim/mblite/%.vdb: mblite/%.vhd
$(VHPCOMP) --work mblite=isim/mblite $< $(VHPCOMPOPTS)
isim/work/intercon_package.vdb isim/work/intercon.vdb: src/wb_interconnect.vhd
$(VHPCOMP) $< $(VHPCOMPOPTS)
isim/work/vhdl_bl4_dqs_delay.vdb: ddr2_sdram/vhdl_bl4/example_design/rtl/vhdl_bl4_dqs_delay_0.vhd
$(VHPCOMP) $< $(VHPCOMPOPTS)
isim/work/%.vdb: src/%.vhd
$(VHPCOMP) $< $(VHPCOMPOPTS)
isim/work/%.vdb: src/uart/%.vhd
$(VHPCOMP) $< $(VHPCOMPOPTS)
isim/work/%.vdb: zy2000/%.vhd
$(VHPCOMP) $< $(VHPCOMPOPTS)
@@ -189,10 +218,93 @@ isim/work/%.vdb: tb/%.vhd
isim/work/%.vdb: coregen/%.vhd
$(VHPCOMP) $< $(VHPCOMPOPTS)
%.exe: $(SIMALLFILESXDB) $(CORESVDB) isim/work/%.vdb
%.exe: $(CORESVDB) isim/work/%.vdb #$(SIMALLFILESXDB)
$(FUSE) work.$(@:.exe=) -o $@ $(FUSEOPTS)
clean:
rm -f $(NGCFILE) $(PCFFILE) $(NGDFILE) $(NCDFILE) $(NCDFILE_R) $(BITFILE) $(SIMALLFILESXDB) $(CORESVDB)
cd firmware && make clean
.PSEUDO=all synth impl timing clean
isim/work/toplevel_tb.vdb: isim/work/sim_bmppack.vdb isim/work/toplevel.vdb
isim/work/toplevel.vdb: isim/work/mblite_wrapper.vdb isim/work/intercon_package.vdb isim/work/intercon.vdb isim/work/clk_reset.vdb isim/work/wb_ddr_ctrl.vdb isim/work/vga.vdb isim/work/wb_ram.vdb isim/work/pio.vdb isim/work/uart_wbc.vdb
isim/work/mblite_wrapper.vdb: isim/work/intercon_package.vdb isim/work/mblite_rom.vdb isim/mblite/core_wb.vdb
isim/work/mblite_rom.vdb: isim/work/intercon_package.vdb isim/work/mblite_rom_data.vdb
isim/mblite/core_wb.vdb: isim/mblite/config_Pkg.vdb isim/mblite/core_Pkg.vdb isim/mblite/std_Pkg.vdb isim/mblite/core_wb_adapter.vdb isim/mblite/core.vdb
isim/mblite/core_Pkg.vdb: isim/mblite/config_Pkg.vdb isim/mblite/std_Pkg.vdb
isim/mblite/core_wb_adapter.vdb: isim/mblite/config_Pkg.vdb isim/mblite/core_Pkg.vdb isim/mblite/std_Pkg.vdb
isim/mblite/core.vdb: isim/mblite/config_Pkg.vdb isim/mblite/core_Pkg.vdb isim/mblite/fetch.vdb isim/mblite/decode.vdb isim/mblite/execute.vdb isim/mblite/mem.vdb
isim/mblite/fetch.vdb: isim/mblite/config_Pkg.vdb isim/mblite/core_Pkg.vdb isim/mblite/std_Pkg.vdb
isim/mblite/decode.vdb: isim/mblite/config_Pkg.vdb isim/mblite/core_Pkg.vdb isim/mblite/std_Pkg.vdb isim/mblite/gprf.vdb
isim/mblite/gprf.vdb: isim/mblite/config_Pkg.vdb isim/mblite/core_Pkg.vdb isim/mblite/std_Pkg.vdb isim/mblite/dsram.vdb
isim/mblite/dsram.vdb: isim/mblite/std_Pkg.vdb
isim/mblite/execute.vdb: isim/mblite/config_Pkg.vdb isim/mblite/core_Pkg.vdb isim/mblite/std_Pkg.vdb
isim/mblite/mem.vdb: isim/mblite/config_Pkg.vdb isim/mblite/core_Pkg.vdb isim/mblite/std_Pkg.vdb
isim/work/wb_ddr_ctrl.vdb: isim/work/intercon_package.vdb isim/work/wb_ddr_ctrl_ddrwrap.vdb isim/work/wb_ddr_ctrl_wb.vdb
isim/work/wb_ddr_ctrl_ddrwrap.vdb: isim/work/vhdl_bl4_parameters_0.vdb isim/work/vhdl_bl4_infrastructure_top.vdb isim/work/vhdl_bl4_top_0.vdb
isim/work/vhdl_bl4_infrastructure_top.vdb: isim/work/vhdl_bl4_parameters_0.vdb isim/work/vhdl_bl4_clk_dcm.vdb isim/work/vhdl_bl4_cal_top.vdb
isim/work/vhdl_bl4_cal_top.vdb: isim/work/vhdl_bl4_cal_ctl.vdb isim/work/vhdl_bl4_tap_dly.vdb
isim/work/vhdl_bl4_top_0.vdb: isim/work/vhdl_bl4_parameters_0.vdb isim/work/vhdl_bl4_controller_0.vdb isim/work/vhdl_bl4_data_path_0.vdb isim/work/vhdl_bl4_infrastructure.vdb isim/work/vhdl_bl4_iobs_0.vdb
isim/work/vhdl_bl4_controller_0.vdb: isim/work/vhdl_bl4_parameters_0.vdb
isim/work/vhdl_bl4_data_path_0.vdb: isim/work/vhdl_bl4_parameters_0.vdb isim/work/vhdl_bl4_data_read_0.vdb isim/work/vhdl_bl4_data_read_controller_0.vdb isim/work/vhdl_bl4_data_write_0.vdb
isim/work/vhdl_bl4_data_read_0.vdb: isim/work/vhdl_bl4_parameters_0.vdb isim/work/vhdl_bl4_rd_gray_cntr.vdb isim/work/vhdl_bl4_ram8d_0.vdb isim/work/vhdl_bl4_ram8d_1.vdb
isim/work/vhdl_bl4_ram8d_0.vdb: isim/work/vhdl_bl4_parameters_0.vdb
isim/work/vhdl_bl4_ram8d_1.vdb: isim/work/vhdl_bl4_parameters_0.vdb
isim/work/vhdl_bl4_data_read_controller_0.vdb: isim/work/vhdl_bl4_parameters_0.vdb isim/work/vhdl_bl4_dqs_delay.vdb isim/work/vhdl_bl4_wr_gray_cntr.vdb isim/work/vhdl_bl4_fifo_0_wr_en_0.vdb isim/work/vhdl_bl4_fifo_1_wr_en_0.vdb
isim/work/vhdl_bl4_data_write_0.vdb: isim/work/vhdl_bl4_parameters_0.vdb
isim/work/vhdl_bl4_iobs_0.vdb: isim/work/vhdl_bl4_parameters_0.vdb isim/work/vhdl_bl4_infrastructure_iobs_0.vdb isim/work/vhdl_bl4_controller_iobs_0.vdb isim/work/vhdl_bl4_data_path_iobs_0.vdb
isim/work/vhdl_bl4_infrastructure_iobs_0.vdb: isim/work/vhdl_bl4_parameters_0.vdb
isim/work/vhdl_bl4_controller_iobs_0.vdb: isim/work/vhdl_bl4_parameters_0.vdb
isim/work/vhdl_bl4_data_path_iobs_0.vdb: isim/work/vhdl_bl4_parameters_0.vdb isim/work/vhdl_bl4_s3_dqs_iob.vdb isim/work/vhdl_bl4_s3_dq_iob.vdb isim/work/vhdl_bl4_s3_dm_iob.vdb
isim/work/wb_ddr_ctrl_wb.vdb: isim/work/intercon_package.vdb isim/work/wb_ddr_ctrl_wb_from_ddr.vdb isim/work/wb_ddr_ctrl_wb_to_ddr.vdb isim/work/wb_ddr_ctrl_wb_sc.vdb isim/work/wb_ddr_ctrl_wb_dc.vdb
isim/work/wb_ddr_ctrl_wb_sc.vdb: isim/work/intercon_package.vdb isim/work/wb_ddr_ctrl_wb_sc_fe.vdb
isim/work/wb_ddr_ctrl_wb_sc_fe.vdb: isim/work/intercon_package.vdb isim/work/wb_ddr_ctrl_wb_sc_fe_fsm.vdb isim/work/wb_ddr_ctrl_wb_sc_fe_ram.vdb
isim/work/wb_ddr_ctrl_wb_sc_fe_fsm.vdb: isim/work/intercon_package.vdb
isim/work/wb_ddr_ctrl_wb_dc.vdb: isim/work/wb_ddr_ctrl_wb_dc_fsm.vdb
isim/work/vga.vdb: isim/work/intercon_package.vdb isim/work/vga_pixelreader.vdb isim/work/vga_pixeldata_fifo.vdb isim/work/vga_syncgen.vdb isim/work/vga_pixelgen.vdb
isim/work/vga_pixelreader.vdb: isim/work/intercon_package.vdb
isim/work/wb_ram.vdb: isim/work/intercon_package.vdb
isim/work/pio.vdb: isim/work/intercon_package.vdb
isim/work/uart_wbc.vdb: isim/work/uart.vdb
isim/work/uart.vdb: isim/work/ser2par.vdb isim/work/readctrl.vdb isim/work/fifo16x8.vdb isim/work/pulsegen325.vdb isim/work/par2ser.vdb isim/work/writectrl.vdb

View File

@@ -46,4 +46,8 @@ NET "LED<3>" LOC = "U19" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
NET "LED<4>" LOC = "V19" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
NET "LED<5>" LOC = "V20" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
NET "LED<6>" LOC = "Y22" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
NET "LED<7>" LOC = "W21" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
NET "LED<7>" LOC = "W21" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8;
# RS232
NET "RS232_RXD" LOC = "E16" | IOSTANDARD = LVCMOS33;
NET "RS232_TXD" LOC = "F15" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW;

21
firmware/Makefile Normal file
View File

@@ -0,0 +1,21 @@
C_SRCS=
S_SRCS=test.s
LDOPTS=-T standalone.ld
COPTS=-ffreestanding -nostdlib -nostdinc
ASOPTS=
OBJS=$(addprefix objs/,$(C_SRCS:.c=.o)) $(addprefix objs/,$(S_SRCS:.s=.o))
fw.elf: standalone.ld $(OBJS) objs/kcrt0.o
mb-gcc $(COPTS) $(LDOPTS) -o fw.elf $(OBJS)
objs/%.o: %.c
mb-gcc $(COPTS) -o $@ $<
objs/%.o: %.s
mb-as $(ASOPTS) -o $@ $<
clean:
rm -f $(OBJS) objs/kcrt0.o fw.elf
.PSEUDO=clean

57
firmware/kcrt0.s Normal file
View File

@@ -0,0 +1,57 @@
.text
.org 0x0
_vec_reset:
bri _start
.org 0x8
_vec_user_ex:
bri _start
.org 0x10
_vec_int:
bri _start
.org 0x18
_vec_break:
bri _start
.org 0x20
_vec_hw_ex:
bri _start
.org 0x50
.global _start
_start:
# Set stack pointer
addi r1, r0, _stack
# Copy data to RAM
addi r3, r0, _datald # Start of data in ROM
addi r4, r0, _data_start # Start of data in RAM
rsubi r5, r4, _data_end # Length of data
_start_data_loop:
beqi r5, _start_data_done
addi r5, r5, -4
lw r6, r3, r5
sw r6, r4, r5
bri _start_data_loop
_start_data_done:
# Clear BSS
addi r3, r0, _bss_start # Start of BSS
rsubi r4, r3, _bss_end # Length of BSS
_start_bss_loop:
beqi r4, _start_bss_done
addi r4, r4, -4
sw r0, r3, r4
bri _start_bss_loop
_start_bss_done:
# Jump to firmware start
bri main

1
firmware/objs/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.o

29
firmware/standalone.ld Normal file
View File

@@ -0,0 +1,29 @@
ENTRY(_start)
STARTUP(objs/kcrt0.o)
SECTIONS {
.text 0x0 : ALIGN(4) {
*(.text)
}
.rodata : ALIGN(4) {
*(.rodata)
_rodata_end = .;
}
.datald : ALIGN(4) {
_datald = .;
}
/* From here on in RAM */
.data 0x1000 : AT ( _datald ) ALIGN(4) {
_data_start = .;
*(.data)
_data_end = .;
}
.bss (NOLOAD) : ALIGN(4) {
_bss_start = .;
*(.bss)
_bss_end = .;
}
_stack = 0x1800;
}

32
firmware/test.s Normal file
View File

@@ -0,0 +1,32 @@
.global main
main:
lbui r3, r0, testdata+1
swi r3, r0, 0x4000
addi r19, r0, helloworld
main_loop:
lbu r5, r19, r0
beqi r5, done
brlid r15, send_byte
addi r19, r19, 1 # delay slot
bri main_loop
done:
bri done
send_byte:
lbui r3, r0, 0x4024
andi r3, r3, 0x2 # writefull
bnei r3, send_byte
rtsd r15, 8
sbi r5, r0, 0x4020 # delay slot
.rodata
helloworld:
.asciz "Hello, World!"
.data
testdata:
.word 0xdeadbeef

54
mblite/config_Pkg.vhd Normal file
View File

@@ -0,0 +1,54 @@
----------------------------------------------------------------------------------------------
--
-- Input file : config_Pkg.vhd
-- Design name : config_Pkg
-- Author : Tamar Kranenburg
-- Company : Delft University of Technology
-- : Faculty EEMCS, Department ME&CE
-- : Systems and Circuits group
--
-- Description : Configuration parameters for the design
--
----------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
package config_Pkg is
----------------------------------------------------------------------------------------------
-- CORE PARAMETERS
----------------------------------------------------------------------------------------------
-- Implement external interrupt
constant CFG_INTERRUPT : boolean := true; -- Disable or enable external interrupt [0,1]
-- Implement hardware multiplier
constant CFG_USE_HW_MUL : boolean := false; -- Disable or enable multiplier [0,1]
-- Implement hardware barrel shifter
constant CFG_USE_BARREL : boolean := false; -- Disable or enable barrel shifter [0,1]
-- Debug mode
constant CFG_DEBUG : boolean := false; -- Resets some extra registers for better readability
-- and enables feedback (report) [0,1]
-- Set CFG_DEBUG to zero to obtain best performance.
-- Memory parameters
constant CFG_DMEM_SIZE : positive := 28; -- Data memory bus size in 2LOG # elements
constant CFG_IMEM_SIZE : positive := 12; -- Instruction memory bus size in 2LOG # elements
constant CFG_BYTE_ORDER : boolean := true; -- Switch between MSB (1, default) and LSB (0) byte order policy
-- Register parameters
constant CFG_REG_FORCE_ZERO : boolean := true; -- Force data to zero if register address is zero [0,1]
constant CFG_REG_FWD_WRB : boolean := true; -- Forward writeback to loosen register memory requirements [0,1]
constant CFG_MEM_FWD_WRB : boolean := false; -- Forward memory result in stead of introducing stalls [0,1]
----------------------------------------------------------------------------------------------
-- CONSTANTS (currently not configurable / not tested)
----------------------------------------------------------------------------------------------
constant CFG_DMEM_WIDTH : positive := 32; -- Data memory width in bits
constant CFG_IMEM_WIDTH : positive := 32; -- Instruction memory width in bits
constant CFG_GPRF_SIZE : positive := 5; -- General Purpose Register File Size in 2LOG # elements
end config_Pkg;

156
mblite/core.vhd Normal file
View File

@@ -0,0 +1,156 @@
----------------------------------------------------------------------------------------------
--
-- Input file : core.vhd
-- Design name : core
-- Author : Tamar Kranenburg
-- Company : Delft University of Technology
-- : Faculty EEMCS, Department ME&CE
-- : Systems and Circuits group
--
-- Description : Top level entity of the integer unit
--
--
----------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library mblite;
use mblite.config_Pkg.all;
use mblite.core_Pkg.all;
entity core is generic
(
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
port
(
imem_o : out imem_out_type;
dmem_o : out dmem_out_type;
imem_i : in imem_in_type;
dmem_i : in dmem_in_type;
int_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
end core;
architecture arch of core is
signal fetch_i : fetch_in_type;
signal fetch_o : fetch_out_type;
signal decode_i : decode_in_type;
signal decode_o : decode_out_type;
signal gprf_o : gprf_out_type;
signal exec_i : execute_in_type;
signal exec_o : execute_out_type;
signal mem_i : mem_in_type;
signal mem_o : mem_out_type;
signal ena_i : std_logic;
begin
ena_i <= dmem_i.ena_i;
fetch_i.hazard <= decode_o.hazard;
fetch_i.branch <= exec_o.branch;
fetch_i.branch_target <= exec_o.alu_result(CFG_IMEM_SIZE - 1 downto 0);
fetch0 : fetch port map
(
fetch_o => fetch_o,
imem_o => imem_o,
fetch_i => fetch_i,
rst_i => rst_i,
ena_i => ena_i,
clk_i => clk_i
);
decode_i.program_counter <= fetch_o.program_counter;
decode_i.instruction <= imem_i.dat_i;
decode_i.ctrl_wrb <= mem_o.ctrl_wrb;
decode_i.ctrl_mem_wrb <= mem_o.ctrl_mem_wrb;
decode_i.mem_result <= dmem_i.dat_i;
decode_i.alu_result <= mem_o.alu_result;
decode_i.interrupt <= int_i;
decode_i.flush_id <= exec_o.flush_id;
decode0: decode generic map
(
G_INTERRUPT => G_INTERRUPT,
G_USE_HW_MUL => G_USE_HW_MUL,
G_USE_BARREL => G_USE_BARREL,
G_DEBUG => G_DEBUG
)
port map
(
decode_o => decode_o,
decode_i => decode_i,
gprf_o => gprf_o,
ena_i => ena_i,
rst_i => rst_i,
clk_i => clk_i
);
exec_i.fwd_dec <= decode_o.fwd_dec;
exec_i.fwd_dec_result <= decode_o.fwd_dec_result;
exec_i.dat_a <= gprf_o.dat_a_o;
exec_i.dat_b <= gprf_o.dat_b_o;
exec_i.dat_d <= gprf_o.dat_d_o;
exec_i.reg_a <= decode_o.reg_a;
exec_i.reg_b <= decode_o.reg_b;
exec_i.imm <= decode_o.imm;
exec_i.program_counter <= decode_o.program_counter;
exec_i.ctrl_wrb <= decode_o.ctrl_wrb;
exec_i.ctrl_mem <= decode_o.ctrl_mem;
exec_i.ctrl_ex <= decode_o.ctrl_ex;
exec_i.fwd_mem <= mem_o.ctrl_wrb;
exec_i.mem_result <= dmem_i.dat_i;
exec_i.alu_result <= mem_o.alu_result;
exec_i.ctrl_mem_wrb <= mem_o.ctrl_mem_wrb;
execute0 : execute generic map
(
G_USE_HW_MUL => G_USE_HW_MUL,
G_USE_BARREL => G_USE_BARREL
)
port map
(
exec_o => exec_o,
exec_i => exec_i,
ena_i => ena_i,
rst_i => rst_i,
clk_i => clk_i
);
mem_i.alu_result <= exec_o.alu_result;
mem_i.program_counter <= exec_o.program_counter;
mem_i.branch <= exec_o.branch;
mem_i.dat_d <= exec_o.dat_d;
mem_i.ctrl_wrb <= exec_o.ctrl_wrb;
mem_i.ctrl_mem <= exec_o.ctrl_mem;
mem_i.mem_result <= dmem_i.dat_i;
mem0 : mem port map
(
mem_o => mem_o,
dmem_o => dmem_o,
mem_i => mem_i,
ena_i => ena_i,
rst_i => rst_i,
clk_i => clk_i
);
end arch;

439
mblite/core_Pkg.vhd Normal file
View File

@@ -0,0 +1,439 @@
----------------------------------------------------------------------------------------------
--
-- Input file : core_Pkg.vhd
-- Design name : core_Pkg
-- Author : Tamar Kranenburg
-- Company : Delft University of Technology
-- : Faculty EEMCS, Department ME&CE
-- : Systems and Circuits group
--
-- Description : Package with components and type definitions for the interface
-- of the components
--
--
----------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library mblite;
use mblite.config_Pkg.all;
use mblite.std_Pkg.all;
package core_Pkg is
constant C_8_ZEROS : std_logic_vector ( 7 downto 0) := (others => '0');
constant C_16_ZEROS : std_logic_vector (15 downto 0) := (others => '0');
constant C_24_ZEROS : std_logic_vector (23 downto 0) := (others => '0');
constant C_32_ZEROS : std_logic_vector (31 downto 0) := (others => '0');
----------------------------------------------------------------------------------------------
-- TYPES USED IN MB-LITE
----------------------------------------------------------------------------------------------
type alu_operation is (ALU_ADD, ALU_OR, ALU_AND, ALU_XOR, ALU_SHIFT, ALU_SEXT8, ALU_SEXT16, ALU_MUL, ALU_BS);
type src_type_a is (ALU_SRC_REGA, ALU_SRC_NOT_REGA, ALU_SRC_PC, ALU_SRC_ZERO);
type src_type_b is (ALU_SRC_REGB, ALU_SRC_NOT_REGB, ALU_SRC_IMM, ALU_SRC_NOT_IMM);
type carry_type is (CARRY_ZERO, CARRY_ONE, CARRY_ALU, CARRY_ARITH);
type carry_keep_type is (CARRY_NOT_KEEP, CARRY_KEEP);
type branch_condition is (NOP, BNC, BEQ, BNE, BLT, BLE, BGT, BGE);
type transfer_size is (WORD, HALFWORD, BYTE);
type ctrl_execution is record
alu_op : alu_operation;
alu_src_a : src_type_a;
alu_src_b : src_type_b;
operation : std_logic;
carry : carry_type;
carry_keep : carry_keep_type;
branch_cond : branch_condition;
delay : std_logic;
end record;
type ctrl_memory is record
mem_write : std_logic;
mem_read : std_logic;
transfer_size : transfer_size;
end record;
type ctrl_memory_writeback_type is record
mem_read : std_logic;
transfer_size : transfer_size;
end record;
type forward_type is record
reg_d : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
reg_write : std_logic;
end record;
type imem_in_type is record
dat_i : std_logic_vector(CFG_IMEM_WIDTH - 1 downto 0);
end record;
type imem_out_type is record
adr_o : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
ena_o : std_logic;
end record;
type fetch_in_type is record
hazard : std_logic;
branch : std_logic;
branch_target : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
end record;
type fetch_out_type is record
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
end record;
type gprf_out_type is record
dat_a_o : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
dat_b_o : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
dat_d_o : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
end record;
type decode_in_type is record
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
instruction : std_logic_vector(CFG_IMEM_WIDTH - 1 downto 0);
ctrl_wrb : forward_type;
ctrl_mem_wrb : ctrl_memory_writeback_type;
mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
interrupt : std_logic;
flush_id : std_logic;
end record;
type decode_out_type is record
reg_a : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
reg_b : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
imm : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
hazard : std_logic;
ctrl_ex : ctrl_execution;
ctrl_mem : ctrl_memory;
ctrl_wrb : forward_type;
fwd_dec_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
fwd_dec : forward_type;
end record;
type gprf_in_type is record
adr_a_i : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
adr_b_i : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
adr_d_i : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
dat_w_i : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
adr_w_i : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
wre_i : std_logic;
end record;
type execute_out_type is record
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
branch : std_logic;
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
flush_id : std_logic;
ctrl_mem : ctrl_memory;
ctrl_wrb : forward_type;
end record;
type execute_in_type is record
reg_a : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
dat_a : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
reg_b : std_logic_vector(CFG_GPRF_SIZE - 1 downto 0);
dat_b : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
imm : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
fwd_dec : forward_type;
fwd_dec_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
fwd_mem : forward_type;
ctrl_ex : ctrl_execution;
ctrl_mem : ctrl_memory;
ctrl_wrb : forward_type;
ctrl_mem_wrb : ctrl_memory_writeback_type;
mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
end record;
type mem_in_type is record
dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
branch : std_logic;
ctrl_mem : ctrl_memory;
ctrl_wrb : forward_type;
end record;
type mem_out_type is record
alu_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
ctrl_wrb : forward_type;
ctrl_mem_wrb : ctrl_memory_writeback_type;
end record;
type dmem_in_type is record
dat_i : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
ena_i : std_logic;
end record;
type dmem_out_type is record
dat_o : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
adr_o : std_logic_vector(CFG_DMEM_SIZE - 1 downto 0);
sel_o : std_logic_vector(3 downto 0);
we_o : std_logic;
ena_o : std_logic;
end record;
type dmem_in_array_type is array(natural range <>) of dmem_in_type;
type dmem_out_array_type is array(natural range <>) of dmem_out_type;
-- WB-master inputs from the wb-slaves
type wb_mst_in_type is record
clk_i : std_logic; -- master clock input
rst_i : std_logic; -- synchronous active high reset
dat_i : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); -- databus input
ack_i : std_logic; -- buscycle acknowledge input
int_i : std_logic; -- interrupt request input
end record;
-- WB-master outputs to the wb-slaves
type wb_mst_out_type is record
adr_o : std_logic_vector(CFG_DMEM_SIZE - 1 downto 0); -- address bits
dat_o : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); -- databus output
we_o : std_logic; -- write enable output
stb_o : std_logic; -- strobe signals
sel_o : std_logic_vector(3 downto 0); -- select output array
cyc_o : std_logic; -- valid BUS cycle output
end record;
-- WB-slave inputs, from the WB-master
type wb_slv_in_type is record
clk_i : std_logic; -- master clock input
rst_i : std_logic; -- synchronous active high reset
adr_i : std_logic_vector(CFG_DMEM_SIZE - 1 downto 0); -- address bits
dat_i : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); -- Databus input
we_i : std_logic; -- Write enable input
stb_i : std_logic; -- strobe signals / core select signal
sel_i : std_logic_vector(3 downto 0); -- select output array
cyc_i : std_logic; -- valid BUS cycle input
end record;
-- WB-slave outputs to the WB-master
type wb_slv_out_type is record
dat_o : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0); -- Databus output
ack_o : std_logic; -- Bus cycle acknowledge output
int_o : std_logic; -- interrupt request output
end record;
----------------------------------------------------------------------------------------------
-- COMPONENTS USED IN MB-LITE
----------------------------------------------------------------------------------------------
component core
generic (
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
port (
imem_o : out imem_out_type;
dmem_o : out dmem_out_type;
imem_i : in imem_in_type;
dmem_i : in dmem_in_type;
int_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
end component;
component core_wb
generic (
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
port (
imem_o : out imem_out_type;
wb_o : out wb_mst_out_type;
imem_i : in imem_in_type;
wb_i : in wb_mst_in_type
);
end component;
component core_wb_adapter
port (
dmem_i : out dmem_in_type;
wb_o : out wb_mst_out_type;
dmem_o : in dmem_out_type;
wb_i : in wb_mst_in_type
);
end component;
component core_wb_async_adapter
port (
dmem_i : out dmem_in_type;
wb_o : out wb_mst_out_type;
dmem_o : in dmem_out_type;
wb_i : in wb_mst_in_type
);
end component;
component fetch
port (
fetch_o : out fetch_out_type;
imem_o : out imem_out_type;
fetch_i : in fetch_in_type;
rst_i : in std_logic;
ena_i : in std_logic;
clk_i : in std_logic
);
end component;
component decode
generic (
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
port (
decode_o : out decode_out_type;
gprf_o : out gprf_out_type;
decode_i : in decode_in_type;
ena_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
end component;
component gprf
port (
gprf_o : out gprf_out_type;
gprf_i : in gprf_in_type;
ena_i : in std_logic;
clk_i : in std_logic
);
end component;
component execute
generic (
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL
);
port (
exec_o : out execute_out_type;
exec_i : in execute_in_type;
ena_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
end component;
component mem
port (
mem_o : out mem_out_type;
dmem_o : out dmem_out_type;
mem_i : in mem_in_type;
ena_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
end component;
----------------------------------------------------------------------------------------------
-- FUNCTIONS USED IN MB-LITE
----------------------------------------------------------------------------------------------
function select_register_data (reg_dat, reg, wb_dat : std_logic_vector; write : std_logic) return std_logic_vector;
function forward_condition (reg_write : std_logic; reg_a, reg_d : std_logic_vector) return std_logic;
function align_mem_load (data : std_logic_vector; size : transfer_size; address : std_logic_vector) return std_logic_vector;
function align_mem_store (data : std_logic_vector; size : transfer_size) return std_logic_vector;
function decode_mem_store (address : std_logic_vector(1 downto 0); size : transfer_size) return std_logic_vector;
end core_Pkg;
package body core_Pkg is
-- This function select the register value:
-- A) zero
-- B) bypass value read from register file
-- C) value from register file
function select_register_data (reg_dat, reg, wb_dat : std_logic_vector; write : std_logic) return std_logic_vector is
variable tmp : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
begin
if CFG_REG_FORCE_ZERO = true and is_zero(reg) = '1' then
tmp := (others => '0');
elsif CFG_REG_FWD_WRB = true and write = '1' then
tmp := wb_dat;
else
tmp := reg_dat;
end if;
return tmp;
end select_register_data;
-- This function checks if a forwarding condition is met. The condition is met of register A and D match
-- and the signal needs to be written back to the register file.
function forward_condition (reg_write : std_logic; reg_a, reg_d : std_logic_vector ) return std_logic is
begin
return reg_write and compare(reg_a, reg_d);
end forward_condition;
-- This function aligns the memory load operation (Big endian decoding).
function align_mem_load (data : std_logic_vector; size : transfer_size; address : std_logic_vector ) return std_logic_vector is
begin
case size is
when byte =>
case address(1 downto 0) is
when "00" => return C_24_ZEROS & data(31 downto 24);
when "01" => return C_24_ZEROS & data(23 downto 16);
when "10" => return C_24_ZEROS & data(15 downto 8);
when "11" => return C_24_ZEROS & data( 7 downto 0);
when others => return C_32_ZEROS;
end case;
when halfword =>
case address(1 downto 0) is
when "00" => return C_16_ZEROS & data(31 downto 16);
when "10" => return C_16_ZEROS & data(15 downto 0);
when others => return C_32_ZEROS;
end case;
when others =>
return data;
end case;
end align_mem_load;
-- This function repeats the operand to all positions in a memory store operation.
function align_mem_store (data : std_logic_vector; size : transfer_size) return std_logic_vector is
begin
case size is
when byte => return data( 7 downto 0) & data( 7 downto 0) & data(7 downto 0) & data(7 downto 0);
when halfword => return data(15 downto 0) & data(15 downto 0);
when others => return data;
end case;
end align_mem_store;
-- This function selects the correct bytes for memory writes (Big endian encoding).
function decode_mem_store (address : std_logic_vector(1 downto 0); size : transfer_size) return std_logic_vector is
begin
case size is
when BYTE =>
case address is
when "00" => return "1000";
when "01" => return "0100";
when "10" => return "0010";
when "11" => return "0001";
when others => return "0000";
end case;
when HALFWORD =>
case address is
-- Big endian encoding
when "10" => return "0011";
when "00" => return "1100";
when others => return "0000";
end case;
when others =>
return "1111";
end case;
end decode_mem_store;
end core_Pkg;

71
mblite/core_wb.vhd Normal file
View File

@@ -0,0 +1,71 @@
----------------------------------------------------------------------------------------------
--
-- Input file : core_wb.vhd
-- Design name : core_wb
-- Author : Tamar Kranenburg
-- Company : Delft University of Technology
-- : Faculty EEMCS, Department ME&CE
-- : Systems and Circuits group
--
-- Description : Top level module of the MB-Lite microprocessor with connected
-- wishbone data bus
--
----------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library mblite;
use mblite.config_Pkg.all;
use mblite.core_Pkg.all;
use mblite.std_Pkg.all;
entity core_wb is generic
(
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
port
(
imem_o : out imem_out_type;
wb_o : out wb_mst_out_type;
imem_i : in imem_in_type;
wb_i : in wb_mst_in_type
);
end core_wb;
architecture arch of core_wb is
signal dmem_i : dmem_in_type;
signal dmem_o : dmem_out_type;
begin
wb_adapter0 : core_wb_adapter port map
(
dmem_i => dmem_i,
wb_o => wb_o,
dmem_o => dmem_o,
wb_i => wb_i
);
core0 : core generic map
(
G_INTERRUPT => G_INTERRUPT,
G_USE_HW_MUL => G_USE_HW_MUL,
G_USE_BARREL => G_USE_BARREL,
G_DEBUG => G_DEBUG
)
port map
(
imem_o => imem_o,
dmem_o => dmem_o,
imem_i => imem_i,
dmem_i => dmem_i,
int_i => wb_i.int_i,
rst_i => wb_i.rst_i,
clk_i => wb_i.clk_i
);
end arch;

106
mblite/core_wb_adapter.vhd Normal file
View File

@@ -0,0 +1,106 @@
----------------------------------------------------------------------------------------------
--
-- Input file : core_wb_adapter.vhd
-- Design name : core_wb_adapter.vhd
-- Author : Tamar Kranenburg
-- Company : Delft University of Technology
-- : Faculty EEMCS, Department ME&CE
-- : Systems and Circuits group
--
-- Description : Wishbone adapter for the MB-Lite microprocessor. The data output
-- is registered for multicycle transfers. This adapter implements
-- the synchronous Wishbone Bus protocol, Rev3B.
--
----------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library mblite;
use mblite.config_Pkg.all;
use mblite.core_Pkg.all;
use mblite.std_Pkg.all;
entity core_wb_adapter is port
(
dmem_i : out dmem_in_type;
wb_o : out wb_mst_out_type;
dmem_o : in dmem_out_type;
wb_i : in wb_mst_in_type
);
end core_wb_adapter;
architecture arch of core_wb_adapter is
signal r_cyc_o : std_logic;
signal rin_cyc_o : std_logic;
signal r_data, rin_data : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
signal s_wait : std_logic;
signal wb_i_ack_i_dly : std_logic;
begin
-- Direct input-output connections
wb_o.adr_o <= dmem_o.adr_o;
wb_o.sel_o <= dmem_o.sel_o;
wb_o.we_o <= dmem_o.we_o;
dmem_i.dat_i <= wb_i.dat_i;
dly : process(wb_i.clk_i)
begin
if rising_edge(wb_i.clk_i) then
wb_i_ack_i_dly <= wb_i.ack_i;
end if;
end process dly;
-- synchronous bus control connections
wb_o.cyc_o <= r_cyc_o or wb_i_ack_i_dly;
wb_o.stb_o <= r_cyc_o;
-- asynchronous core enable connection
dmem_i.ena_i <= '0' when (dmem_o.ena_o = '1' and rin_cyc_o = '1') or s_wait = '1' else '1';
wb_o.dat_o <= rin_data;
-- logic for wishbone master
wb_adapter_comb: process(wb_i, dmem_o, r_cyc_o, r_data)
begin
if wb_i.rst_i = '1' then
-- reset bus
rin_data <= r_data;
rin_cyc_o <= '0';
s_wait <= '0';
elsif r_cyc_o = '1' and wb_i.ack_i = '1' then
-- terminate wishbone cycle
rin_data <= r_data;
rin_cyc_o <= '0';
s_wait <= '0';
elsif dmem_o.ena_o = '1' and wb_i.ack_i = '1' then
-- wishbone bus is occuppied
rin_data <= r_data;
rin_cyc_o <= '1';
s_wait <= '1';
elsif r_cyc_o = '0' and dmem_o.ena_o = '1' and wb_i.ack_i = '0' then
-- start wishbone cycle
rin_data <= dmem_o.dat_o;
rin_cyc_o <= '1';
s_wait <= '0';
else
-- maintain wishbone cycle
rin_data <= r_data;
rin_cyc_o <= r_cyc_o;
s_wait <= '0';
end if;
end process;
wb_adapter_seq: process(wb_i.clk_i)
begin
if rising_edge(wb_i.clk_i) then
r_cyc_o <= rin_cyc_o;
r_data <= rin_data;
end if;
end process;
end arch;

499
mblite/decode.vhd Normal file
View File

@@ -0,0 +1,499 @@
----------------------------------------------------------------------------------------------
--
-- Input file : decode.vhd
-- Design name : decode
-- Author : Tamar Kranenburg
-- Company : Delft University of Technology
-- : Faculty EEMCS, Department ME&CE
-- : Systems and Circuits group
--
-- Description : This combined register file and decoder uses three Dual Port
-- read after write Random Access Memory components. Every clock
-- cycle three data values can be read (ra, rb and rd) and one value
-- can be stored.
--
----------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library mblite;
use mblite.config_Pkg.all;
use mblite.core_Pkg.all;
use mblite.std_Pkg.all;
entity decode is generic
(
G_INTERRUPT : boolean := CFG_INTERRUPT;
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL;
G_DEBUG : boolean := CFG_DEBUG
);
port
(
decode_o : out decode_out_type;
gprf_o : out gprf_out_type;
decode_i : in decode_in_type;
ena_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
end decode;
architecture arch of decode is
type decode_reg_type is record
instruction : std_logic_vector(CFG_IMEM_WIDTH - 1 downto 0);
program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
immediate : std_logic_vector(15 downto 0);
is_immediate : std_logic;
msr_interrupt_enable : std_logic;
interrupt : std_logic;
delay_interrupt : std_logic;
end record;
signal r, rin : decode_out_type;
signal reg, regin : decode_reg_type;
signal wb_dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
begin
decode_o.imm <= r.imm;
decode_o.ctrl_ex <= r.ctrl_ex;
decode_o.ctrl_mem <= r.ctrl_mem;
decode_o.ctrl_wrb <= r.ctrl_wrb;
decode_o.reg_a <= r.reg_a;
decode_o.reg_b <= r.reg_b;
decode_o.hazard <= r.hazard;
decode_o.program_counter <= r.program_counter;
decode_o.fwd_dec_result <= r.fwd_dec_result;
decode_o.fwd_dec <= r.fwd_dec;
decode_comb: process(decode_i,decode_i.ctrl_wrb,
decode_i.ctrl_mem_wrb,
decode_i.instruction,
decode_i.ctrl_mem_wrb.transfer_size,
r,r.ctrl_ex,r.ctrl_mem,
r.ctrl_mem.transfer_size,r.ctrl_wrb,
r.ctrl_wrb.reg_d,
r.fwd_dec,reg)
variable v : decode_out_type;
variable v_reg : decode_reg_type;
variable opcode : std_logic_vector(5 downto 0);
variable instruction : std_logic_vector(CFG_IMEM_WIDTH - 1 downto 0);
variable program_counter : std_logic_vector(CFG_IMEM_SIZE - 1 downto 0);
variable mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
begin
v := r;
v_reg := reg;
-- Default register values (NOP)
v_reg.immediate := (others => '0');
v_reg.is_immediate := '0';
v_reg.program_counter := decode_i.program_counter;
v_reg.instruction := decode_i.instruction;
if decode_i.ctrl_mem_wrb.mem_read = '1' then
mem_result := align_mem_load(decode_i.mem_result, decode_i.ctrl_mem_wrb.transfer_size, decode_i.alu_result(1 downto 0));
else
mem_result := decode_i.alu_result;
end if;
wb_dat_d <= mem_result;
if G_INTERRUPT = true then
v_reg.delay_interrupt := '0';
end if;
if CFG_REG_FWD_WRB = true then
v.fwd_dec_result := mem_result;
v.fwd_dec := decode_i.ctrl_wrb;
else
v.fwd_dec_result := (others => '0');
v.fwd_dec.reg_d := (others => '0');
v.fwd_dec.reg_write := '0';
end if;
if (not decode_i.flush_id and r.ctrl_mem.mem_read and (compare(decode_i.instruction(20 downto 16), r.ctrl_wrb.reg_d) or compare(decode_i.instruction(15 downto 11), r.ctrl_wrb.reg_d))) = '1' then
-- A hazard occurred on register a or b
-- set current instruction and program counter to 0
instruction := (others => '0');
program_counter := (others => '0');
v.hazard := '1';
elsif CFG_MEM_FWD_WRB = false and (not decode_i.flush_id and r.ctrl_mem.mem_read and compare(decode_i.instruction(25 downto 21), r.ctrl_wrb.reg_d)) = '1' then
-- A hazard occurred on register d
-- set current instruction and program counter to 0
instruction := (others => '0');
program_counter := (others => '0');
v.hazard := '1';
elsif r.hazard = '1' then
-- Recover from hazard. Insert latched instruction
instruction := reg.instruction;
program_counter := reg.program_counter;
v.hazard := '0';
else
instruction := decode_i.instruction;
program_counter := decode_i.program_counter;
v.hazard := '0';
end if;
v.program_counter := program_counter;
opcode := instruction(31 downto 26);
v.ctrl_wrb.reg_d := instruction(25 downto 21);
v.reg_a := instruction(20 downto 16);
v.reg_b := instruction(15 downto 11);
-- SET IMM value
if reg.is_immediate = '1' then
v.imm := reg.immediate & instruction(15 downto 0);
else
v.imm := sign_extend(instruction(15 downto 0), instruction(15), 32);
end if;
-- Register if an interrupt occurs
if G_INTERRUPT = true then
if v_reg.msr_interrupt_enable = '1' and decode_i.interrupt = '1' then
v_reg.interrupt := '1';
v_reg.msr_interrupt_enable := '0';
end if;
end if;
v.ctrl_ex.alu_op := ALU_ADD;
v.ctrl_ex.alu_src_a := ALU_SRC_REGA;
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
v.ctrl_ex.operation := '0';
v.ctrl_ex.carry := CARRY_ZERO;
v.ctrl_ex.carry_keep := CARRY_KEEP;
v.ctrl_ex.delay := '0';
v.ctrl_ex.branch_cond := NOP;
v.ctrl_mem.mem_write := '0';
v.ctrl_mem.transfer_size := WORD;
v.ctrl_mem.mem_read := '0';
v.ctrl_wrb.reg_write := '0';
if G_INTERRUPT = true and (v_reg.interrupt = '1' and reg.delay_interrupt = '0' and decode_i.flush_id = '0' and v.hazard = '0' and r.ctrl_ex.delay = '0' and reg.is_immediate = '0') then
-- IF an interrupt occured
-- AND the current instruction is not a branch or return instruction,
-- AND the current instruction is not in a delay slot,
-- AND this is instruction is not preceded by an IMM instruction, than handle the interrupt.
v_reg.msr_interrupt_enable := '0';
v_reg.interrupt := '0';
v.reg_a := (others => '0');
v.reg_b := (others => '0');
v.imm := X"00000010";
v.ctrl_wrb.reg_d := "01110";
v.ctrl_ex.branch_cond := BNC;
v.ctrl_ex.alu_src_a := ALU_SRC_ZERO;
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
v.ctrl_wrb.reg_write := '1';
elsif (decode_i.flush_id or v.hazard) = '1' then
-- clearing these registers is not necessary, but facilitates debugging.
-- On the other hand performance improves when disabled.
if G_DEBUG = true then
v.program_counter := (others => '0');
v.ctrl_wrb.reg_d := (others => '0');
v.reg_a := (others => '0');
v.reg_b := (others => '0');
v.imm := (others => '0');
end if;
elsif is_zero(opcode(5 downto 4)) = '1' then
-- ADD, SUBTRACT OR COMPARE
-- Alu operation
v.ctrl_ex.alu_op := ALU_ADD;
-- Source operand A
if opcode(0) = '1' then
v.ctrl_ex.alu_src_a := ALU_SRC_NOT_REGA;
else
v.ctrl_ex.alu_src_a := ALU_SRC_REGA;
end if;
-- Source operand B
if opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
end if;
if (compare(opcode, "000101") and instruction(1)) = '1' then
v.ctrl_ex.operation := '1';
end if;
-- Carry
case opcode(1 downto 0) is
when "00" => v.ctrl_ex.carry := CARRY_ZERO;
when "01" => v.ctrl_ex.carry := CARRY_ONE;
when others => v.ctrl_ex.carry := CARRY_ALU;
end case;
-- Carry keep
if opcode(2) = '1' then
v.ctrl_ex.carry_keep := CARRY_KEEP;
else
v.ctrl_ex.carry_keep := CARRY_NOT_KEEP;
end if;
-- Flag writeback if reg_d != 0
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
elsif (compare(opcode(5 downto 2), "1000") or compare(opcode(5 downto 2), "1010")) = '1' then
-- OR, AND, XOR, ANDN
-- ORI, ANDI, XORI, ANDNI
case opcode(1 downto 0) is
when "00" => v.ctrl_ex.alu_op := ALU_OR;
when "10" => v.ctrl_ex.alu_op := ALU_XOR;
when others => v.ctrl_ex.alu_op := ALU_AND;
end case;
if opcode(3) = '1' and compare(opcode(1 downto 0), "11") = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_NOT_IMM;
elsif opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
elsif opcode(3) = '0' and compare(opcode(1 downto 0), "11") = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_NOT_REGB;
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
end if;
-- Flag writeback if reg_d != 0
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
elsif compare(opcode, "101100") = '1' then
-- IMM instruction
v_reg.immediate := instruction(15 downto 0);
v_reg.is_immediate := '1';
elsif compare(opcode, "100100") = '1' then
-- SHIFT, SIGN EXTEND
if compare(instruction(6 downto 5), "11") = '1' then
if instruction(0) = '1' then
v.ctrl_ex.alu_op:= ALU_SEXT16;
else
v.ctrl_ex.alu_op:= ALU_SEXT8;
end if;
else
v.ctrl_ex.alu_op:= ALU_SHIFT;
v.ctrl_ex.carry_keep := CARRY_NOT_KEEP;
case instruction(6 downto 5) is
when "10" => v.ctrl_ex.carry := CARRY_ZERO;
when "01" => v.ctrl_ex.carry := CARRY_ALU;
when others => v.ctrl_ex.carry := CARRY_ARITH;
end case;
end if;
-- Flag writeback if reg_d != 0
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
elsif (compare(opcode, "100110") or compare(opcode, "101110")) = '1' then
-- BRANCH UNCONDITIONAL
v.ctrl_ex.branch_cond := BNC;
if opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
end if;
-- WRITE THE RESULT ALSO TO REGISTER D
if v.reg_a(2) = '1' then
-- Flag writeback if reg_d != 0
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
end if;
if v.reg_a(3) = '1' then
v.ctrl_ex.alu_src_a := ALU_SRC_ZERO;
else
v.ctrl_ex.alu_src_a := ALU_SRC_PC;
end if;
if G_INTERRUPT = true then
v_reg.delay_interrupt := '1';
end if;
v.ctrl_ex.delay := v.reg_a(4);
elsif (compare(opcode, "100111") or compare(opcode, "101111")) = '1' then
-- BRANCH CONDITIONAL
v.ctrl_ex.alu_op := ALU_ADD;
v.ctrl_ex.alu_src_a := ALU_SRC_PC;
if opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
end if;
case v.ctrl_wrb.reg_d(2 downto 0) is
when "000" => v.ctrl_ex.branch_cond := BEQ;
when "001" => v.ctrl_ex.branch_cond := BNE;
when "010" => v.ctrl_ex.branch_cond := BLT;
when "011" => v.ctrl_ex.branch_cond := BLE;
when "100" => v.ctrl_ex.branch_cond := BGT;
when others => v.ctrl_ex.branch_cond := BGE;
end case;
if G_INTERRUPT = true then
v_reg.delay_interrupt := '1';
end if;
v.ctrl_ex.delay := v.ctrl_wrb.reg_d(4);
elsif compare(opcode, "101101") = '1' then
-- RETURN
v.ctrl_ex.branch_cond := BNC;
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
v.ctrl_ex.delay := '1';
if G_INTERRUPT = true then
if v.ctrl_wrb.reg_d(0) = '1' then
v_reg.msr_interrupt_enable := '1';
end if;
v_reg.delay_interrupt := '1';
end if;
elsif compare(opcode(5 downto 4), "11") = '1' then
-- SW, LW
v.ctrl_ex.alu_op := ALU_ADD;
v.ctrl_ex.alu_src_a := ALU_SRC_REGA;
if opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
end if;
v.ctrl_ex.carry := CARRY_ZERO;
if opcode(2) = '1' then
-- Store
v.ctrl_mem.mem_write := '1';
v.ctrl_mem.mem_read := '0';
v.ctrl_wrb.reg_write := '0';
else
-- Load
v.ctrl_mem.mem_write := '0';
v.ctrl_mem.mem_read := '1';
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
end if;
case opcode(1 downto 0) is
when "00" => v.ctrl_mem.transfer_size := BYTE;
when "01" => v.ctrl_mem.transfer_size := HALFWORD;
when others => v.ctrl_mem.transfer_size := WORD;
end case;
v.ctrl_ex.delay := '0';
elsif G_USE_HW_MUL = true and (compare(opcode, "010000") or compare(opcode, "011000")) = '1' then
v.ctrl_ex.alu_op := ALU_MUL;
if opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
end if;
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
elsif G_USE_BARREL = true and (compare(opcode, "010001") or compare(opcode, "011001")) = '1' then
v.ctrl_ex.alu_op := ALU_BS;
if opcode(3) = '1' then
v.ctrl_ex.alu_src_b := ALU_SRC_IMM;
else
v.ctrl_ex.alu_src_b := ALU_SRC_REGB;
end if;
v.ctrl_wrb.reg_write := is_not_zero(v.ctrl_wrb.reg_d);
else
-- UNKNOWN OPCODE
null;
end if;
rin <= v;
regin <= v_reg;
end process;
decode_seq: process(clk_i)
procedure proc_reset_decode is
begin
r.reg_a <= (others => '0');
r.reg_b <= (others => '0');
r.imm <= (others => '0');
r.program_counter <= (others => '0');
r.hazard <= '0';
r.ctrl_ex.alu_op <= ALU_ADD;
r.ctrl_ex.alu_src_a <= ALU_SRC_REGA;
r.ctrl_ex.alu_src_b <= ALU_SRC_REGB;
r.ctrl_ex.operation <= '0';
r.ctrl_ex.carry <= CARRY_ZERO;
r.ctrl_ex.carry_keep <= CARRY_NOT_KEEP;
r.ctrl_ex.delay <= '0';
r.ctrl_ex.branch_cond <= NOP;
r.ctrl_mem.mem_write <= '0';
r.ctrl_mem.transfer_size <= WORD;
r.ctrl_mem.mem_read <= '0';
r.ctrl_wrb.reg_d <= (others => '0');
r.ctrl_wrb.reg_write <= '0';
r.fwd_dec_result <= (others => '0');
r.fwd_dec.reg_d <= (others => '0');
r.fwd_dec.reg_write <= '0';
reg.instruction <= (others => '0');
reg.program_counter <= (others => '0');
reg.immediate <= (others => '0');
reg.is_immediate <= '0';
reg.msr_interrupt_enable <= '1';
reg.interrupt <= '0';
reg.delay_interrupt <= '0';
end procedure proc_reset_decode;
begin
if rising_edge(clk_i) then
if rst_i = '1' then
proc_reset_decode;
elsif ena_i = '1' then
r <= rin;
reg <= regin;
end if;
end if;
end process;
gprf0 : gprf port map
(
gprf_o => gprf_o,
gprf_i.adr_a_i => rin.reg_a,
gprf_i.adr_b_i => rin.reg_b,
gprf_i.adr_d_i => rin.ctrl_wrb.reg_d,
gprf_i.dat_w_i => wb_dat_d,
gprf_i.adr_w_i => decode_i.ctrl_wrb.reg_d,
gprf_i.wre_i => decode_i.ctrl_wrb.reg_write,
ena_i => ena_i,
clk_i => clk_i
);
end arch;

55
mblite/dsram.vhd Normal file
View File

@@ -0,0 +1,55 @@
----------------------------------------------------------------------------------------------
--
-- Input file : dsram.vhd
-- Design name : dsram
-- Author : Tamar Kranenburg
-- Company : Delft University of Technology
-- : Faculty EEMCS, Department ME&CE
-- : Systems and Circuits group
--
-- Description : Dual Port Synchronous 'read after write' Ram. 1 Read Port and 1
-- Write Port.
--
--
----------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library mblite;
use mblite.std_Pkg.all;
entity dsram is generic
(
WIDTH : positive := 32;
SIZE : positive := 8
);
port
(
dat_o : out std_logic_vector(WIDTH - 1 downto 0);
adr_i : in std_logic_vector(SIZE - 1 downto 0);
ena_i : in std_logic;
dat_w_i : in std_logic_vector(WIDTH - 1 downto 0);
adr_w_i : in std_logic_vector(SIZE - 1 downto 0);
wre_i : in std_logic;
clk_i : in std_logic
);
end dsram;
architecture arch of dsram is
type ram_type is array(2 ** SIZE - 1 downto 0) of std_logic_vector(WIDTH - 1 downto 0);
signal ram : ram_type;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
if ena_i = '1' then
if wre_i = '1' then
ram(my_conv_integer(adr_w_i)) <= dat_w_i;
end if;
dat_o <= ram(my_conv_integer(adr_i));
end if;
end if;
end process;
end arch;

257
mblite/execute.vhd Normal file
View File

@@ -0,0 +1,257 @@
----------------------------------------------------------------------------------------------
--
-- Input file : execute.vhd
-- Design name : execute
-- Author : Tamar Kranenburg
-- Company : Delft University of Technology
-- : Faculty EEMCS, Department ME&CE
-- : Systems and Circuits group
--
-- Description : The Execution Unit performs all arithmetic operations and makes
-- the branch decision. Furthermore the forwarding logic is located
-- here. Everything is computed within a single clock-cycle
--
--
----------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library mblite;
use mblite.config_Pkg.all;
use mblite.core_Pkg.all;
use mblite.std_Pkg.all;
entity execute is generic
(
G_USE_HW_MUL : boolean := CFG_USE_HW_MUL;
G_USE_BARREL : boolean := CFG_USE_BARREL
);
port
(
exec_o : out execute_out_type;
exec_i : in execute_in_type;
ena_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
end execute;
architecture arch of execute is
type execute_reg_type is record
carry : std_logic;
flush_ex : std_logic;
end record;
signal r, rin : execute_out_type;
signal reg, regin : execute_reg_type;
begin
exec_o <= r;
execute_comb: process(exec_i,exec_i.fwd_mem,exec_i.ctrl_ex,
exec_i.ctrl_wrb,exec_i.ctrl_mem,
exec_i.ctrl_mem.transfer_size,
exec_i.ctrl_mem_wrb,exec_i.fwd_dec,
r,r.ctrl_mem,r.ctrl_mem.transfer_size,
r.ctrl_wrb,reg)
variable v : execute_out_type;
variable v_reg : execute_reg_type;
variable alu_src_a : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
variable alu_src_b : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
variable carry : std_logic;
variable result : std_logic_vector(CFG_DMEM_WIDTH downto 0);
variable result_add : std_logic_vector(CFG_DMEM_WIDTH downto 0);
variable zero : std_logic;
variable dat_a, dat_b : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
variable sel_dat_a, sel_dat_b, sel_dat_d : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
variable mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
begin
v := r;
sel_dat_a := select_register_data(exec_i.dat_a, exec_i.reg_a, exec_i.fwd_dec_result, forward_condition(exec_i.fwd_dec.reg_write, exec_i.fwd_dec.reg_d, exec_i.reg_a));
sel_dat_b := select_register_data(exec_i.dat_b, exec_i.reg_b, exec_i.fwd_dec_result, forward_condition(exec_i.fwd_dec.reg_write, exec_i.fwd_dec.reg_d, exec_i.reg_b));
sel_dat_d := select_register_data(exec_i.dat_d, exec_i.ctrl_wrb.reg_d, exec_i.fwd_dec_result, forward_condition(exec_i.fwd_dec.reg_write, exec_i.fwd_dec.reg_d, exec_i.ctrl_wrb.reg_d));
if reg.flush_ex = '1' then
v.ctrl_mem.mem_write := '0';
v.ctrl_mem.mem_read := '0';
v.ctrl_wrb.reg_write := '0';
v.ctrl_wrb.reg_d := (others => '0');
else
v.ctrl_mem := exec_i.ctrl_mem;
v.ctrl_wrb := exec_i.ctrl_wrb;
end if;
if exec_i.ctrl_mem_wrb.mem_read = '1' then
mem_result := align_mem_load(exec_i.mem_result, exec_i.ctrl_mem_wrb.transfer_size, exec_i.alu_result(1 downto 0));
else
mem_result := exec_i.alu_result;
end if;
if forward_condition(r.ctrl_wrb.reg_write, r.ctrl_wrb.reg_d, exec_i.reg_a) = '1' then
-- Forward Execution Result to REG a
dat_a := r.alu_result;
elsif forward_condition(exec_i.fwd_mem.reg_write, exec_i.fwd_mem.reg_d, exec_i.reg_a) = '1' then
-- Forward Memory Result to REG a
dat_a := mem_result;
else
-- DEFAULT: value of REG a
dat_a := sel_dat_a;
end if;
if forward_condition(r.ctrl_wrb.reg_write, r.ctrl_wrb.reg_d, exec_i.reg_b) = '1' then
-- Forward (latched) Execution Result to REG b
dat_b := r.alu_result;
elsif forward_condition(exec_i.fwd_mem.reg_write, exec_i.fwd_mem.reg_d, exec_i.reg_b) = '1' then
-- Forward Memory Result to REG b
dat_b := mem_result;
else
-- DEFAULT: value of REG b
dat_b := sel_dat_b;
end if;
if forward_condition(r.ctrl_wrb.reg_write, r.ctrl_wrb.reg_d, exec_i.ctrl_wrb.reg_d) = '1' then
-- Forward Execution Result to REG d
v.dat_d := align_mem_store(r.alu_result, exec_i.ctrl_mem.transfer_size);
elsif forward_condition(exec_i.fwd_mem.reg_write, exec_i.fwd_mem.reg_d, exec_i.ctrl_wrb.reg_d) = '1' then
-- Forward Memory Result to REG d
v.dat_d := align_mem_store(mem_result, exec_i.ctrl_mem.transfer_size);
else
-- DEFAULT: value of REG d
v.dat_d := align_mem_store(sel_dat_d, exec_i.ctrl_mem.transfer_size);
end if;
-- Set the first operand of the ALU
case exec_i.ctrl_ex.alu_src_a is
when ALU_SRC_PC => alu_src_a := sign_extend(exec_i.program_counter, '0', 32);
when ALU_SRC_NOT_REGA => alu_src_a := not dat_a;
when ALU_SRC_ZERO => alu_src_a := (others => '0');
when others => alu_src_a := dat_a;
end case;
-- Set the second operand of the ALU
case exec_i.ctrl_ex.alu_src_b is
when ALU_SRC_IMM => alu_src_b := exec_i.imm;
when ALU_SRC_NOT_IMM => alu_src_b := not exec_i.imm;
when ALU_SRC_NOT_REGB => alu_src_b := not dat_b;
when others => alu_src_b := dat_b;
end case;
-- Determine value of carry in
case exec_i.ctrl_ex.carry is
when CARRY_ALU => carry := reg.carry;
when CARRY_ONE => carry := '1';
when CARRY_ARITH => carry := alu_src_a(CFG_DMEM_WIDTH - 1);
when others => carry := '0';
end case;
result_add := add(alu_src_a, alu_src_b, carry);
case exec_i.ctrl_ex.alu_op is
when ALU_ADD => result := result_add;
when ALU_OR => result := '0' & (alu_src_a or alu_src_b);
when ALU_AND => result := '0' & (alu_src_a and alu_src_b);
when ALU_XOR => result := '0' & (alu_src_a xor alu_src_b);
when ALU_SHIFT => result := alu_src_a(0) & carry & alu_src_a(CFG_DMEM_WIDTH - 1 downto 1);
when ALU_SEXT8 => result := '0' & sign_extend(alu_src_a(7 downto 0), alu_src_a(7), 32);
when ALU_SEXT16 => result := '0' & sign_extend(alu_src_a(15 downto 0), alu_src_a(15), 32);
when ALU_MUL =>
if G_USE_HW_MUL = true then
result := '0' & multiply(alu_src_a, alu_src_b);
else
result := (others => '0');
end if;
when ALU_BS =>
if G_USE_BARREL = true then
result := '0' & shift(alu_src_a, alu_src_b(4 downto 0), exec_i.imm(10), exec_i.imm(9));
else
result := (others => '0');
end if;
when others =>
result := (others => '0');
report "Invalid ALU operation" severity FAILURE;
end case;
-- Set carry register
if exec_i.ctrl_ex.carry_keep = CARRY_KEEP then
v_reg.carry := reg.carry;
else
v_reg.carry := result(CFG_DMEM_WIDTH);
end if;
zero := is_zero(dat_a);
-- Overwrite branch condition
if reg.flush_ex = '1' then
v.branch := '0';
else
-- Determine branch condition
case exec_i.ctrl_ex.branch_cond is
when BNC => v.branch := '1';
when BEQ => v.branch := zero;
when BNE => v.branch := not zero;
when BLT => v.branch := dat_a(CFG_DMEM_WIDTH - 1);
when BLE => v.branch := dat_a(CFG_DMEM_WIDTH - 1) or zero;
when BGT => v.branch := not (dat_a(CFG_DMEM_WIDTH - 1) or zero);
when BGE => v.branch := not dat_a(CFG_DMEM_WIDTH - 1);
when others => v.branch := '0';
end case;
end if;
-- Handle CMPU
if ( exec_i.ctrl_ex.operation and not (alu_src_a(CFG_DMEM_WIDTH - 1) xor alu_src_b(CFG_DMEM_WIDTH - 1))) = '1' then
-- Set MSB
v.alu_result(CFG_DMEM_WIDTH - 1 downto 0) := (not result(CFG_DMEM_WIDTH - 1)) & result(CFG_DMEM_WIDTH - 2 downto 0);
else
-- Use ALU result
v.alu_result := result(CFG_DMEM_WIDTH - 1 downto 0);
end if;
v.program_counter := exec_i.program_counter;
-- Determine flush signals
v.flush_id := v.branch;
v_reg.flush_ex := v.branch and not exec_i.ctrl_ex.delay;
rin <= v;
regin <= v_reg;
end process;
execute_seq: process(clk_i)
procedure proc_execute_reset is
begin
r.alu_result <= (others => '0');
r.dat_d <= (others => '0');
r.branch <= '0';
r.program_counter <= (others => '0');
r.flush_id <= '0';
r.ctrl_mem.mem_write <= '0';
r.ctrl_mem.mem_read <= '0';
r.ctrl_mem.transfer_size <= WORD;
r.ctrl_wrb.reg_d <= (others => '0');
r.ctrl_wrb.reg_write <= '0';
reg.carry <= '0';
reg.flush_ex <= '0';
end procedure proc_execute_reset;
begin
if rising_edge(clk_i) then
if rst_i = '1' then
proc_execute_reset;
elsif ena_i = '1' then
r <= rin;
reg <= regin;
end if;
end if;
end process;
end arch;

72
mblite/fetch.vhd Normal file
View File

@@ -0,0 +1,72 @@
----------------------------------------------------------------------------------------------
--
-- Input file : fetch.vhd
-- Design name : fetch
-- Author : Tamar Kranenburg
-- Company : Delft University of Technology
-- : Faculty EEMCS, Department ME&CE
-- : Systems and Circuits group
--
-- Description : Instruction Fetch Stage inserts instruction into the pipeline. It
-- uses a single port Random Access Memory component which holds
-- the instructions. The next instruction is computed in the decode
-- stage.
--
----------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library mblite;
use mblite.config_Pkg.all;
use mblite.core_Pkg.all;
use mblite.std_Pkg.all;
entity fetch is port
(
fetch_o : out fetch_out_type;
imem_o : out imem_out_type;
fetch_i : in fetch_in_type;
rst_i : in std_logic;
ena_i : in std_logic;
clk_i : in std_logic
);
end fetch;
architecture arch of fetch is
signal r, rin : fetch_out_type;
begin
fetch_o.program_counter <= r.program_counter;
imem_o.adr_o <= rin.program_counter;
imem_o.ena_o <= ena_i;
fetch_comb: process(fetch_i, r, rst_i)
variable v : fetch_out_type;
begin
v := r;
if rst_i = '1' then
v.program_counter := (OTHERS => '0');
elsif fetch_i.hazard = '1' then
v.program_counter := r.program_counter;
elsif fetch_i.branch = '1' then
v.program_counter := fetch_i.branch_target;
else
v.program_counter := increment(r.program_counter(CFG_IMEM_SIZE - 1 downto 2)) & "00";
end if;
rin <= v;
end process;
fetch_seq: process(clk_i)
begin
if rising_edge(clk_i) then
if rst_i = '1' then
r.program_counter <= (others => '0');
elsif ena_i = '1' then
r <= rin;
end if;
end if;
end process;
end arch;

87
mblite/gprf.vhd Normal file
View File

@@ -0,0 +1,87 @@
----------------------------------------------------------------------------------------------
--
-- Input file : gprf.vhd
-- Design name : gprf
-- Author : Tamar Kranenburg
-- Company : Delft University of Technology
-- : Faculty EEMCS, Department ME&CE
-- : Systems and Circuits group
--
-- Description : The general purpose register infers memory blocks to implement
-- the register file. All outputs are registered, possibly by using
-- registered memory elements.
--
----------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library mblite;
use mblite.config_Pkg.all;
use mblite.core_Pkg.all;
use mblite.std_Pkg.all;
entity gprf is port
(
gprf_o : out gprf_out_type;
gprf_i : in gprf_in_type;
ena_i : in std_logic;
clk_i : in std_logic
);
end gprf;
-- This architecture is the default implementation. It
-- consists of three dual port memories. Other
-- architectures can be added while configurations can
-- control the implemented architecture.
architecture arch of gprf is
begin
a : dsram generic map
(
WIDTH => CFG_DMEM_WIDTH,
SIZE => CFG_GPRF_SIZE
)
port map
(
dat_o => gprf_o.dat_a_o,
adr_i => gprf_i.adr_a_i,
ena_i => ena_i,
dat_w_i => gprf_i.dat_w_i,
adr_w_i => gprf_i.adr_w_i,
wre_i => gprf_i.wre_i,
clk_i => clk_i
);
b : dsram generic map
(
WIDTH => CFG_DMEM_WIDTH,
SIZE => CFG_GPRF_SIZE
)
port map
(
dat_o => gprf_o.dat_b_o,
adr_i => gprf_i.adr_b_i,
ena_i => ena_i,
dat_w_i => gprf_i.dat_w_i,
adr_w_i => gprf_i.adr_w_i,
wre_i => gprf_i.wre_i,
clk_i => clk_i
);
d : dsram generic map
(
WIDTH => CFG_DMEM_WIDTH,
SIZE => CFG_GPRF_SIZE
)
port map
(
dat_o => gprf_o.dat_d_o,
adr_i => gprf_i.adr_d_i,
ena_i => ena_i,
dat_w_i => gprf_i.dat_w_i,
adr_w_i => gprf_i.adr_w_i,
wre_i => gprf_i.wre_i,
clk_i => clk_i
);
end arch;

107
mblite/mem.vhd Normal file
View File

@@ -0,0 +1,107 @@
----------------------------------------------------------------------------------------------
--
-- Input file : mem.vhd
-- Design name : mem
-- Author : Tamar Kranenburg
-- Company : Delft University of Technology
-- : Faculty EEMCS, Department ME&CE
-- : Systems and Circuits group
--
-- Description : Memory retrieves data words from a data memory. Memory file
-- access of byte, halfword and word sizes is supported. The sel_o
-- signal indicates which bytes should be read or written. The
-- responsibility for writing the right memory address is not within
-- this integer unit but should be handled by the external memory
-- device. This facilitates the addition of devices with different
-- bus sizes.
--
-- The dmem_i signals are directly connected to the decode and
-- execute components.
--
----------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
library mblite;
use mblite.config_Pkg.all;
use mblite.core_Pkg.all;
use mblite.std_Pkg.all;
entity mem is port
(
mem_o : out mem_out_type;
dmem_o : out dmem_out_type;
mem_i : in mem_in_type;
ena_i : in std_logic;
rst_i : in std_logic;
clk_i : in std_logic
);
end mem;
architecture arch of mem is
signal r, rin : mem_out_type;
signal mem_result : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
begin
-- connect pipline signals
mem_o.ctrl_wrb <= r.ctrl_wrb;
mem_o.ctrl_mem_wrb <= r.ctrl_mem_wrb;
mem_o.alu_result <= r.alu_result;
-- connect memory interface signals
dmem_o.dat_o <= mem_result;
dmem_o.sel_o <= decode_mem_store(mem_i.alu_result(1 downto 0), mem_i.ctrl_mem.transfer_size);
dmem_o.we_o <= mem_i.ctrl_mem.mem_write;
dmem_o.adr_o <= mem_i.alu_result(CFG_DMEM_SIZE - 1 downto 0);
dmem_o.ena_o <= mem_i.ctrl_mem.mem_read or mem_i.ctrl_mem.mem_write;
mem_comb: process(mem_i, mem_i.ctrl_wrb, mem_i.ctrl_mem, r, r.ctrl_wrb, r.ctrl_mem_wrb)
variable v : mem_out_type;
variable intermediate : std_logic_vector(CFG_DMEM_WIDTH - 1 downto 0);
begin
v := r;
v.ctrl_wrb := mem_i.ctrl_wrb;
if mem_i.branch = '1' then
-- set alu result for branch and load instructions
v.alu_result := sign_extend(mem_i.program_counter, '0', 32);
else
v.alu_result := mem_i.alu_result;
end if;
-- Forward memory result
if CFG_MEM_FWD_WRB = true and ( r.ctrl_mem_wrb.mem_read and compare(mem_i.ctrl_wrb.reg_d, r.ctrl_wrb.reg_d)) = '1' then
intermediate := align_mem_load(mem_i.mem_result, r.ctrl_mem_wrb.transfer_size, r.alu_result(1 downto 0));
mem_result <= align_mem_store(intermediate, mem_i.ctrl_mem.transfer_size);
else
mem_result <= mem_i.dat_d;
end if;
v.ctrl_mem_wrb.mem_read := mem_i.ctrl_mem.mem_read;
v.ctrl_mem_wrb.transfer_size := mem_i.ctrl_mem.transfer_size;
rin <= v;
end process;
mem_seq: process(clk_i)
procedure proc_mem_reset is
begin
r.alu_result <= (others => '0');
r.ctrl_wrb.reg_d <= (others => '0');
r.ctrl_wrb.reg_write <= '0';
r.ctrl_mem_wrb.mem_read <= '0';
r.ctrl_mem_wrb.transfer_size <= WORD;
end procedure proc_mem_reset;
begin
if rising_edge(clk_i) then
if rst_i = '1' then
proc_mem_reset;
elsif ena_i = '1' then
r <= rin;
end if;
end if;
end process;
end arch;

262
mblite/std_Pkg.vhd Normal file
View File

@@ -0,0 +1,262 @@
----------------------------------------------------------------------------------------------
--
-- Input file : std_Pkg.vhd
-- Design name : std_Pkg
-- Author : Tamar Kranenburg
-- Company : Delft University of Technology
-- : Faculty EEMCS, Department ME&CE
-- : Systems and Circuits group
--
-- Description : Package with several standard components.
--
----------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
PACKAGE std_Pkg IS
----------------------------------------------------------------------------------------------
-- STANDARD COMPONENTS IN STD_PKG
----------------------------------------------------------------------------------------------
component sram generic
(
WIDTH : positive;
SIZE : positive
);
port
(
dat_o : out std_logic_vector(WIDTH - 1 downto 0);
dat_i : in std_logic_vector(WIDTH - 1 downto 0);
adr_i : in std_logic_vector(SIZE - 1 downto 0);
wre_i : in std_logic;
ena_i : in std_logic;
clk_i : in std_logic
);
end component;
component sram_4en generic
(
WIDTH : positive;
SIZE : positive
);
port
(
dat_o : out std_logic_vector(WIDTH - 1 downto 0);
dat_i : in std_logic_vector(WIDTH - 1 downto 0);
adr_i : in std_logic_vector(SIZE - 1 downto 0);
wre_i : in std_logic_vector(3 downto 0);
ena_i : in std_logic;
clk_i : in std_logic
);
end component;
component dsram generic
(
WIDTH : positive;
SIZE : positive
);
port
(
dat_o : out std_logic_vector(WIDTH - 1 downto 0);
adr_i : in std_logic_vector(SIZE - 1 downto 0);
ena_i : in std_logic;
dat_w_i : in std_logic_vector(WIDTH - 1 downto 0);
adr_w_i : in std_logic_vector(SIZE - 1 downto 0);
wre_i : in std_logic;
clk_i : in std_logic
);
end component;
----------------------------------------------------------------------------------------------
-- FUNCTIONS IN STD_PKG
----------------------------------------------------------------------------------------------
function v_or(d : std_logic_vector) return std_logic;
function is_zero(d : std_logic_vector) return std_logic;
function is_not_zero(d : std_logic_vector) return std_logic;
function my_conv_integer(a: std_logic_vector) return integer;
function notx(d : std_logic_vector) return boolean;
function compare(a, b : std_logic_vector) return std_logic;
function multiply(a, b : std_logic_vector) return std_logic_vector;
function sign_extend(value: std_logic_vector; fill: std_logic; size: positive) return std_logic_vector;
function add(a, b : std_logic_vector; ci: std_logic) return std_logic_vector;
function increment(a : std_logic_vector) return std_logic_vector;
function shift(value : std_logic_vector(31 downto 0); shamt: std_logic_vector(4 downto 0); s: std_logic; t: std_logic) return std_logic_vector;
function shift_left(value : std_logic_vector(31 downto 0); shamt : std_logic_vector(4 downto 0)) return std_logic_vector;
function shift_right(value : std_logic_vector(31 downto 0); shamt : std_logic_vector(4 downto 0); padding: std_logic) return std_logic_vector;
end std_Pkg;
PACKAGE BODY std_Pkg IS
-- Unary OR reduction
function v_or(d : std_logic_vector) return std_logic is
variable z : std_logic;
begin
z := '0';
if notx (d) then
for i in d'range loop
z := z or d(i);
end loop;
end if;
return z;
end;
-- Check for ones in the vector
function is_not_zero(d : std_logic_vector) return std_logic is
variable z : std_logic_vector(d'range);
begin
z := (others => '0');
if notx(d) then
if d = z then
return '0';
else
return '1';
end if;
else
return '0';
end if;
end;
-- Check for ones in the vector
function is_zero(d : std_logic_vector) return std_logic is
begin
return not is_not_zero(d);
end;
-- rewrite conv_integer to avoid modelsim warnings
function my_conv_integer(a : std_logic_vector) return integer is
variable res : integer range 0 to 2**a'length-1;
begin
res := 0;
if (notx(a)) then
res := to_integer(unsigned(a));
end if;
return res;
end;
function compare(a, b : std_logic_vector) return std_logic is
variable z : std_logic;
begin
if notx(a & b) and a = b then
return '1';
else
return '0';
end if;
end;
-- Unary NOT X test
function notx(d : std_logic_vector) return boolean is
variable res : boolean;
begin
res := true;
-- pragma translate_off
res := not is_x(d);
-- pragma translate_on
return (res);
end;
-- -- 32 bit shifter
-- -- SYNOPSIS:
-- -- value: value to be shifted
-- -- shamt: shift amount
-- -- s 0 / 1: shift right / left
-- -- t 0 / 1: shift logical / arithmetic
-- -- PSEUDOCODE (from microblaze reference guide)
-- -- if S = 1 then
-- -- (rD) = (rA) << (rB)[27:31]
-- -- else
-- -- if T = 1 then
-- -- if ((rB)[27:31]) != 0 then
-- -- (rD)[0:(rB)[27:31]-1] = (rA)[0]
-- -- (rD)[(rB)[27:31]:31] = (rA) >> (rB)[27:31]
-- -- else
-- -- (rD) = (rA)
-- -- else
-- -- (rD) = (rA) >> (rB)[27:31]
function shift(value: std_logic_vector(31 downto 0); shamt: std_logic_vector(4 downto 0); s: std_logic; t: std_logic) return std_logic_vector is
begin
if s = '1' then
-- left arithmetic or logical shift
return shift_left(value, shamt);
else
if t = '1' then
-- right arithmetic shift
return shift_right(value, shamt, value(31));
else
-- right logical shift
return shift_right(value, shamt, '0');
end if;
end if;
end;
function shift_left(value: std_logic_vector(31 downto 0); shamt: std_logic_vector(4 downto 0)) return std_logic_vector is
variable result: std_logic_vector(31 downto 0);
variable paddings: std_logic_vector(15 downto 0);
begin
paddings := (others => '0');
result := value;
if (shamt(4) = '1') then result := result(15 downto 0) & paddings(15 downto 0); end if;
if (shamt(3) = '1') then result := result(23 downto 0) & paddings( 7 downto 0); end if;
if (shamt(2) = '1') then result := result(27 downto 0) & paddings( 3 downto 0); end if;
if (shamt(1) = '1') then result := result(29 downto 0) & paddings( 1 downto 0); end if;
if (shamt(0) = '1') then result := result(30 downto 0) & paddings( 0 ); end if;
return result;
end;
function shift_right(value: std_logic_vector(31 downto 0); shamt: std_logic_vector(4 downto 0); padding: std_logic) return std_logic_vector is
variable result: std_logic_vector(31 downto 0);
variable paddings: std_logic_vector(15 downto 0);
begin
paddings := (others => padding);
result := value;
if (shamt(4) = '1') then result := paddings(15 downto 0) & result(31 downto 16); end if;
if (shamt(3) = '1') then result := paddings( 7 downto 0) & result(31 downto 8); end if;
if (shamt(2) = '1') then result := paddings( 3 downto 0) & result(31 downto 4); end if;
if (shamt(1) = '1') then result := paddings( 1 downto 0) & result(31 downto 2); end if;
if (shamt(0) = '1') then result := paddings( 0 ) & result(31 downto 1); end if;
return result;
end;
function multiply(a, b: std_logic_vector) return std_logic_vector is
variable x: std_logic_vector (a'length + b'length - 1 downto 0);
begin
x := std_logic_vector(signed(a) * signed(b));
return x(31 downto 0);
end;
function sign_extend(value: std_logic_vector; fill: std_logic; size: positive) return std_logic_vector is
variable a: std_logic_vector (size - 1 downto 0);
begin
a(size - 1 downto value'length) := (others => fill);
a(value'length - 1 downto 0) := value;
return a;
end;
function add(a, b : std_logic_vector; ci: std_logic) return std_logic_vector is
variable x : std_logic_vector(a'length + 1 downto 0);
begin
x := (others => '0');
if notx (a & b & ci) then
x := std_logic_vector(signed('0' & a & '1') + signed('0' & b & ci));
end if;
return x(a'length + 1 downto 1);
end;
function increment(a : std_logic_vector) return std_logic_vector is
variable x : std_logic_vector(a'length-1 downto 0);
begin
x := (others => '0');
if notx (a) then
x := std_logic_vector(signed(a) + 1);
end if;
return x;
end;
end std_Pkg;

6
mblite_rom.bmm Normal file
View File

@@ -0,0 +1,6 @@
ADDRESS_SPACE mblite_rom RAMB16 [0x00000000:0x00000FFF]
BUS_BLOCK
cpu_inst/mblite_rom_inst/rom1_inst [31:16];
cpu_inst/mblite_rom_inst/rom0_inst [15:0];
END_BUS_BLOCK;
END_ADDRESS_SPACE;

243
src/mblite_rom.vhd Normal file
View File

@@ -0,0 +1,243 @@
-- Title : mblite core instruction ROM
-- Project :
-------------------------------------------------------------------------------
-- File : mblite_rom.vhd
-- Author : Matthias Blankertz <matthias@blankertz.org>
-- Company :
-- Created : 2013-06-02
-- Last update: 2013-06-03
-- Platform :
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
-- Copyright (c) 2013
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2013-06-02 1.0 matthias Created
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
use work.mblite_rom_data_pkg_mblite_rom.all;
use work.intercon_package.all;
entity mblite_rom is
port (
clka : IN STD_LOGIC;
ena : IN STD_LOGIC;
addra : IN STD_LOGIC_VECTOR(9 DOWNTO 0);
douta : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
wbs_i : in mblite_rom_wbs_i_type;
wbs_o : out mblite_rom_wbs_o_type
);
end entity mblite_rom;
architecture Mixed of mblite_rom is
signal wb_clk : std_logic;
begin
wb_clk <= clka;
wb_ack : process(clka)
begin
if rising_edge(clka) then
wbs_o.ack_o <= wbs_i.stb_i and wbs_i.cyc_i;
end if;
end process wb_ack;
rom0_inst : ramb16_s18_s18
generic map (
INIT_00 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_00,
INIT_01 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_01,
INIT_02 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_02,
INIT_03 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_03,
INIT_04 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_04,
INIT_05 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_05,
INIT_06 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_06,
INIT_07 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_07,
INIT_08 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_08,
INIT_09 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_09,
INIT_0A => cpu_inst_mblite_rom_inst_rom0_inst_INIT_0A,
INIT_0B => cpu_inst_mblite_rom_inst_rom0_inst_INIT_0B,
INIT_0C => cpu_inst_mblite_rom_inst_rom0_inst_INIT_0C,
INIT_0D => cpu_inst_mblite_rom_inst_rom0_inst_INIT_0D,
INIT_0E => cpu_inst_mblite_rom_inst_rom0_inst_INIT_0E,
INIT_0F => cpu_inst_mblite_rom_inst_rom0_inst_INIT_0F,
INIT_10 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_10,
INIT_11 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_11,
INIT_12 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_12,
INIT_13 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_13,
INIT_14 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_14,
INIT_15 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_15,
INIT_16 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_16,
INIT_17 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_17,
INIT_18 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_18,
INIT_19 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_19,
INIT_1A => cpu_inst_mblite_rom_inst_rom0_inst_INIT_1A,
INIT_1B => cpu_inst_mblite_rom_inst_rom0_inst_INIT_1B,
INIT_1C => cpu_inst_mblite_rom_inst_rom0_inst_INIT_1C,
INIT_1D => cpu_inst_mblite_rom_inst_rom0_inst_INIT_1D,
INIT_1E => cpu_inst_mblite_rom_inst_rom0_inst_INIT_1E,
INIT_1F => cpu_inst_mblite_rom_inst_rom0_inst_INIT_1F,
INIT_20 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_20,
INIT_21 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_21,
INIT_22 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_22,
INIT_23 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_23,
INIT_24 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_24,
INIT_25 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_25,
INIT_26 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_26,
INIT_27 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_27,
INIT_28 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_28,
INIT_29 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_29,
INIT_2A => cpu_inst_mblite_rom_inst_rom0_inst_INIT_2A,
INIT_2B => cpu_inst_mblite_rom_inst_rom0_inst_INIT_2B,
INIT_2C => cpu_inst_mblite_rom_inst_rom0_inst_INIT_2C,
INIT_2D => cpu_inst_mblite_rom_inst_rom0_inst_INIT_2D,
INIT_2E => cpu_inst_mblite_rom_inst_rom0_inst_INIT_2E,
INIT_2F => cpu_inst_mblite_rom_inst_rom0_inst_INIT_2F,
INIT_30 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_30,
INIT_31 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_31,
INIT_32 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_32,
INIT_33 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_33,
INIT_34 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_34,
INIT_35 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_35,
INIT_36 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_36,
INIT_37 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_37,
INIT_38 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_38,
INIT_39 => cpu_inst_mblite_rom_inst_rom0_inst_INIT_39,
INIT_3A => cpu_inst_mblite_rom_inst_rom0_inst_INIT_3A,
INIT_3B => cpu_inst_mblite_rom_inst_rom0_inst_INIT_3B,
INIT_3C => cpu_inst_mblite_rom_inst_rom0_inst_INIT_3C,
INIT_3D => cpu_inst_mblite_rom_inst_rom0_inst_INIT_3D,
INIT_3E => cpu_inst_mblite_rom_inst_rom0_inst_INIT_3E,
INIT_3F => cpu_inst_mblite_rom_inst_rom0_inst_INIT_3F
)
port map (
doa => douta(15 downto 0),
dopa => open,
dia => x"0000",
dipa => "00",
addra => addra,
wea => '0',
ena => ena,
ssra => '0',
clka => clka,
dob => wbs_o.dat_o(15 downto 0),
dopb => open,
dib => x"0000",
dipb => "00",
addrb => wbs_i.adr_i,
web => '0',
enb => '1',
ssrb => '0',
clkb => wb_clk
);
rom1_inst : ramb16_s18_s18
generic map (
INIT_00 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_00,
INIT_01 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_01,
INIT_02 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_02,
INIT_03 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_03,
INIT_04 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_04,
INIT_05 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_05,
INIT_06 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_06,
INIT_07 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_07,
INIT_08 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_08,
INIT_09 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_09,
INIT_0A => cpu_inst_mblite_rom_inst_rom1_inst_INIT_0A,
INIT_0B => cpu_inst_mblite_rom_inst_rom1_inst_INIT_0B,
INIT_0C => cpu_inst_mblite_rom_inst_rom1_inst_INIT_0C,
INIT_0D => cpu_inst_mblite_rom_inst_rom1_inst_INIT_0D,
INIT_0E => cpu_inst_mblite_rom_inst_rom1_inst_INIT_0E,
INIT_0F => cpu_inst_mblite_rom_inst_rom1_inst_INIT_0F,
INIT_10 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_10,
INIT_11 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_11,
INIT_12 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_12,
INIT_13 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_13,
INIT_14 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_14,
INIT_15 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_15,
INIT_16 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_16,
INIT_17 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_17,
INIT_18 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_18,
INIT_19 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_19,
INIT_1A => cpu_inst_mblite_rom_inst_rom1_inst_INIT_1A,
INIT_1B => cpu_inst_mblite_rom_inst_rom1_inst_INIT_1B,
INIT_1C => cpu_inst_mblite_rom_inst_rom1_inst_INIT_1C,
INIT_1D => cpu_inst_mblite_rom_inst_rom1_inst_INIT_1D,
INIT_1E => cpu_inst_mblite_rom_inst_rom1_inst_INIT_1E,
INIT_1F => cpu_inst_mblite_rom_inst_rom1_inst_INIT_1F,
INIT_20 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_20,
INIT_21 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_21,
INIT_22 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_22,
INIT_23 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_23,
INIT_24 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_24,
INIT_25 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_25,
INIT_26 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_26,
INIT_27 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_27,
INIT_28 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_28,
INIT_29 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_29,
INIT_2A => cpu_inst_mblite_rom_inst_rom1_inst_INIT_2A,
INIT_2B => cpu_inst_mblite_rom_inst_rom1_inst_INIT_2B,
INIT_2C => cpu_inst_mblite_rom_inst_rom1_inst_INIT_2C,
INIT_2D => cpu_inst_mblite_rom_inst_rom1_inst_INIT_2D,
INIT_2E => cpu_inst_mblite_rom_inst_rom1_inst_INIT_2E,
INIT_2F => cpu_inst_mblite_rom_inst_rom1_inst_INIT_2F,
INIT_30 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_30,
INIT_31 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_31,
INIT_32 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_32,
INIT_33 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_33,
INIT_34 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_34,
INIT_35 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_35,
INIT_36 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_36,
INIT_37 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_37,
INIT_38 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_38,
INIT_39 => cpu_inst_mblite_rom_inst_rom1_inst_INIT_39,
INIT_3A => cpu_inst_mblite_rom_inst_rom1_inst_INIT_3A,
INIT_3B => cpu_inst_mblite_rom_inst_rom1_inst_INIT_3B,
INIT_3C => cpu_inst_mblite_rom_inst_rom1_inst_INIT_3C,
INIT_3D => cpu_inst_mblite_rom_inst_rom1_inst_INIT_3D,
INIT_3E => cpu_inst_mblite_rom_inst_rom1_inst_INIT_3E,
INIT_3F => cpu_inst_mblite_rom_inst_rom1_inst_INIT_3F
)
port map (
doa => douta(31 downto 16),
dopa => open,
dia => x"0000",
dipa => "00",
addra => addra,
wea => '0',
ena => ena,
ssra => '0',
clka => clka,
dob => wbs_o.dat_o(31 downto 16),
dopb => open,
dib => x"0000",
dipb => "00",
addrb => wbs_i.adr_i,
web => '0',
enb => '1',
ssrb => '0',
clkb => wb_clk
);
end Mixed;

97
src/mblite_wrapper.vhd Normal file
View File

@@ -0,0 +1,97 @@
-------------------------------------------------------------------------------
-- Title : Wrapper to integrate mblite core
-- Project :
-------------------------------------------------------------------------------
-- File : mblite_wrapper.vhd
-- Author : Matthias Blankertz <matthias@blankertz.org>
-- Company :
-- Created : 2013-06-02
-- Last update: 2013-06-03
-- Platform :
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
-- Copyright (c) 2013
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2013-06-02 1.0 matthias Created
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
use work.intercon_package.all;
library mblite;
use mblite.core_Pkg.all;
entity mblite_wrapper is
port (
clk_i : in std_logic;
rst_i : in std_logic;
wbm_i : in cpu_wbm_i_type;
wbm_o : out cpu_wbm_o_type;
rom_wbs_i : in mblite_rom_wbs_i_type;
rom_wbs_o : out mblite_rom_wbs_o_type
);
end mblite_wrapper;
architecture Mixed of mblite_wrapper is
signal mb_imem_o : imem_out_type;
signal mb_imem_i : imem_in_type;
signal mb_wb_o : wb_mst_out_type;
signal mb_wb_i : wb_mst_in_type;
begin
mb_wb_i.clk_i <= clk_i;
mb_wb_i.rst_i <= rst_i;
mblite_inst : entity mblite.core_wb
port map (
imem_o => mb_imem_o,
imem_i => mb_imem_i,
wb_o => mb_wb_o,
wb_i => mb_wb_i
);
mblite_rom_inst : entity work.mblite_rom
port map (
clka => clk_i,
ena => mb_imem_o.ena_o,
addra => mb_imem_o.adr_o(11 downto 2),
douta => mb_imem_i.dat_i,
wbs_i => rom_wbs_i,
wbs_o => rom_wbs_o
);
wb_reg : process(clk_i)
begin
if rising_edge(clk_i) then
wbm_o.adr_o <= mb_wb_o.adr_o;
wbm_o.we_o <= mb_wb_o.we_o;
wbm_o.sel_o <= mb_wb_o.sel_o;
end if;
end process wb_reg;
wbm_o.dat_o <= mb_wb_o.dat_o;
wbm_o.stb_o <= mb_wb_o.stb_o;
wbm_o.cyc_o <= mb_wb_o.cyc_o;
mb_wb_i.dat_i <= wbm_i.dat_i;
mb_wb_i.ack_i <= wbm_i.ack_i;
mb_wb_i.int_i <= '0';
end Mixed;

130
src/pio.vhd Normal file
View File

@@ -0,0 +1,130 @@
-------------------------------------------------------------------------------
-- Title : Simple wishbone PIO
-- Project :
-------------------------------------------------------------------------------
-- File : pio.vhd
-- Author : Matthias Blankertz <matthias@blankertz.org>
-- Company :
-- Created : 2013-06-02
-- Last update: 2013-06-02
-- Platform :
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
-- Copyright (c) 2013
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2013-06-02 1.0 matthias Created
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
use work.intercon_package.all;
entity pio is
generic (
port_width : integer := 8;
port_in : boolean := false;
reset_val : std_logic_vector(31 downto 0) := (others => '0')
);
port (
clk_i : in std_logic;
rst_i : in std_logic;
dat_i : in std_logic_vector(31 downto 0);
we_i : in std_logic;
sel_i : in std_logic_vector(3 downto 0);
cyc_i : in std_logic;
stb_i : in std_logic;
dat_o : out std_logic_vector(31 downto 0);
ack_o : out std_logic;
pio_in : in std_logic_vector(port_width-1 downto 0) := (others => '0');
pio_out : out std_logic_vector(port_width-1 downto 0)
);
end pio;
architecture Behavioral of pio is
signal pio_reg : std_logic_vector(31 downto 0);
type pio_sr_t is array(0 to 2) of std_logic_vector(port_width-1 downto 0);
signal pio_sr : pio_sr_t;
begin
out_pio : if not port_in generate
ctrl : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_i = '1' then
pio_reg(port_width-1 downto 0) <= reset_val(port_width-1 downto 0);
ack_o <= '0';
else
if cyc_i = '1' and stb_i = '1' and we_i = '1' then
if sel_i(0) = '1' then
pio_reg(7 downto 0) <= dat_i(7 downto 0);
end if;
if sel_i(1) = '1' then
pio_reg(15 downto 8) <= dat_i(15 downto 8);
end if;
if sel_i(2) = '1' then
pio_reg(23 downto 16) <= dat_i(23 downto 16);
end if;
if sel_i(3) = '1' then
pio_reg(31 downto 24) <= dat_i(31 downto 24);
end if;
end if;
ack_o <= cyc_i and stb_i;
end if;
end if;
end process ctrl;
pio_out <= pio_reg(port_width-1 downto 0);
fill_zeros : if port_width < 32 generate
dat_o(31 downto port_width) <= (others => '0');
end generate;
dat_o(port_width-1 downto 0) <= pio_reg(port_width-1 downto 0);
end generate;
in_pio : if port_in generate
-- input metastability protection
pio_in_sr : process(clk_i)
begin
if rising_edge(clk_i) then
pio_sr <= pio_in & pio_sr(0 to 1);
end if;
end process pio_in_sr;
ctrl : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_i = '1' then
ack_o <= '0';
else
ack_o <= cyc_i and stb_i;
end if;
end if;
end process ctrl;
fill_zeros : if port_width < 32 generate
dat_o(31 downto port_width) <= (others => '0');
end generate;
dat_o(port_width-1 downto 0) <= pio_sr(2);
end generate;
end Behavioral;

View File

@@ -52,7 +52,7 @@ entity toplevel is
dataflash_miso : IN std_ulogic;
-- LEDs
-- led : OUT std_ulogic_vector(7 downto 0);
led : OUT std_logic_vector(7 downto 0);
-- DDR2 SDRAM
ddr2_dq : inout std_logic_vector(15 downto 0);
@@ -70,171 +70,46 @@ entity toplevel is
ddr2_dqs : inout std_logic_vector(1 downto 0);
ddr2_dqs_n : inout std_logic_vector(1 downto 0);
ddr2_ck : out std_logic_vector(0 downto 0);
ddr2_ck_n : out std_logic_vector(0 downto 0)
ddr2_ck_n : out std_logic_vector(0 downto 0);
-- RS232
rs232_txd : out std_logic;
rs232_rxd : in std_logic
);
end toplevel;
architecture Mixed of toplevel is
component clk_reset is
Generic (
reset_dcm_on_ext_reset : BOOLEAN := false
);
Port ( clkIn50 : in STD_LOGIC;
sysClk50 : out STD_LOGIC;
sysClk25 : out std_logic;
rstIn : in STD_LOGIC;
sysRst50 : out STD_LOGIC);
end component;
component wb_ddr_ctrl is
generic (
dontcare : std_logic := '-'
);
Port (
-- DDR2 control
ddr2_clock : in std_ulogic;
ddr2_reset : in std_ulogic;
-- DDR2 SDRAM
ddr2_dq : inout std_logic_vector(15 downto 0);
ddr2_a : out std_logic_vector(12 downto 0);
ddr2_ba : out std_logic_vector(1 downto 0);
ddr2_cke : out std_logic;
ddr2_cs_n : out std_logic;
ddr2_ras_n : out std_logic;
ddr2_cas_n : out std_logic;
ddr2_we_n : out std_logic;
ddr2_odt : out std_logic;
ddr2_dm : out std_logic_vector(1 downto 0);
rst_dqs_div_in : in std_logic;
rst_dqs_div_out : out std_logic;
ddr2_dqs : inout std_logic_vector(1 downto 0);
ddr2_dqs_n : inout std_logic_vector(1 downto 0);
ddr2_ck : out std_logic_vector(0 downto 0);
ddr2_ck_n : out std_logic_vector(0 downto 0);
-- Wishbone slave
clk_i : in std_ulogic;
rst_i : in std_ulogic;
wbs_i : in sdram_ctrl_wbs_i_type;
wbs_o : out sdram_ctrl_wbs_o_type;
wbs_cc_i : in sdram_ctrl_cc_wbs_i_type;
wbs_cc_o : out sdram_ctrl_cc_wbs_o_type;
signal sysClk, sysRst, vgaClk : std_logic;
-- Direct memctrl access for VGA
vga_mem_rdrq : in std_logic;
vga_mem_adr : in std_logic_vector(19 downto 0);
vga_mem_ack : out std_logic;
vga_mem_dat_i : out std_logic_vector(63 downto 0)
);
end component;
component vga
generic (
h_total_pixels : integer;
h_front_porch : integer;
h_back_porch : integer;
h_sync_pulse : integer;
h_sync_pos : boolean;
h_active_pixels : integer;
v_total_lines : integer;
v_front_porch : integer;
v_back_porch : integer;
v_sync_pulse : integer;
v_sync_pos : boolean;
v_active_lines : integer;
framebuffer0_base : integer;
burst_length : integer;
burst_length_ln2 : integer;
addr_width : integer;
dontcare : std_logic);
port (
clk_in : in std_logic;
clk_vga : in std_logic;
rst : in std_logic;
mem_rdrq : out std_logic;
mem_adr : out std_logic_vector(19 downto 0);
mem_ack : in std_logic;
mem_dat_i : in std_logic_vector(63 downto 0);
red : out std_logic_vector(3 downto 0);
green : out std_logic_vector(3 downto 0);
blue : out std_logic_vector(3 downto 0);
vsync : out std_logic;
hsync : out std_logic;
fb_in_use : out std_logic;
fb_flip : in std_logic;
fb_flip_ack : out std_logic);
end component;
component cpu
port (
rst_i : in std_logic;
clk_i : in std_logic;
wbm_i : in cpu_wbm_i_type;
wbm_o : out cpu_wbm_o_type;
fb_in_use : in std_logic;
fb_flip : out std_logic;
fb_flip_ack : in std_logic);
end component;
component wb_ram
port (
clk_i : in std_logic;
wbs_i : in ram_wbs_i_type;
wbs_o : out ram_wbs_o_type);
end component;
component wb_rom
port (
clk_i : in std_logic;
wbs_i : in rom_wbs_i_type;
wbs_o : out rom_wbs_o_type);
end component;
signal cpu_wbm_o : cpu_wbm_o_type;
signal cpu_wbm_i : cpu_wbm_i_type;
signal ram_wbs_o : ram_wbs_o_type;
signal ram_wbs_i : ram_wbs_i_type;
signal rom_wbs_o : mblite_rom_wbs_o_type;
signal rom_wbs_i : mblite_rom_wbs_i_type;
signal sdram_ctrl_wbs_i : sdram_ctrl_wbs_i_type;
signal sdram_ctrl_wbs_o : sdram_ctrl_wbs_o_type;
signal sdram_ctrl_cc_wbs_i : sdram_ctrl_cc_wbs_i_type;
signal sdram_ctrl_cc_wbs_o : sdram_ctrl_cc_wbs_o_type;
signal pio_led_wbs_i : pio_led_wbs_i_type;
signal pio_led_wbs_o : pio_led_wbs_o_type;
signal uart_wbs_i : uart_wbs_i_type;
signal uart_wbs_o : uart_wbs_o_type;
component intercon
port (
dummy_wbm_o : in dummy_wbm_o_type;
cpu_wbm_i : out cpu_wbm_i_type;
cpu_wbm_o : in cpu_wbm_o_type;
ram_wbs_i : out ram_wbs_i_type;
ram_wbs_o : in ram_wbs_o_type;
rom_wbs_i : out rom_wbs_i_type;
rom_wbs_o : in rom_wbs_o_type;
sdram_ctrl_wbs_i : out sdram_ctrl_wbs_i_type;
sdram_ctrl_wbs_o : in sdram_ctrl_wbs_o_type;
sdram_ctrl_cc_wbs_i : out sdram_ctrl_cc_wbs_i_type;
sdram_ctrl_cc_wbs_o : in sdram_ctrl_cc_wbs_o_type;
clk : in std_logic;
reset : in std_logic);
end component;
signal sysClk, sysRst, vgaClk : std_logic;
signal cpu_wbm_o : cpu_wbm_o_type;
signal cpu_wbm_i : cpu_wbm_i_type;
signal ram_wbs_o : ram_wbs_o_type;
signal ram_wbs_i : ram_wbs_i_type;
signal rom_wbs_o : rom_wbs_o_type;
signal rom_wbs_i : rom_wbs_i_type;
signal sdram_ctrl_wbs_i : sdram_ctrl_wbs_i_type;
signal sdram_ctrl_wbs_o : sdram_ctrl_wbs_o_type;
signal sdram_ctrl_cc_wbs_i : sdram_ctrl_cc_wbs_i_type;
signal sdram_ctrl_cc_wbs_o : sdram_ctrl_cc_wbs_o_type;
signal vga_mem_rdrq : std_logic;
signal vga_mem_adr : std_logic_vector(19 downto 0);
signal vga_mem_ack : std_logic;
signal vga_mem_dat_i : std_logic_vector(63 downto 0);
signal vga_mem_rdrq : std_logic;
signal vga_mem_adr : std_logic_vector(19 downto 0);
signal vga_mem_ack : std_logic;
signal vga_mem_dat_i : std_logic_vector(63 downto 0);
signal reset_int : std_logic;
signal reset_int : std_logic;
signal fb_flip, fb_flip_ack, fb_in_use : std_logic;
signal fb_flip, fb_flip_ack, fb_in_use : std_logic;
signal pio_led_out : std_logic_vector(7 downto 0);
begin
reset_int <= reset;
sys_clk_rst : clk_reset
sys_clk_rst : entity work.clk_reset
port map (
clkIn50 => clkin_50MHz,
rstIn => reset_int,
@@ -243,7 +118,7 @@ sys_clk_rst : clk_reset
sysRst50 => sysRst
);
ddr_ctrl0 : wb_ddr_ctrl
ddr_ctrl0 : entity work.wb_ddr_ctrl
generic map (
dontcare => dontcare
)
@@ -283,7 +158,7 @@ ddr_ctrl0 : wb_ddr_ctrl
vga_mem_dat_i => vga_mem_dat_i
);
vga_1: vga
vga_1: entity work.vga
generic map (
h_total_pixels => 800,
h_front_porch => 16,
@@ -322,42 +197,75 @@ vga_1: vga
fb_flip => fb_flip,
fb_flip_ack => fb_flip_ack);
wb_ram_inst: wb_ram
wb_ram_inst: entity work.wb_ram
port map (
clk_i => sysClk,
wbs_i => ram_wbs_i,
wbs_o => ram_wbs_o);
wb_rom_inst: wb_rom
pio_led: entity work.pio
port map (
clk_i => sysClk,
wbs_i => rom_wbs_i,
wbs_o => rom_wbs_o);
rst_i => sysRst,
cpu_system_inst: cpu
dat_i => pio_led_wbs_i.dat_i,
we_i => pio_led_wbs_i.we_i,
sel_i => pio_led_wbs_i.sel_i,
cyc_i => pio_led_wbs_i.cyc_i,
stb_i => pio_led_wbs_i.stb_i,
dat_o => pio_led_wbs_o.dat_o,
ack_o => pio_led_wbs_o.ack_o,
pio_out => pio_led_out
);
uart_inst: entity work.uart_wbc
port map (
rst_i => sysRst,
clk_i => sysClk,
CLK_I => sysClk,
RST_I => sysRst,
wbm_i => cpu_wbm_i,
wbm_o => cpu_wbm_o,
DAT_O => uart_wbs_o.dat_o(7 downto 0),
DAT_I => uart_wbs_i.dat_i(7 downto 0),
ACK_O => uart_wbs_o.ack_o,
STB_I => uart_wbs_i.stb_i,
WE_I => uart_wbs_i.we_i,
ADR_I => uart_wbs_i.adr_i,
fb_in_use => fb_in_use,
fb_flip => fb_flip,
fb_flip_ack => fb_flip_ack);
SERIALIN => rs232_rxd,
SERIALOUT => rs232_txd
);
intercon_1: intercon
cpu_inst : entity work.mblite_wrapper
port map (
clk_i => sysClk,
rst_i => sysRst,
wbm_i => cpu_wbm_i,
wbm_o => cpu_wbm_o,
rom_wbs_i => rom_wbs_i,
rom_wbs_o => rom_wbs_o
);
fb_flip <= '0';
intercon_1: entity work.intercon
port map (
cpu_wbm_i => cpu_wbm_i,
cpu_wbm_o => cpu_wbm_o,
rom_wbs_i => rom_wbs_i,
rom_wbs_o => rom_wbs_o,
mblite_rom_wbs_i => rom_wbs_i,
mblite_rom_wbs_o => rom_wbs_o,
ram_wbs_i => ram_wbs_i,
ram_wbs_o => ram_wbs_o,
sdram_ctrl_wbs_i => sdram_ctrl_wbs_i,
sdram_ctrl_wbs_o => sdram_ctrl_wbs_o,
sdram_ctrl_cc_wbs_i => sdram_ctrl_cc_wbs_i,
sdram_ctrl_cc_wbs_o => sdram_ctrl_cc_wbs_o,
pio_led_wbs_o => pio_led_wbs_o,
pio_led_wbs_i => pio_led_wbs_i,
uart_wbs_o => uart_wbs_o,
uart_wbs_i => uart_wbs_i,
dummy_wbm_o => ("----", (others => '-'), "--", "---", '0', '0'),
clk => sysClk,
reset => sysRst);
@@ -368,4 +276,6 @@ dataflash_ss <= 'Z';
dataflash_wp <= 'Z';
dataflash_rst <= 'Z';
led <= pio_led_out;
end Mixed;

73
src/uart/fifo16x8.vhd Executable file
View File

@@ -0,0 +1,73 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 14:10:50 12/28/2008
-- Design Name:
-- Module Name: fifo16x8 - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
entity fifo16x8 is
Port ( DATAIN : in STD_LOGIC_VECTOR (7 downto 0);
WRITESTB : in STD_LOGIC;
DATAOUT : out STD_LOGIC_VECTOR (7 downto 0);
READSTB : in STD_LOGIC;
CLK : in STD_LOGIC;
FULL : out STD_LOGIC;
EMPTY : out STD_LOGIC);
end fifo16x8;
architecture Behavioral of fifo16x8 is
signal counter: std_logic_vector(3 downto 0) := "1111";
begin
shift: for i in 0 to 7 generate
srl16e_inst: SRL16E
port map (
Q => DATAOUT(i),
A0 => counter(0),
A1 => counter(1),
A2 => counter(2),
A3 => counter(3),
CE => WRITESTB,
CLK => CLK,
D => DATAIN(i));
end generate;
fifo: process(CLK)
begin
if rising_edge(CLK) then
if (WRITESTB = '0') and (READSTB = '1') then
counter <= counter - 1;
elsif (WRITESTB = '1') and (READSTB = '0') then
counter <= counter + 1;
else
counter <= counter;
end if;
end if;
end process;
FULL <= '1' when counter = "1110" else '0';
EMPTY <= '1' when counter = "1111" else '0';
end Behavioral;

55
src/uart/par2ser.vhd Executable file
View File

@@ -0,0 +1,55 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 17:13:06 12/28/2008
-- Design Name:
-- Module Name: par2ser - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity par2ser is
Port ( CLK : in STD_LOGIC;
WRITESTB : in STD_LOGIC;
LOAD : in STD_LOGIC;
DATAIN : in STD_LOGIC_VECTOR (7 downto 0);
RS232OUT : out STD_LOGIC := '1');
end par2ser;
architecture Behavioral of par2ser is
signal data: std_logic_vector(9 downto 0) := "1111111111";
begin
process(CLK)
begin
if rising_edge(CLK) then
if LOAD = '1' then
data <= '1' & DATAIN & '0'; -- stop bit, data, start bit;
elsif WRITESTB = '1' then
RS232OUT <= data(0);
data <= '1' & data(9 downto 1);
end if;
end if;
end process;
end Behavioral;

80
src/uart/pulsegen325.vhd Executable file
View File

@@ -0,0 +1,80 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 11:58:32 12/26/2008
-- Design Name:
-- Module Name: clkdiv325 - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
entity pulsegen325 is
Port ( CLK : in STD_LOGIC;
PULSE : out STD_LOGIC);
end pulsegen325;
-- 9600 baud with 50 MHz clk
--architecture Behavioral of pulsegen325 is
--signal pulse_out: std_logic;
--signal sr25_16: std_logic_vector(15 downto 0) := "0000000000000001";
--signal sr25_9: std_logic_vector(8 downto 0) := "000000000";
--signal sr13_13: std_logic_vector(12 downto 0) := "0000000000001";
--begin
-- process(CLK)
-- begin
-- if rising_edge(CLK) then
-- sr25_16 <= sr25_16(14 downto 0) & sr25_9(8);
-- sr25_9 <= sr25_9(7 downto 0) & sr25_16(15);
--
-- if sr25_9(8) = '1' then
-- sr13_13 <= sr13_13(11 downto 0) & sr13_13(12);
-- end if;
--
-- pulse_out <= sr13_13(12) AND sr25_9(8);
-- end if;
-- end process;
--PULSE <= pulse_out;
--end Behavioral;
-- 57600 baud with 50 MHz clk
-- 115200 baud with 100 MHz clk
architecture Behavioral of pulsegen325 is
signal pulse_out: std_logic;
signal sr9_9: std_logic_vector(8 downto 0) := "000000001";
signal sr6_6: std_logic_vector(5 downto 0) := "000001";
begin
process(CLK)
begin
if rising_edge(CLK) then
sr9_9 <= sr9_9(7 downto 0) & sr9_9(8);
if sr9_9(8) = '1' then
sr6_6 <= sr6_6(4 downto 0) & sr6_6(5);
end if;
pulse_out <= sr6_6(5) AND sr9_9(8);
end if;
end process;
PULSE <= pulse_out;
end Behavioral;

72
src/uart/readctrl.vhd Executable file
View File

@@ -0,0 +1,72 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 12:20:56 12/28/2008
-- Design Name:
-- Module Name: genreadstb - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
entity readctrl is
Port ( CLK : in STD_LOGIC;
PULSE16 : in STD_LOGIC;
RS232IN : in STD_LOGIC;
READSTB : out STD_LOGIC;
DONE : out STD_LOGIC);
end readctrl;
architecture Behavioral of readctrl is
signal rs232in_ff: std_logic := '1';
signal sr8: std_logic_vector(7 downto 0) := "00000000";
signal sr16: std_logic_vector(15 downto 0) := "0000000000000000";
signal dly10_sr10: std_logic_vector(9 downto 0) := "0000000000";
signal start: std_logic := '0';
signal running: std_logic := '0';
begin
process(CLK)
begin
if rising_edge(CLK) then
if PULSE16 = '1' then
rs232in_ff <= RS232IN;
if (rs232in_ff = '1') and (RS232IN = '0') and (running = '0') then
start <= '1';
else
start <= '0';
end if;
running <= (running or start) and (not dly10_sr10(9));
sr8 <= sr8(6 downto 0) & start;
sr16 <= sr16(14 downto 0) & ((sr8(7) or sr16(15)) and (not dly10_sr10(8)));
if (sr8(7) or sr16(15)) = '1' then
dly10_sr10 <= dly10_sr10(8 downto 0) & sr8(7);
end if;
end if;
end if;
end process;
READSTB <= sr16(15) and (not dly10_sr10(8)) and PULSE16;
DONE <= sr16(15) and dly10_sr10(8) and PULSE16;
end Behavioral;

52
src/uart/ser2par.vhd Executable file
View File

@@ -0,0 +1,52 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 13:58:15 12/28/2008
-- Design Name:
-- Module Name: ser2par - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ser2par is
Port ( CLK : in STD_LOGIC;
READSTB : in STD_LOGIC;
RS232IN : in STD_LOGIC;
DATA : out STD_LOGIC_VECTOR (7 downto 0));
end ser2par;
architecture Behavioral of ser2par is
signal shift: std_logic_vector(7 downto 0);
begin
p2s: process(CLK)
begin
if rising_edge(CLK) then
if READSTB = '1' then
shift <= RS232IN & shift(7 downto 1);
end if;
end if;
end process;
DATA <= shift;
end Behavioral;

162
src/uart/uart.vhd Executable file
View File

@@ -0,0 +1,162 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 14:03:38 12/28/2008
-- Design Name:
-- Module Name: rs232_in - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
-- 57600 baud with 50 MHz clk
-- 115200 baud with 100 MHz clk
entity uart is
Port (
CLK : in STD_LOGIC; -- clock
-- serial
SERIALIN : in STD_LOGIC;
SERIALOUT : out STD_LOGIC;
-- data & status
DATAOUT : out STD_LOGIC_VECTOR (7 downto 0);
DATAIN : in STD_LOGIC_VECTOR (7 downto 0);
READFIFOSTB : in STD_LOGIC;
WRITEFIFOSTB : in STD_LOGIC;
READFULL : out STD_LOGIC;
READEMPTY : out STD_LOGIC;
WRITEFULL : out STD_LOGIC;
WRITEEMPTY : out STD_LOGIC);
end uart;
architecture Behavioral of uart is
component ser2par is
Port ( CLK : in STD_LOGIC;
READSTB : in STD_LOGIC;
RS232IN : in STD_LOGIC;
DATA : out STD_LOGIC_VECTOR (7 downto 0));
end component;
component readctrl is
Port ( CLK : in STD_LOGIC;
PULSE16 : in STD_LOGIC;
RS232IN : in STD_LOGIC;
READSTB : out STD_LOGIC;
DONE : out STD_LOGIC);
end component;
component fifo16x8 is
Port ( DATAIN : in STD_LOGIC_VECTOR (7 downto 0);
WRITESTB : in STD_LOGIC;
DATAOUT : out STD_LOGIC_VECTOR (7 downto 0);
READSTB : in STD_LOGIC;
CLK : in STD_LOGIC;
FULL : out STD_LOGIC;
EMPTY : out STD_LOGIC);
end component;
component pulsegen325 is
Port ( CLK : in STD_LOGIC;
PULSE : out STD_LOGIC);
end component;
component par2ser is
Port ( CLK : in STD_LOGIC;
WRITESTB : in STD_LOGIC;
LOAD : in STD_LOGIC;
DATAIN : in STD_LOGIC_VECTOR (7 downto 0);
RS232OUT : out STD_LOGIC);
end component;
component writectrl is
Port ( CLK : in STD_LOGIC;
PULSE16 : in STD_LOGIC;
FIFOEMPTY : in STD_LOGIC;
WRITESTB : out STD_LOGIC;
FIFOREAD : out STD_LOGIC;
P2SLOAD : out STD_LOGIC);
end component;
signal pulse16, readstb, done, full_read, empty_read, writestb, full_write, empty_write, load, writefifo_readstb: std_logic;
signal read_data_in, read_data_out, write_data_out: std_logic_vector(7 downto 0);
begin
pulsegen325_inst: pulsegen325
port map (
CLK => CLK,
PULSE => pulse16);
readctrl_inst: readctrl
port map (
CLK => CLK,
PULSE16 => pulse16,
RS232IN => SERIALIN,
READSTB => readstb,
DONE => done);
ser2par_inst: ser2par
port map (
CLK => CLK,
READSTB => readstb,
RS232IN => SERIALIN,
DATA => read_data_in);
fifo16x8_inst_read: fifo16x8
port map (
DATAIN => read_data_in,
WRITESTB => done,
DATAOUT => read_data_out,
READSTB => READFIFOSTB,
CLK => CLK,
FULL => full_read,
EMPTY => empty_read);
writectrl_inst: writectrl
port map (
CLK => CLK,
PULSE16 => pulse16,
FIFOEMPTY => empty_write,
WRITESTB => writestb,
FIFOREAD => writefifo_readstb,
P2SLOAD => load);
par2ser_inst: par2ser
port map (
CLK => CLK,
WRITESTB => writestb,
LOAD => load,
DATAIN => write_data_out,
RS232OUT => SERIALOUT);
fifo16x8_inst_write: fifo16x8
port map (
DATAIN => DATAIN,
WRITESTB => WRITEFIFOSTB,
DATAOUT => write_data_out,
READSTB => writefifo_readstb,
CLK => CLK,
FULL => full_write,
EMPTY => empty_write);
DATAOUT <= read_data_out;
READFULL <= full_read;
READEMPTY <= empty_read;
WRITEFULL <= full_write;
WRITEEMPTY <= empty_write;
end Behavioral;

116
src/uart/uart_wbc.vhd Executable file
View File

@@ -0,0 +1,116 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 23:07:12 12/28/2008
-- Design Name:
-- Module Name: uart_wbc - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
-- 57600 baud with 50 MHz clk
-- 115200 baud with 100 MHz clk
entity uart_wbc is
Port (
-- Wishbone slave
DAT_O : out STD_LOGIC_VECTOR (7 downto 0);
DAT_I : in STD_LOGIC_VECTOR (7 downto 0);
ACK_O : out STD_LOGIC;
STB_I : in STD_LOGIC;
WE_I : in STD_LOGIC;
RST_I : in STD_LOGIC;
CLK_I : in STD_LOGIC;
ADR_I : in STD_LOGIC_VECTOR (0 downto 0);
-- non-Wishbone signals
SERIALIN : in STD_LOGIC;
SERIALOUT : out STD_LOGIC);
end uart_wbc;
architecture Behavioral of uart_wbc is
component uart is
Port ( CLK : in STD_LOGIC; -- clock
-- serial
SERIALIN : in STD_LOGIC;
SERIALOUT : out STD_LOGIC;
-- data & status
DATAOUT : out STD_LOGIC_VECTOR (7 downto 0);
DATAIN : in STD_LOGIC_VECTOR (7 downto 0);
READFIFOSTB : in STD_LOGIC;
WRITEFIFOSTB : in STD_LOGIC;
READFULL : out STD_LOGIC;
READEMPTY : out STD_LOGIC;
WRITEFULL : out STD_LOGIC;
WRITEEMPTY : out STD_LOGIC);
end component;
signal serialout_o: std_logic;
signal uart_dataout, uart_datain: std_logic_vector(7 downto 0);
signal uart_readfifostb, uart_writefifostb: std_logic := '0';
signal uart_readfull, uart_readempty, uart_writefull, uart_writeempty: std_logic;
signal in_cyc : std_logic := '0';
begin
uart_inst: uart
port map (
CLK => CLK_I,
SERIALIN => SERIALIN,
SERIALOUT => serialout_o,
DATAOUT => uart_dataout,
DATAIN => uart_datain,
READFIFOSTB => uart_readfifostb,
WRITEFIFOSTB => uart_writefifostb,
READFULL => uart_readfull,
READEMPTY => uart_readempty,
WRITEFULL => uart_writefull,
WRITEEMPTY => uart_writeempty);
wb : process(CLK_I)
begin
if rising_edge(CLK_I) then
uart_writefifostb <= '0';
uart_readfifostb <= '0';
if RST_I = '1' then
in_cyc <= '0';
else
if STB_I = '0' then
in_cyc <= '0';
ACK_O <= '0';
elsif STB_I = '1' and in_cyc = '0' then
if ADR_I(0) = '0' and WE_I = '1' then
uart_writefifostb <= '1';
elsif ADR_I(0) = '0' and WE_I = '0' then
uart_readfifostb <= '1';
DAT_O <= uart_dataout;
elsif ADR_I(0) = '1' then
DAT_O <= "----" & uart_readfull & uart_readempty & uart_writefull & uart_writeempty;
end if;
in_cyc <= '1';
ACK_O <= '1';
end if;
end if;
end if;
end process wb;
uart_datain <= DAT_I;
SERIALOUT <= serialout_o;
end Behavioral;

69
src/uart/writectrl.vhd Executable file
View File

@@ -0,0 +1,69 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 15:50:29 12/28/2008
-- Design Name:
-- Module Name: writectrl - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity writectrl is
Port ( CLK : in STD_LOGIC;
PULSE16 : in STD_LOGIC;
FIFOEMPTY : in STD_LOGIC;
WRITESTB : out STD_LOGIC;
FIFOREAD : out STD_LOGIC;
P2SLOAD : out STD_LOGIC);
end writectrl;
architecture Behavioral of writectrl is
signal writestb_sr16: std_logic_vector(15 downto 0) := "0000000000000000";
signal done_sr11: std_logic_vector(10 downto 0) := "00000000000";
signal active: std_logic := '0';
signal start: std_logic := '0';
begin
process(CLK)
begin
if rising_edge(CLK) then
if PULSE16 = '1' then
start <= (active nor FIFOEMPTY) and (not done_sr11(10));
active <= (active or (not FIFOEMPTY)) and (not done_sr11(10));
writestb_sr16 <= writestb_sr16(14 downto 0) & ((writestb_sr16(15) or start) and (not done_sr11(10)));
if (writestb_sr16(15) = '1') or (start = '1') then
done_sr11 <= done_sr11(9 downto 0) & start;
end if;
end if;
end if;
end process;
WRITESTB <= writestb_sr16(15) and PULSE16 and (not done_sr11(10));
P2SLOAD <= start and PULSE16;
fiforeaddly: process(CLK)
begin
if rising_edge(CLK) then
FIFOREAD <= start and PULSE16;
end if;
end process;
end Behavioral;

View File

@@ -131,6 +131,8 @@ architecture Behavioral of wb_ddr_ctrl_wb_sc is
signal out_complete_dly : std_logic_vector(write_delay-1 downto 0) := (others => '0');
signal fifo_to_ddr_full_last : std_logic := '1';
signal wbs_i_dly : sdram_ctrl_wbs_i_type;
begin
wb_ddr_ctrl_wb_sc_fe_1: wb_ddr_ctrl_wb_sc_fe
generic map (
@@ -146,7 +148,7 @@ begin
port map (
clk_i => clk_i,
rst_i => rst_i,
wbs_i => wbs_i,
wbs_i => wbs_i_dly,
wbs_o => wbs_o,
wbs_cc_i => wbs_cc_i,
wbs_cc_o => wbs_cc_o,
@@ -157,6 +159,13 @@ begin
mem_ack => cfe_mem_ack,
mem_dat_i => cfe_mem_dat_i);
dly : process(clk_i)
begin
if rising_edge(clk_i) then
wbs_i_dly <= wbs_i;
end if;
end process dly;
vga_mem_dat_i <= ddr_dout;
vga_mem_ack <= dout_data_valid when bus_owner_reg = B_VGA else
'0';

View File

@@ -441,15 +441,15 @@ begin
user_cc_req_flush <=
wbs_cc_i.dat_i(1) when (wbs_cc_i.cyc_i = '1' and wbs_cc_i.stb_i = '1' and
wbs_cc_i.we_i = '1' and wbs_cc_i.adr_i(2) = '0') else
wbs_cc_i.we_i = '1') else
'0';
user_cc_req_inval <=
wbs_cc_i.dat_i(0) when (wbs_cc_i.cyc_i = '1' and wbs_cc_i.stb_i = '1' and
wbs_cc_i.we_i = '1' and wbs_cc_i.adr_i(2) = '0') else
wbs_cc_i.we_i = '1') else
'0';
user_cc_req_none <=
'1' when (wbs_cc_i.cyc_i = '1' and wbs_cc_i.stb_i = '1' and
(wbs_cc_i.we_i = '0' or wbs_cc_i.adr_i(2) /= '0' or wbs_cc_i.dat_i(1 downto 0) = "00")) else
(wbs_cc_i.we_i = '0' or wbs_cc_i.dat_i(1 downto 0) = "00")) else
'0';

View File

@@ -1,68 +0,0 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 11/06/2012 03:04:35 PM
-- Design Name:
-- Module Name: wb_rom - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description: Wishbone interface for a block ROM
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
use work.intercon_package.all;
entity wb_rom is
port (
clk_i : in std_logic;
wbs_i : in rom_wbs_i_type;
wbs_o : out rom_wbs_o_type
);
end wb_rom;
architecture Behavioral of wb_rom is
attribute ram_style : string;
constant length : integer := 2**(wbs_i.adr_i'high - wbs_i.adr_i'low+1);
type rom_a is array(length-1 downto 0) of std_logic_vector(31 downto 0);
signal rom : rom_a := (others => (others => '0')); -- to be initialized with data2mem
attribute ram_style of rom : signal is "block";
begin
readport : process(clk_i)
begin
if rising_edge(clk_i) then
wbs_o.dat_o <= rom(to_integer(unsigned(wbs_i.adr_i)));
end if;
end process readport;
ack : process(clk_i)
begin
if rising_edge(clk_i) then
wbs_o.ack_o <= wbs_i.stb_i and wbs_i.cyc_i;
end if;
end process ack;
end Behavioral;

View File

@@ -33,8 +33,10 @@ master dummy
rty_i=0
priority_sdram_ctrl=1
priority_sdram_ctrl_cc=1
priority_rom=1
priority_mblite_rom=1
priority_ram=1
priority_pio_led=1
priority_uart=1
end master dummy
# system controller
@@ -48,14 +50,16 @@ master cpu
rty_i=0
priority_sdram_ctrl=2
priority_sdram_ctrl_cc=2
priority_rom=2
priority_mblite_rom=2
priority_ram=2
priority_pio_led=2
priority_uart=2
end master cpu
# BOOT rom
slave rom
# Wishbone (secondary) read port on CPU instr. memory
slave mblite_rom
type=ro
adr_i_hi=10
adr_i_hi=11
adr_i_lo=2
tga_i=0
tgc_i=0
@@ -63,9 +67,9 @@ slave rom
lock_i=0
err_o=0
rty_o=0
baseadr=0x0000000
size=0x800
end slave rom
baseaddr=0x0000000
size=0x1000
end slave mblite_rom
# Internal RAM
slave ram
@@ -78,23 +82,53 @@ slave ram
lock_i=0
err_o=0
rty_o=0
baseadr=0x0000800
baseadr=0x0001000
size=0x800
end slave ram
# PIO for LEDs
slave pio_led
type=rw
adr_i_hi=1
adr_i_lo=1
tga_i=0
tgc_i=0
tgd_i=0
lock_i=0
err_o=0
rty_o=0
baseadr=0x0004000
size=0x4
end slave pio_led
# UART
slave uart
type=rw
adr_i_hi=2
adr_i_lo=2
tga_i=0
tgc_i=0
tgd_i=0
lock_i=0
err_o=0
rty_o=0
baseadr=0x0004020
size=0x8
end slave uart
# SDRAM controller Cache control port
slave sdram_ctrl_cc
type=rw
adr_i_hi=2
adr_i_lo=2
adr_i_hi=1
adr_i_lo=1
tga_i=1
tgc_i=1
tgd_i=0
lock_i=0
err_o=0
rty_o=0
baseadr=0x8000000
size=0x8
baseadr=0x0004010
size=0x4
end slave sdram_ctrl_cc
# SDRAM controller memory port

View File

@@ -6,7 +6,7 @@
-- Author : <Matthias@MATTHIAS-PC>
-- Company :
-- Created : 2013-03-02
-- Last update: 2013-03-21
-- Last update: 2013-06-03
-- Platform :
-- Standard : VHDL'87
-------------------------------------------------------------------------------
@@ -61,7 +61,10 @@ architecture testbench of toplevel_tb is
ddr2_dqs : inout std_logic_vector(1 downto 0);
ddr2_dqs_n : inout std_logic_vector(1 downto 0);
ddr2_ck : out std_logic_vector(0 downto 0);
ddr2_ck_n : out std_logic_vector(0 downto 0));
ddr2_ck_n : out std_logic_vector(0 downto 0);
rs232_txd : out std_logic;
rs232_rxd : in std_logic
);
end component;
component ddr2_model
@@ -112,6 +115,8 @@ architecture testbench of toplevel_tb is
signal ddr2_ck : std_logic_vector(0 downto 0);
signal ddr2_ck_n : std_logic_vector(0 downto 0);
signal rs232_txd, rs232_rxd : std_logic := '1';
signal sim_done : boolean := false;
begin -- testbench
@@ -152,7 +157,9 @@ begin -- testbench
ddr2_dqs => ddr2_dqs,
ddr2_dqs_n => ddr2_dqs_n,
ddr2_ck => ddr2_ck,
ddr2_ck_n => ddr2_ck_n);
ddr2_ck_n => ddr2_ck_n,
rs232_txd => rs232_txd,
rs232_rxd => rs232_rxd);
rst_dqs_div_in <= rst_dqs_div_out after 100 ps;

View File

@@ -5,12 +5,16 @@
<db_ref_list>
<db_ref path="./isim.wdb" id="1" type="auto">
<top_modules>
<top_module name="config_pkg" />
<top_module name="core_pkg" />
<top_module name="intercon_package" />
<top_module name="mblite_rom_data_pkg_mblite_rom" />
<top_module name="numeric_std" />
<top_module name="sim_bmppack" />
<top_module name="std_logic_1164" />
<top_module name="std_logic_arith" />
<top_module name="std_logic_unsigned" />
<top_module name="std_pkg" />
<top_module name="textio" />
<top_module name="toplevel_tb" />
<top_module name="vcomponents" />
@@ -22,7 +26,7 @@
</top_modules>
</db_ref>
</db_ref_list>
<WVObjectSize size="47" />
<WVObjectSize size="58" />
<wvobject fp_name="/toplevel_tb/DUT/clkin_50mhz" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">clkin_50mhz</obj_property>
<obj_property name="ObjectShortName">clkin_50mhz</obj_property>
@@ -58,6 +62,10 @@
<obj_property name="ElementShortName">vga_hsync</obj_property>
<obj_property name="ObjectShortName">vga_hsync</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/led" type="array" db_ref_id="1">
<obj_property name="ElementShortName">led[7:0]</obj_property>
<obj_property name="ObjectShortName">led[7:0]</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/dataflash_mosi" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">dataflash_mosi</obj_property>
<obj_property name="ObjectShortName">dataflash_mosi</obj_property>
@@ -147,6 +155,14 @@
<obj_property name="ElementShortName">ddr2_ck_n[0:0]</obj_property>
<obj_property name="ObjectShortName">ddr2_ck_n[0:0]</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/rs232_txd" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">rs232_txd</obj_property>
<obj_property name="ObjectShortName">rs232_txd</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/rs232_rxd" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">rs232_rxd</obj_property>
<obj_property name="ObjectShortName">rs232_rxd</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/sysclk" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">sysclk</obj_property>
<obj_property name="ObjectShortName">sysclk</obj_property>
@@ -188,6 +204,7 @@
<wvobject fp_name="/toplevel_tb/DUT/cpu_wbm_o.sel_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.sel_o</obj_property>
<obj_property name="ObjectShortName">cpu_wbm_o.sel_o</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_wbm_o.adr_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.adr_o</obj_property>
@@ -203,6 +220,19 @@
<obj_property name="ObjectShortName">cpu_wbm_o.stb_o</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_wbm_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">cpu_wbm_i</obj_property>
<obj_property name="ObjectShortName">cpu_wbm_i</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/cpu_wbm_i.dat_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.dat_i</obj_property>
<obj_property name="ObjectShortName">cpu_wbm_i.dat_i</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_wbm_i.ack_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.ack_i</obj_property>
<obj_property name="ObjectShortName">cpu_wbm_i.ack_i</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/sdram_ctrl_wbs_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">sdram_ctrl_wbs_i</obj_property>
<obj_property name="ObjectShortName">sdram_ctrl_wbs_i</obj_property>
@@ -246,6 +276,125 @@
<obj_property name="ObjectShortName">sdram_ctrl_wbs_o.ack_o</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/rom_wbs_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">rom_wbs_o</obj_property>
<obj_property name="ObjectShortName">rom_wbs_o</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/rom_wbs_o.dat_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.dat_o</obj_property>
<obj_property name="ObjectShortName">rom_wbs_o.dat_o</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/rom_wbs_o.ack_o" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.ack_o</obj_property>
<obj_property name="ObjectShortName">rom_wbs_o.ack_o</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/rom_wbs_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">rom_wbs_i</obj_property>
<obj_property name="ObjectShortName">rom_wbs_i</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/rom_wbs_i.sel_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.sel_i</obj_property>
<obj_property name="ObjectShortName">rom_wbs_i.sel_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/rom_wbs_i.adr_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.adr_i</obj_property>
<obj_property name="ObjectShortName">rom_wbs_i.adr_i</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/rom_wbs_i.cyc_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.cyc_i</obj_property>
<obj_property name="ObjectShortName">rom_wbs_i.cyc_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/rom_wbs_i.stb_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.stb_i</obj_property>
<obj_property name="ObjectShortName">rom_wbs_i.stb_i</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/ram_wbs_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">ram_wbs_o</obj_property>
<obj_property name="ObjectShortName">ram_wbs_o</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/ram_wbs_o.dat_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.dat_o</obj_property>
<obj_property name="ObjectShortName">ram_wbs_o.dat_o</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/ram_wbs_o.ack_o" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.ack_o</obj_property>
<obj_property name="ObjectShortName">ram_wbs_o.ack_o</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/ram_wbs_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">ram_wbs_i</obj_property>
<obj_property name="ObjectShortName">ram_wbs_i</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/ram_wbs_i.dat_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.dat_i</obj_property>
<obj_property name="ObjectShortName">ram_wbs_i.dat_i</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/ram_wbs_i.we_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.we_i</obj_property>
<obj_property name="ObjectShortName">ram_wbs_i.we_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/ram_wbs_i.sel_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.sel_i</obj_property>
<obj_property name="ObjectShortName">ram_wbs_i.sel_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/ram_wbs_i.adr_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.adr_i</obj_property>
<obj_property name="ObjectShortName">ram_wbs_i.adr_i</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/ram_wbs_i.cyc_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.cyc_i</obj_property>
<obj_property name="ObjectShortName">ram_wbs_i.cyc_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/ram_wbs_i.stb_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.stb_i</obj_property>
<obj_property name="ObjectShortName">ram_wbs_i.stb_i</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/uart_wbs_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">uart_wbs_i</obj_property>
<obj_property name="ObjectShortName">uart_wbs_i</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/uart_wbs_i.dat_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.dat_i</obj_property>
<obj_property name="ObjectShortName">uart_wbs_i.dat_i</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/uart_wbs_i.we_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.we_i</obj_property>
<obj_property name="ObjectShortName">uart_wbs_i.we_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/uart_wbs_i.sel_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.sel_i</obj_property>
<obj_property name="ObjectShortName">uart_wbs_i.sel_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/uart_wbs_i.adr_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.adr_i</obj_property>
<obj_property name="ObjectShortName">uart_wbs_i.adr_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/uart_wbs_i.cyc_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.cyc_i</obj_property>
<obj_property name="ObjectShortName">uart_wbs_i.cyc_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/uart_wbs_i.stb_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.stb_i</obj_property>
<obj_property name="ObjectShortName">uart_wbs_i.stb_i</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/uart_wbs_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">uart_wbs_o</obj_property>
<obj_property name="ObjectShortName">uart_wbs_o</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/uart_wbs_o.dat_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.dat_o</obj_property>
<obj_property name="ObjectShortName">uart_wbs_o.dat_o</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/uart_wbs_o.ack_o" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.ack_o</obj_property>
<obj_property name="ObjectShortName">uart_wbs_o.ack_o</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/fb_flip" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">fb_flip</obj_property>
<obj_property name="ObjectShortName">fb_flip</obj_property>
@@ -258,75 +407,93 @@
<obj_property name="ElementShortName">fb_in_use</obj_property>
<obj_property name="ObjectShortName">fb_in_use</obj_property>
</wvobject>
<wvobject fp_name="group68" type="group">
<obj_property name="label">cpu_1</obj_property>
<wvobject fp_name="group296" type="group">
<obj_property name="label">cpu</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/clk_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">clk_i</obj_property>
<obj_property name="ObjectShortName">clk_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/rst_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">rst_i</obj_property>
<obj_property name="ObjectShortName">rst_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/wbm_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">wbm_i</obj_property>
<obj_property name="ObjectShortName">wbm_i</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/wbm_i.dat_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.dat_i</obj_property>
<obj_property name="ObjectShortName">wbm_i.dat_i</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
<wvobject fp_name="group68" type="group">
<obj_property name="label">cpu_wrapper</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_imem_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">mb_imem_o</obj_property>
<obj_property name="ObjectShortName">mb_imem_o</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_imem_o.adr_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.adr_o</obj_property>
<obj_property name="ObjectShortName">mb_imem_o.adr_o</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_imem_o.ena_o" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.ena_o</obj_property>
<obj_property name="ObjectShortName">mb_imem_o.ena_o</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/wbm_i.ack_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.ack_i</obj_property>
<obj_property name="ObjectShortName">wbm_i.ack_i</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_imem_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">mb_imem_i</obj_property>
<obj_property name="ObjectShortName">mb_imem_i</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_imem_i.dat_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.dat_i</obj_property>
<obj_property name="ObjectShortName">mb_imem_i.dat_i</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">mb_wb_o</obj_property>
<obj_property name="ObjectShortName">mb_wb_o</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_o.adr_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.adr_o</obj_property>
<obj_property name="ObjectShortName">mb_wb_o.adr_o</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_o.dat_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.dat_o</obj_property>
<obj_property name="ObjectShortName">mb_wb_o.dat_o</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_o.we_o" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.we_o</obj_property>
<obj_property name="ObjectShortName">mb_wb_o.we_o</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_o.stb_o" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.stb_o</obj_property>
<obj_property name="ObjectShortName">mb_wb_o.stb_o</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_o.sel_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.sel_o</obj_property>
<obj_property name="ObjectShortName">mb_wb_o.sel_o</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_o.cyc_o" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.cyc_o</obj_property>
<obj_property name="ObjectShortName">mb_wb_o.cyc_o</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">mb_wb_i</obj_property>
<obj_property name="ObjectShortName">mb_wb_i</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_i.clk_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.clk_i</obj_property>
<obj_property name="ObjectShortName">mb_wb_i.clk_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_i.rst_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.rst_i</obj_property>
<obj_property name="ObjectShortName">mb_wb_i.rst_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_i.dat_i" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.dat_i</obj_property>
<obj_property name="ObjectShortName">mb_wb_i.dat_i</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_i.ack_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.ack_i</obj_property>
<obj_property name="ObjectShortName">mb_wb_i.ack_i</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_inst/mb_wb_i.int_i" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.int_i</obj_property>
<obj_property name="ObjectShortName">mb_wb_i.int_i</obj_property>
</wvobject>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/wbm_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">wbm_o</obj_property>
<obj_property name="ObjectShortName">wbm_o</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/wbm_o.dat_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.dat_o</obj_property>
<obj_property name="ObjectShortName">wbm_o.dat_o</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/wbm_o.we_o" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.we_o</obj_property>
<obj_property name="ObjectShortName">wbm_o.we_o</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/wbm_o.sel_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.sel_o</obj_property>
<obj_property name="ObjectShortName">wbm_o.sel_o</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/wbm_o.adr_o" type="array" db_ref_id="1">
<obj_property name="ElementShortName">.adr_o</obj_property>
<obj_property name="ObjectShortName">wbm_o.adr_o</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/wbm_o.cyc_o" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.cyc_o</obj_property>
<obj_property name="ObjectShortName">wbm_o.cyc_o</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/wbm_o.stb_o" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">.stb_o</obj_property>
<obj_property name="ObjectShortName">wbm_o.stb_o</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/state" type="other" db_ref_id="1">
<obj_property name="ElementShortName">state</obj_property>
<obj_property name="ObjectShortName">state</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/x" type="other" db_ref_id="1">
<obj_property name="ElementShortName">x</obj_property>
<obj_property name="ObjectShortName">x</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/y" type="other" db_ref_id="1">
<obj_property name="ElementShortName">y</obj_property>
<obj_property name="ObjectShortName">y</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/cpu_system_inst/adr" type="other" db_ref_id="1">
<obj_property name="ElementShortName">adr</obj_property>
<obj_property name="ObjectShortName">adr</obj_property>
<wvobject fp_name="group332" type="group">
<obj_property name="label">cpu</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="group86" type="group">
@@ -1221,4 +1388,20 @@
<obj_property name="ObjectShortName">fifo_from_sys_valid</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="group302" type="group">
<obj_property name="label">pio_led</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/toplevel_tb/DUT/pio_led/pio_out" type="array" db_ref_id="1">
<obj_property name="ElementShortName">pio_out[7:0]</obj_property>
<obj_property name="ObjectShortName">pio_out[7:0]</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/pio_led/pio_reg" type="array" db_ref_id="1">
<obj_property name="ElementShortName">pio_reg[31:0]</obj_property>
<obj_property name="ObjectShortName">pio_reg[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/toplevel_tb/DUT/pio_led/pio_sr" type="array" db_ref_id="1">
<obj_property name="ElementShortName">pio_sr[0:2]</obj_property>
<obj_property name="ObjectShortName">pio_sr[0:2]</obj_property>
</wvobject>
</wvobject>
</wave_config>

View File

@@ -1,21 +0,0 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
package zpu_config is
-- generate trace output or not.
constant Generate_Trace : boolean := false;
constant wordPower : integer := 5;
-- during simulation, set this to '0' to get matching trace.txt
constant DontCareValue : std_logic := '-';
-- Clock frequency in MHz.
constant ZPU_Frequency : std_logic_vector(7 downto 0) := x"32"; -- 50 MHz
-- This is the msb address bit. bytes=2^(maxAddrBitIncIO+1)
constant maxAddrBitIncIO : integer := 27;
-- start byte address of stack.
-- point to top of RAM - 2*words
constant spStart : std_logic_vector(maxAddrBitIncIO downto 0) := x"3fffff8";
end zpu_config;

View File

@@ -1,948 +0,0 @@
-- Company: ZPU4 generic memory interface CPU
-- Engineer: <20>yvind Harboe
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.STD_LOGIC_arith.ALL;
library work;
use work.zpu_config.all;
use work.zpupkg.all;
entity zpu_core is
Port ( clk : in std_logic;
areset : in std_logic;
enable : in std_logic;
mem_req : out std_logic;
mem_we : out std_logic;
mem_ack : in std_logic;
mem_read : in std_logic_vector(wordSize-1 downto 0);
mem_write : out std_logic_vector(wordSize-1 downto 0);
out_mem_addr : out std_logic_vector(maxAddrBitIncIO downto 0);
mem_writeMask: out std_logic_vector(wordBytes-1 downto 0);
interrupt : in std_logic;
break : out std_logic;
zpu_status : out std_logic_vector(63 downto 0));
end zpu_core;
architecture behave of zpu_core is
type InsnType is
(
State_AddTop,
State_Dup,
State_DupStackB,
State_Pop,
State_Popdown,
State_Add,
State_Or,
State_And,
State_Store,
State_AddSP,
State_Shift,
State_Nop,
State_Im,
State_LoadSP,
State_StoreSP,
State_Emulate,
State_Load,
State_PushPC,
State_PushSP,
State_PopPC,
State_PopPCRel,
State_Not,
State_Flip,
State_PopSP,
State_Neqbranch,
State_Eq,
State_Loadb,
State_Mult,
State_Lessthan,
State_Lessthanorequal,
State_Ulessthanorequal,
State_Ulessthan,
State_Pushspadd,
State_Call,
State_Callpcrel,
State_Sub,
State_Break,
State_Storeb,
State_Interrupt,
State_InsnFetch
);
type StateType is
(
State_Idle, -- using first state first on the list out of paranoia
State_Load2,
State_Popped,
State_LoadSP2,
State_LoadSP3,
State_AddSP2,
State_Fetch,
State_Execute,
State_Decode,
State_Decode2,
State_Resync,
State_StoreSP2,
State_Resync2,
State_Resync3,
State_Loadb2,
State_Storeb2,
State_Mult2,
State_Mult3,
State_Mult5,
State_Mult6,
State_Mult4,
State_BinaryOpResult
);
signal pc : std_logic_vector(maxAddrBitIncIO downto 0);
signal sp : std_logic_vector(maxAddrBitIncIO downto minAddrBit);
signal incSp : std_logic_vector(maxAddrBitIncIO downto minAddrBit);
signal incIncSp : std_logic_vector(maxAddrBitIncIO downto minAddrBit);
signal decSp : std_logic_vector(maxAddrBitIncIO downto minAddrBit);
signal stackA : std_logic_vector(wordSize-1 downto 0);
signal binaryOpResult : std_logic_vector(wordSize-1 downto 0);
signal multResult2 : std_logic_vector(wordSize-1 downto 0);
signal multResult3 : std_logic_vector(wordSize-1 downto 0);
signal multResult : std_logic_vector(wordSize-1 downto 0);
signal multA : std_logic_vector(wordSize-1 downto 0);
signal multB : std_logic_vector(wordSize-1 downto 0);
signal stackB : std_logic_vector(wordSize-1 downto 0);
signal idim_flag : std_logic;
signal busy : std_logic;
signal mem_readEnable : std_logic;
signal mem_addr : std_logic_vector(maxAddrBitIncIO downto minAddrBit);
signal mem_delayAddr : std_logic_vector(maxAddrBitIncIO downto minAddrBit);
signal mem_delayReadEnable : std_logic;
signal mem_busy : std_logic;
signal decodeWord : std_logic_vector(wordSize-1 downto 0);
signal state : StateType;
signal insn : InsnType;
type InsnArray is array(0 to wordBytes-1) of InsnType;
signal decodedOpcode : InsnArray;
type OpcodeArray is array(0 to wordBytes-1) of std_logic_vector(7 downto 0);
signal opcode : OpcodeArray;
signal begin_inst : std_logic;
signal trace_opcode : std_logic_vector(7 downto 0);
signal trace_pc : std_logic_vector(maxAddrBitIncIO downto 0);
signal trace_sp : std_logic_vector(maxAddrBitIncIO downto minAddrBit);
signal trace_topOfStack : std_logic_vector(wordSize-1 downto 0);
signal trace_topOfStackB : std_logic_vector(wordSize-1 downto 0);
signal out_mem_req : std_logic;
signal inInterrupt : std_logic;
-- state machine.
begin
zpu_status(maxAddrBitIncIO downto 0) <= trace_pc;
zpu_status(31) <= '1';
zpu_status(39 downto 32) <= trace_opcode;
zpu_status(40) <= '1' when (state = State_Idle) else '0';
zpu_status(62) <= '1';
traceFileGenerate:
if Generate_Trace generate
trace_file: trace port map (
clk => clk,
begin_inst => begin_inst,
pc => trace_pc,
opcode => trace_opcode,
sp => trace_sp,
memA => trace_topOfStack,
memB => trace_topOfStackB,
busy => busy,
intsp => (others => 'U')
);
end generate;
-- the memory subsystem will tell us one cycle later whether or
-- not it is busy
out_mem_addr(maxAddrBitIncIO downto minAddrBit) <= mem_addr;
out_mem_addr(minAddrBit-1 downto 0) <= (others => '0');
mem_req <= out_mem_req;
incSp <= sp + 1;
incIncSp <= sp + 2;
decSp <= sp - 1;
mem_busy <= out_mem_req and not mem_ack; -- '1' when the memory is busy
opcodeControl:
process(clk, areset)
variable tOpcode : std_logic_vector(OpCode_Size-1 downto 0);
variable spOffset : std_logic_vector(4 downto 0);
variable tSpOffset : std_logic_vector(4 downto 0);
variable nextPC : std_logic_vector(maxAddrBitIncIO downto 0);
variable tNextState : InsnType;
variable tDecodedOpcode : InsnArray;
variable tMultResult : std_logic_vector(wordSize*2-1 downto 0);
begin
if areset = '1' then
state <= State_Idle;
break <= '0';
sp <= spStart(maxAddrBitIncIO downto minAddrBit);
pc <= (others => '0');
idim_flag <= '0';
begin_inst <= '0';
mem_we <= '0';
multA <= (others => '0');
multB <= (others => '0');
mem_writeMask <= (others => '1');
out_mem_req <= '0';
mem_addr <= (others => DontCareValue);
mem_write <= (others => DontCareValue);
inInterrupt <= '0';
elsif (clk'event and clk = '1') then
-- we must multiply unconditionally to get pipelined multiplication
tMultResult := multA * multB;
multResult3 <= multResult2;
multResult2 <= multResult;
multResult <= tMultResult(wordSize-1 downto 0);
spOffset(4):=not opcode(conv_integer(pc(byteBits-1 downto 0)))(4);
spOffset(3 downto 0):=opcode(conv_integer(pc(byteBits-1 downto 0)))(3 downto 0);
nextPC := pc + 1;
-- prepare trace snapshot
trace_opcode <= opcode(conv_integer(pc(byteBits-1 downto 0)));
trace_pc <= pc;
trace_sp <= sp;
trace_topOfStack <= stackA;
trace_topOfStackB <= stackB;
begin_inst <= '0';
-- we terminate the requeset as soon as we get acknowledge
if mem_ack = '1' then
out_mem_req <= '0';
mem_we <= '0';
end if;
if interrupt='0' then
inInterrupt <= '0'; -- no longer in an interrupt
end if;
case state is
when State_Idle =>
if enable='1' then
state <= State_Resync;
end if;
-- Initial state of ZPU, fetch top of stack + first instruction
when State_Resync =>
if mem_busy='0' then
mem_addr <= sp;
out_mem_req <= '1';
state <= State_Resync2;
end if;
when State_Resync2 =>
if mem_busy='0' then
stackA <= mem_read;
mem_addr <= incSp;
out_mem_req <= '1';
state <= State_Resync3;
end if;
when State_Resync3 =>
if mem_busy='0' then
stackB <= mem_read;
mem_addr <= pc(maxAddrBitIncIO downto minAddrBit);
out_mem_req <= '1';
state <= State_Decode;
end if;
when State_Decode =>
if mem_busy='0' then
decodeWord <= mem_read;
state <= State_Decode2;
end if;
when State_Decode2 =>
-- decode 4 instructions in parallel
for i in 0 to wordBytes-1 loop
tOpcode := decodeWord((wordBytes-1-i+1)*8-1 downto (wordBytes-1-i)*8);
tSpOffset(4):=not tOpcode(4);
tSpOffset(3 downto 0):=tOpcode(3 downto 0);
opcode(i) <= tOpcode;
if (tOpcode(7 downto 7)=OpCode_Im) then
tNextState:=State_Im;
elsif (tOpcode(7 downto 5)=OpCode_StoreSP) then
if tSpOffset = 0 then
tNextState := State_Pop;
elsif tSpOffset=1 then
tNextState := State_PopDown;
else
tNextState :=State_StoreSP;
end if;
elsif (tOpcode(7 downto 5)=OpCode_LoadSP) then
if tSpOffset = 0 then
tNextState :=State_Dup;
elsif tSpOffset = 1 then
tNextState :=State_DupStackB;
else
tNextState :=State_LoadSP;
end if;
elsif (tOpcode(7 downto 5)=OpCode_Emulate) then
tNextState :=State_Emulate;
if tOpcode(5 downto 0)=OpCode_Neqbranch then
tNextState :=State_Neqbranch;
elsif tOpcode(5 downto 0)=OpCode_Eq then
tNextState :=State_Eq;
elsif tOpcode(5 downto 0)=OpCode_Lessthan then
tNextState :=State_Lessthan;
elsif tOpcode(5 downto 0)=OpCode_Lessthanorequal then
--tNextState :=State_Lessthanorequal;
elsif tOpcode(5 downto 0)=OpCode_Ulessthan then
tNextState :=State_Ulessthan;
elsif tOpcode(5 downto 0)=OpCode_Ulessthanorequal then
--tNextState :=State_Ulessthanorequal;
elsif tOpcode(5 downto 0)=OpCode_Loadb then
tNextState :=State_Loadb;
elsif tOpcode(5 downto 0)=OpCode_Mult then
tNextState :=State_Mult;
elsif tOpcode(5 downto 0)=OpCode_Storeb then
tNextState :=State_Storeb;
elsif tOpcode(5 downto 0)=OpCode_Pushspadd then
tNextState :=State_Pushspadd;
elsif tOpcode(5 downto 0)=OpCode_Callpcrel then
tNextState :=State_Callpcrel;
elsif tOpcode(5 downto 0)=OpCode_Call then
--tNextState :=State_Call;
elsif tOpcode(5 downto 0)=OpCode_Sub then
tNextState :=State_Sub;
elsif tOpcode(5 downto 0)=OpCode_PopPCRel then
--tNextState :=State_PopPCRel;
end if;
elsif (tOpcode(7 downto 4)=OpCode_AddSP) then
if tSpOffset = 0 then
tNextState := State_Shift;
elsif tSpOffset = 1 then
tNextState := State_AddTop;
else
tNextState :=State_AddSP;
end if;
else
case tOpcode(3 downto 0) is
when OpCode_Nop =>
tNextState :=State_Nop;
when OpCode_PushSP =>
tNextState :=State_PushSP;
when OpCode_PopPC =>
tNextState :=State_PopPC;
when OpCode_Add =>
tNextState :=State_Add;
when OpCode_Or =>
tNextState :=State_Or;
when OpCode_And =>
tNextState :=State_And;
when OpCode_Load =>
tNextState :=State_Load;
when OpCode_Not =>
tNextState :=State_Not;
when OpCode_Flip =>
tNextState :=State_Flip;
when OpCode_Store =>
tNextState :=State_Store;
when OpCode_PopSP =>
tNextState :=State_PopSP;
when others =>
tNextState := State_Break;
end case;
end if;
tDecodedOpcode(i) := tNextState;
end loop;
insn <= tDecodedOpcode(conv_integer(pc(byteBits-1 downto 0)));
-- once we wrap, we need to fetch
tDecodedOpcode(0) := State_InsnFetch;
decodedOpcode <= tDecodedOpcode;
state <= State_Execute;
-- Each instruction must:
--
-- 1. set idim_flag
-- 2. increase pc if applicable
-- 3. set next state if appliable
-- 4. do it's operation
when State_Execute =>
insn <= decodedOpcode(conv_integer(nextPC(byteBits-1 downto 0)));
case insn is
when State_InsnFetch =>
state <= State_Fetch;
when State_Im =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '1';
pc <= pc + 1;
if idim_flag='1' then
stackA(wordSize-1 downto 7) <= stackA(wordSize-8 downto 0);
stackA(6 downto 0) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(6 downto 0);
else
out_mem_req <= '1';
mem_we <= '1';
mem_addr <= incSp;
mem_write <= stackB;
stackB <= stackA;
sp <= decSp;
for i in wordSize-1 downto 7 loop
stackA(i) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(6);
end loop;
stackA(6 downto 0) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(6 downto 0);
end if;
else
insn <= insn;
end if;
when State_StoreSP =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
state <= State_StoreSP2;
out_mem_req <= '1';
mem_we <= '1';
mem_addr <= sp+spOffset;
mem_write <= stackA;
stackA <= stackB;
sp <= incSp;
else
insn <= insn;
end if;
when State_LoadSP =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
state <= State_LoadSP2;
sp <= decSp;
out_mem_req <= '1';
mem_we <= '1';
mem_addr <= incSp;
mem_write <= stackB;
else
insn <= insn;
end if;
when State_Emulate =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
sp <= decSp;
out_mem_req <= '1';
mem_we <= '1';
mem_addr <= incSp;
mem_write <= stackB;
stackA <= (others => DontCareValue);
stackA(maxAddrBitIncIO downto 0) <= pc + 1;
stackB <= stackA;
-- The emulate address is:
-- 98 7654 3210
-- 0000 00aa aaa0 0000
pc <= (others => '0');
pc(9 downto 5) <= opcode(conv_integer(pc(byteBits-1 downto 0)))(4 downto 0);
state <= State_Fetch;
else
insn <= insn;
end if;
when State_Callpcrel =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
stackA <= (others => DontCareValue);
stackA(maxAddrBitIncIO downto 0) <= pc + 1;
pc <= pc + stackA(maxAddrBitIncIO downto 0);
state <= State_Fetch;
else
insn <= insn;
end if;
when State_Call =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
stackA <= (others => DontCareValue);
stackA(maxAddrBitIncIO downto 0) <= pc + 1;
pc <= stackA(maxAddrBitIncIO downto 0);
state <= State_Fetch;
else
insn <= insn;
end if;
when State_AddSP =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
state <= State_AddSP2;
out_mem_req <= '1';
mem_addr <= sp+spOffset;
else
insn <= insn;
end if;
when State_PushSP =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
pc <= pc + 1;
sp <= decSp;
stackA <= (others => '0');
stackA(maxAddrBitIncIO downto minAddrBit) <= sp;
stackB <= stackA;
out_mem_req <= '1';
mem_we <= '1';
mem_addr <= incSp;
mem_write <= stackB;
else
insn <= insn;
end if;
when State_PopPC =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
pc <= stackA(maxAddrBitIncIO downto 0);
sp <= incSp;
out_mem_req <= '1';
mem_we <= '1';
mem_addr <= incSp;
mem_write <= stackB;
state <= State_Resync;
else
insn <= insn;
end if;
when State_PopPCRel =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
pc <= stackA(maxAddrBitIncIO downto 0) + pc;
sp <= incSp;
out_mem_req <= '1';
mem_we <= '1';
mem_addr <= incSp;
mem_write <= stackB;
state <= State_Resync;
else
insn <= insn;
end if;
when State_Add =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
stackA <= stackA + stackB;
out_mem_req <= '1';
mem_addr <= incIncSp;
sp <= incSp;
state <= State_Popped;
else
insn <= insn;
end if;
when State_Sub =>
begin_inst <= '1';
idim_flag <= '0';
binaryOpResult <= stackB - stackA;
state <= State_BinaryOpResult;
when State_Pop =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
mem_addr <= incIncSp;
out_mem_req <= '1';
sp <= incSp;
stackA <= stackB;
state <= State_Popped;
else
insn <= insn;
end if;
when State_PopDown =>
if mem_busy='0' then
-- PopDown leaves top of stack unchanged
begin_inst <= '1';
idim_flag <= '0';
mem_addr <= incIncSp;
out_mem_req <= '1';
sp <= incSp;
state <= State_Popped;
else
insn <= insn;
end if;
when State_Or =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
stackA <= stackA or stackB;
out_mem_req <= '1';
mem_addr <= incIncSp;
sp <= incSp;
state <= State_Popped;
else
insn <= insn;
end if;
when State_And =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
stackA <= stackA and stackB;
out_mem_req <= '1';
mem_addr <= incIncSp;
sp <= incSp;
state <= State_Popped;
else
insn <= insn;
end if;
when State_Eq =>
begin_inst <= '1';
idim_flag <= '0';
binaryOpResult <= (others => '0');
if (stackA=stackB) then
binaryOpResult(0) <= '1';
end if;
state <= State_BinaryOpResult;
when State_Ulessthan =>
begin_inst <= '1';
idim_flag <= '0';
binaryOpResult <= (others => '0');
if (stackA<stackB) then
binaryOpResult(0) <= '1';
end if;
state <= State_BinaryOpResult;
when State_Ulessthanorequal =>
begin_inst <= '1';
idim_flag <= '0';
binaryOpResult <= (others => '0');
if (stackA<=stackB) then
binaryOpResult(0) <= '1';
end if;
state <= State_BinaryOpResult;
when State_Lessthan =>
begin_inst <= '1';
idim_flag <= '0';
binaryOpResult <= (others => '0');
if (signed(stackA)<signed(stackB)) then
binaryOpResult(0) <= '1';
end if;
state <= State_BinaryOpResult;
when State_Lessthanorequal =>
begin_inst <= '1';
idim_flag <= '0';
binaryOpResult <= (others => '0');
if (signed(stackA)<=signed(stackB)) then
binaryOpResult(0) <= '1';
end if;
state <= State_BinaryOpResult;
when State_Load =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
state <= State_Load2;
mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit);
out_mem_req <= '1';
else
insn <= insn;
end if;
when State_Dup =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
pc <= pc + 1;
sp <= decSp;
stackB <= stackA;
mem_write <= stackB;
mem_addr <= incSp;
out_mem_req <= '1';
mem_we <= '1';
else
insn <= insn;
end if;
when State_DupStackB =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
pc <= pc + 1;
sp <= decSp;
stackA <= stackB;
stackB <= stackA;
mem_write <= stackB;
mem_addr <= incSp;
out_mem_req <= '1';
mem_we <= '1';
else
insn <= insn;
end if;
when State_Store =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
pc <= pc + 1;
mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit);
mem_write <= stackB;
out_mem_req <= '1';
mem_we <= '1';
sp <= incIncSp;
state <= State_Resync;
else
insn <= insn;
end if;
when State_PopSP =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
pc <= pc + 1;
mem_write <= stackB;
mem_addr <= incSp;
out_mem_req <= '1';
mem_we <= '1';
sp <= stackA(maxAddrBitIncIO downto minAddrBit);
state <= State_Resync;
else
insn <= insn;
end if;
when State_Nop =>
begin_inst <= '1';
idim_flag <= '0';
pc <= pc + 1;
when State_Not =>
begin_inst <= '1';
idim_flag <= '0';
pc <= pc + 1;
stackA <= not stackA;
when State_Flip =>
begin_inst <= '1';
idim_flag <= '0';
pc <= pc + 1;
for i in 0 to wordSize-1 loop
stackA(i) <= stackA(wordSize-1-i);
end loop;
when State_AddTop =>
begin_inst <= '1';
idim_flag <= '0';
pc <= pc + 1;
stackA <= stackA + stackB;
when State_Shift =>
begin_inst <= '1';
idim_flag <= '0';
pc <= pc + 1;
stackA(wordSize-1 downto 1) <= stackA(wordSize-2 downto 0);
stackA(0) <= '0';
when State_Pushspadd =>
begin_inst <= '1';
idim_flag <= '0';
pc <= pc + 1;
stackA <= (others => '0');
stackA(maxAddrBitIncIO downto minAddrBit) <= stackA(maxAddrBitIncIO-minAddrBit downto 0)+sp;
when State_Neqbranch =>
-- branches are almost always taken as they form loops
begin_inst <= '1';
idim_flag <= '0';
sp <= incIncSp;
if (stackB/=0) then
pc <= stackA(maxAddrBitIncIO downto 0) + pc;
else
pc <= pc + 1;
end if;
-- need to fetch stack again.
state <= State_Resync;
when State_Mult =>
begin_inst <= '1';
idim_flag <= '0';
multA <= stackA;
multB <= stackB;
state <= State_Mult2;
when State_Break =>
report "Break instruction encountered" severity failure;
break <= '1';
when State_Loadb =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
state <= State_Loadb2;
mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit);
out_mem_req <= '1';
else
insn <= insn;
end if;
when State_Storeb =>
if mem_busy='0' then
begin_inst <= '1';
idim_flag <= '0';
state <= State_Storeb2;
mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit);
out_mem_req <= '1';
else
insn <= insn;
end if;
when others =>
-- sp <= (others => DontCareValue);
report "Illegal instruction" severity failure;
break <= '1';
end case;
when State_StoreSP2 =>
if mem_busy='0' then
mem_addr <= incSp;
out_mem_req <= '1';
state <= State_Popped;
end if;
when State_LoadSP2 =>
if mem_busy='0' then
state <= State_LoadSP3;
out_mem_req <= '1';
mem_addr <= sp+spOffset+1;
end if;
when State_LoadSP3 =>
if mem_busy='0' then
pc <= pc + 1;
state <= State_Execute;
stackB <= stackA;
stackA <= mem_read;
end if;
when State_AddSP2 =>
if mem_busy='0' then
pc <= pc + 1;
state <= State_Execute;
stackA <= stackA + mem_read;
end if;
when State_Load2 =>
if mem_busy='0' then
stackA <= mem_read;
pc <= pc + 1;
state <= State_Execute;
end if;
when State_Loadb2 =>
if mem_busy='0' then
stackA <= (others => '0');
stackA(7 downto 0) <= mem_read(((wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8+7) downto (wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8);
pc <= pc + 1;
state <= State_Execute;
end if;
when State_Storeb2 =>
if mem_busy='0' then
mem_addr <= stackA(maxAddrBitIncIO downto minAddrBit);
mem_write <= mem_read;
mem_write(((wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8+7) downto (wordBytes-1-conv_integer(stackA(byteBits-1 downto 0)))*8) <= stackB(7 downto 0) ;
out_mem_req <= '1';
mem_we <= '1';
pc <= pc + 1;
sp <= incIncSp;
state <= State_Resync;
end if;
when State_Fetch =>
if mem_busy='0' then
if interrupt='1' and inInterrupt='0' and idim_flag='0' then
-- We got an interrupt
inInterrupt <= '1';
sp <= decSp;
out_mem_req <= '1';
mem_we <= '1';
mem_addr <= incSp;
mem_write <= stackB;
stackA <= (others => DontCareValue);
stackA(maxAddrBitIncIO downto 0) <= pc;
stackB <= stackA;
pc <= conv_std_logic_vector(32, maxAddrBitIncIo+1); -- interrupt address
report "ZPU jumped to interrupt!" severity note;
else
mem_addr <= pc(maxAddrBitIncIO downto minAddrBit);
out_mem_req <= '1';
state <= State_Decode;
end if;
end if;
when State_Mult2 =>
state <= State_Mult3;
when State_Mult3 =>
state <= State_Mult4;
when State_Mult4 =>
state <= State_Mult5;
when State_Mult5 =>
stackA <= multResult3;
state <= State_Mult6;
when State_Mult6 =>
if mem_busy='0' then
out_mem_req <= '1';
mem_addr <= incIncSp;
sp <= incSp;
state <= State_Popped;
end if;
when State_BinaryOpResult =>
if mem_busy='0' then
-- NB!!!! we know that the memory isn't busy at this point!!!!
out_mem_req <= '1';
mem_addr <= incIncSp;
sp <= incSp;
stackA <= binaryOpResult;
state <= State_Popped;
end if;
when State_Popped =>
if mem_busy='0' then
pc <= pc + 1;
stackB <= mem_read;
state <= State_Execute;
end if;
when others =>
-- sp <= (others => DontCareValue);
report "Illegal state" severity failure;
break <= '1';
end case;
end if;
end process;
end behave;

View File

@@ -1,121 +0,0 @@
-- ZPU
--
-- Copyright 2004-2008 oharboe - <20>yvind Harboe - oyvind.harboe@zylin.com
--
-- The FreeBSD license
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions
-- are met:
--
-- 1. Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above
-- copyright notice, this list of conditions and the following
-- disclaimer in the documentation and/or other materials
-- provided with the distribution.
--
-- THIS SOFTWARE IS PROVIDED BY THE ZPU PROJECT ``AS IS'' AND ANY
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-- ZPU PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-- The views and conclusions contained in the software and documentation
-- are those of the authors and should not be interpreted as representing
-- official policies, either expressed or implied, of the ZPU Project.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
library work;
use work.intercon_package.all;
use work.zpupkg.all;
use work.zpu_config.all;
entity zpu_system is
generic(
simulate : boolean := false);
port (
areset : in std_logic;
cpu_clk : in std_logic;
-- ZPU Control signals
enable : in std_logic;
interrupt : in std_logic;
zpu_status : out std_logic_vector(63 downto 0);
-- wishbone interfaces
zpu_wb_i : in zpu_wbm_i_type;
zpu_wb_o : out zpu_wbm_o_type
);
end zpu_system;
architecture behave of zpu_system is
component zpu_wb_bridge
port (
clk : in std_logic;
areset : in std_logic;
mem_req : in std_logic;
mem_we : in std_logic;
mem_ack : out std_logic;
mem_read : out std_logic_vector(wordSize-1 downto 0);
mem_write : in std_logic_vector(wordSize-1 downto 0);
out_mem_addr : in std_logic_vector(maxAddrBitIncIO downto 0);
mem_writeMask : in std_logic_vector(wordBytes-1 downto 0);
zpu_wb_i : in zpu_wbm_i_type;
zpu_wb_o : out zpu_wbm_o_type);
end component;
signal mem_req : std_logic;
signal mem_we : std_logic;
signal mem_ack : std_logic;
signal mem_read : std_logic_vector(wordSize-1 downto 0);
signal mem_write : std_logic_vector(wordSize-1 downto 0);
signal out_mem_addr : std_logic_vector(maxAddrBitIncIO downto 0);
signal mem_writeMask : std_logic_vector(wordBytes-1 downto 0);
begin
my_zpu_core:
zpu_core port map (
clk => cpu_clk,
areset => areset,
enable => enable,
mem_req => mem_req,
mem_we => mem_we,
mem_ack => mem_ack,
mem_read => mem_read,
mem_write => mem_write,
out_mem_addr => out_mem_addr,
mem_writeMask => mem_writeMask,
interrupt => interrupt,
zpu_status => zpu_status,
break => open);
my_zpu_wb_bridge:
zpu_wb_bridge port map (
clk => cpu_clk,
areset => areset,
mem_req => mem_req,
mem_we => mem_we,
mem_ack => mem_ack,
mem_read => mem_read,
mem_write => mem_write,
out_mem_addr => out_mem_addr,
mem_writeMask => mem_writeMask,
zpu_wb_i => zpu_wb_i,
zpu_wb_o => zpu_wb_o);
end behave;

View File

@@ -1,84 +0,0 @@
-- ZPU
--
-- Copyright 2004-2008 oharboe - <20>yvind Harboe - oyvind.harboe@zylin.com
--
-- The FreeBSD license
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions
-- are met:
--
-- 1. Redistributions of source code must retain the above copyright
-- notice, this list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above
-- copyright notice, this list of conditions and the following
-- disclaimer in the documentation and/or other materials
-- provided with the distribution.
--
-- THIS SOFTWARE IS PROVIDED BY THE ZPU PROJECT ``AS IS'' AND ANY
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-- ZPU PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-- The views and conclusions contained in the software and documentation
-- are those of the authors and should not be interpreted as representing
-- official policies, either expressed or implied, of the ZPU Project.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library work;
use work.intercon_package.all;
use work.zpupkg.all;
use work.zpu_config.all;
entity zpu_wb_bridge is
port (
-- Native ZPU interface
clk : in std_logic;
areset : in std_logic;
mem_req : in std_logic;
mem_we : in std_logic;
mem_ack : out std_logic;
mem_read : out std_logic_vector(wordSize-1 downto 0);
mem_write : in std_logic_vector(wordSize-1 downto 0);
out_mem_addr : in std_logic_vector(maxAddrBitIncIO downto 0);
mem_writeMask : in std_logic_vector(wordBytes-1 downto 0);
-- Wishbone from ZPU
zpu_wb_i : in zpu_wbm_i_type;
zpu_wb_o : out zpu_wbm_o_type
);
end zpu_wb_bridge;
architecture behave of zpu_wb_bridge is
begin
mem_read <= zpu_wb_i.dat_i;
mem_ack <= zpu_wb_i.ack_i;
zpu_wb_o.adr_o <= out_mem_addr;
zpu_wb_o.dat_o <= mem_write;
zpu_wb_o.sel_o <= mem_writeMask;
zpu_wb_o.stb_o <= mem_req;
zpu_wb_o.cyc_o <= mem_req;
zpu_wb_o.we_o <= mem_we;
end behave;

View File

@@ -1,168 +0,0 @@
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
library work;
use work.zpu_config.all;
package zpupkg is
-- This bit is set for read/writes to IO
-- FIX!!! eventually this should be set to wordSize-1 so as to
-- to make the address of IO independent of amount of memory
-- reserved for CPU. Requires trivial tweaks in toolchain/runtime
-- libraries.
constant byteBits : integer := wordPower-3; -- # of bits in a word that addresses bytes
constant maxAddrBit : integer := maxAddrBitIncIO-1;
constant ioBit : integer := maxAddrBit+1;
constant wordSize : integer := 2**wordPower;
constant wordBytes : integer := wordSize/8;
constant minAddrBit : integer := byteBits;
-- configurable internal stack size. Probably going to be 16 after toolchain is done
constant stack_bits : integer := 5;
constant stack_size : integer := 2**stack_bits;
component dualport_ram is
port (clk : in std_logic;
memAWriteEnable : in std_logic;
memAAddr : in std_logic_vector(maxAddrBit downto minAddrBit);
memAWrite : in std_logic_vector(wordSize-1 downto 0);
memARead : out std_logic_vector(wordSize-1 downto 0);
memBWriteEnable : in std_logic;
memBAddr : in std_logic_vector(maxAddrBit downto minAddrBit);
memBWrite : in std_logic_vector(wordSize-1 downto 0);
memBRead : out std_logic_vector(wordSize-1 downto 0));
end component;
component dram is
port (clk : in std_logic;
areset : in std_logic;
mem_writeEnable : in std_logic;
mem_readEnable : in std_logic;
mem_addr : in std_logic_vector(maxAddrBit downto 0);
mem_write : in std_logic_vector(wordSize-1 downto 0);
mem_read : out std_logic_vector(wordSize-1 downto 0);
mem_busy : out std_logic;
mem_writeMask : in std_logic_vector(wordBytes-1 downto 0));
end component;
component trace is
port(
clk : in std_logic;
begin_inst : in std_logic;
pc : in std_logic_vector(maxAddrBitIncIO downto 0);
opcode : in std_logic_vector(7 downto 0);
sp : in std_logic_vector(maxAddrBitIncIO downto minAddrBit);
memA : in std_logic_vector(wordSize-1 downto 0);
memB : in std_logic_vector(wordSize-1 downto 0);
busy : in std_logic;
intSp : in std_logic_vector(stack_bits-1 downto 0)
);
end component;
component zpu_core is
port ( clk : in std_logic;
areset : in std_logic;
enable : in std_logic;
mem_req : out std_logic;
mem_we : out std_logic;
mem_ack : in std_logic;
mem_read : in std_logic_vector(wordSize-1 downto 0);
mem_write : out std_logic_vector(wordSize-1 downto 0);
out_mem_addr : out std_logic_vector(maxAddrBitIncIO downto 0);
mem_writeMask: out std_logic_vector(wordBytes-1 downto 0);
interrupt : in std_logic;
break : out std_logic;
zpu_status : out std_logic_vector(63 downto 0));
end component;
component timer is
port(
clk : in std_logic;
areset : in std_logic;
sample : in std_logic;
reset : in std_logic;
counter : out std_logic_vector(63 downto 0));
end component;
component zpuio is
port ( areset : in std_logic;
cpu_clk : in std_logic;
clk_status : in std_logic_vector(2 downto 0);
cpu_din : in std_logic_vector(15 downto 0);
cpu_a : in std_logic_vector(20 downto 0);
cpu_we : in std_logic_vector(1 downto 0);
cpu_re : in std_logic;
cpu_dout : inout std_logic_vector(15 downto 0));
end component;
-- opcode decode constants
constant OpCode_Im : std_logic_vector(7 downto 7) := "1";
constant OpCode_StoreSP : std_logic_vector(7 downto 5) := "010";
constant OpCode_LoadSP : std_logic_vector(7 downto 5) := "011";
constant OpCode_Emulate : std_logic_vector(7 downto 5) := "001";
constant OpCode_AddSP : std_logic_vector(7 downto 4) := "0001";
constant OpCode_Short : std_logic_vector(7 downto 4) := "0000";
constant OpCode_Break : std_logic_vector(3 downto 0) := "0000";
constant OpCode_Shiftleft: std_logic_vector(3 downto 0) := "0001";
constant OpCode_PushSP : std_logic_vector(3 downto 0) := "0010";
constant OpCode_PushInt : std_logic_vector(3 downto 0) := "0011";
constant OpCode_PopPC : std_logic_vector(3 downto 0) := "0100";
constant OpCode_Add : std_logic_vector(3 downto 0) := "0101";
constant OpCode_And : std_logic_vector(3 downto 0) := "0110";
constant OpCode_Or : std_logic_vector(3 downto 0) := "0111";
constant OpCode_Load : std_logic_vector(3 downto 0) := "1000";
constant OpCode_Not : std_logic_vector(3 downto 0) := "1001";
constant OpCode_Flip : std_logic_vector(3 downto 0) := "1010";
constant OpCode_Nop : std_logic_vector(3 downto 0) := "1011";
constant OpCode_Store : std_logic_vector(3 downto 0) := "1100";
constant OpCode_PopSP : std_logic_vector(3 downto 0) := "1101";
constant OpCode_Compare : std_logic_vector(3 downto 0) := "1110";
constant OpCode_PopInt : std_logic_vector(3 downto 0) := "1111";
constant OpCode_Lessthan : std_logic_vector(5 downto 0) := conv_std_logic_vector(36, 6);
constant OpCode_Lessthanorequal : std_logic_vector(5 downto 0) := conv_std_logic_vector(37, 6);
constant OpCode_Ulessthan : std_logic_vector(5 downto 0) := conv_std_logic_vector(38, 6);
constant OpCode_Ulessthanorequal : std_logic_vector(5 downto 0) := conv_std_logic_vector(39, 6);
constant OpCode_Swap : std_logic_vector(5 downto 0) := conv_std_logic_vector(40, 6);
constant OpCode_Mult : std_logic_vector(5 downto 0) := conv_std_logic_vector(41, 6);
constant OpCode_Lshiftright : std_logic_vector(5 downto 0) := conv_std_logic_vector(42, 6);
constant OpCode_Ashiftleft : std_logic_vector(5 downto 0) := conv_std_logic_vector(43, 6);
constant OpCode_Ashiftright : std_logic_vector(5 downto 0) := conv_std_logic_vector(44, 6);
constant OpCode_Call : std_logic_vector(5 downto 0) := conv_std_logic_vector(45, 6);
constant OpCode_Eq : std_logic_vector(5 downto 0) := conv_std_logic_vector(46, 6);
constant OpCode_Neq : std_logic_vector(5 downto 0) := conv_std_logic_vector(47, 6);
constant OpCode_Sub : std_logic_vector(5 downto 0) := conv_std_logic_vector(49, 6);
constant OpCode_Loadb : std_logic_vector(5 downto 0) := conv_std_logic_vector(51, 6);
constant OpCode_Storeb : std_logic_vector(5 downto 0) := conv_std_logic_vector(52, 6);
constant OpCode_Eqbranch : std_logic_vector(5 downto 0) := conv_std_logic_vector(55, 6);
constant OpCode_Neqbranch : std_logic_vector(5 downto 0) := conv_std_logic_vector(56, 6);
constant OpCode_Poppcrel : std_logic_vector(5 downto 0) := conv_std_logic_vector(57, 6);
constant OpCode_Pushspadd : std_logic_vector(5 downto 0) := conv_std_logic_vector(61, 6);
constant OpCode_Mult16x16 : std_logic_vector(5 downto 0) := conv_std_logic_vector(62, 6);
constant OpCode_Callpcrel : std_logic_vector(5 downto 0) := conv_std_logic_vector(63, 6);
constant OpCode_Size : integer := 8;
end zpupkg;