- Integrated MBlite CPU
- Integrated UART - Various bug fixes
This commit is contained in:
132
Makefile
132
Makefile
@@ -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
|
||||
|
||||
@@ -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
21
firmware/Makefile
Normal 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
57
firmware/kcrt0.s
Normal 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
1
firmware/objs/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
*.o
|
||||
29
firmware/standalone.ld
Normal file
29
firmware/standalone.ld
Normal 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
32
firmware/test.s
Normal 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
54
mblite/config_Pkg.vhd
Normal 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
156
mblite/core.vhd
Normal 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
439
mblite/core_Pkg.vhd
Normal 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
71
mblite/core_wb.vhd
Normal 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
106
mblite/core_wb_adapter.vhd
Normal 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
499
mblite/decode.vhd
Normal 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
55
mblite/dsram.vhd
Normal 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
257
mblite/execute.vhd
Normal 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
72
mblite/fetch.vhd
Normal 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
87
mblite/gprf.vhd
Normal 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
107
mblite/mem.vhd
Normal 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
262
mblite/std_Pkg.vhd
Normal 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
6
mblite_rom.bmm
Normal 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
243
src/mblite_rom.vhd
Normal 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
97
src/mblite_wrapper.vhd
Normal 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
130
src/pio.vhd
Normal 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;
|
||||
254
src/toplevel.vhd
254
src/toplevel.vhd
@@ -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
73
src/uart/fifo16x8.vhd
Executable 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
55
src/uart/par2ser.vhd
Executable 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
80
src/uart/pulsegen325.vhd
Executable 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
72
src/uart/readctrl.vhd
Executable 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
52
src/uart/ser2par.vhd
Executable 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
162
src/uart/uart.vhd
Executable 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
116
src/uart/uart_wbc.vhd
Executable 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
69
src/uart/writectrl.vhd
Executable 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;
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
315
toplevel_tb.wcfg
315
toplevel_tb.wcfg
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
Reference in New Issue
Block a user