URL
https://opencores.org/ocsvn/openarty/openarty/trunk
Subversion Repositories openarty
Compare Revisions
- This comparison shows the changes necessary to convert path
/openarty
- from Rev 29 to Rev 30
- ↔ Reverse comparison
Rev 29 → Rev 30
/trunk/Makefile
33,7 → 33,7
## |
## |
.PHONY: all |
all: archive datestamp rtl bench |
all: archive datestamp rtl bench sw |
# all: verilated sw bench bit |
# |
# Could also depend upon load, if desired, but not necessary |
52,15 → 52,15
|
.PHONY: datestamp |
datestamp: |
@bash -c 'if [ ! -e $(YYMMDD)-build.v ]; then rm 20??????-build.v; perl mkdatev.pl > $(YYMMDD)-build.v; rm -f rtl/builddate.v; fi' |
@bash -c 'if [ ! -e $(YYMMDD)-build.v ]; then rm -f 20??????-build.v; perl mkdatev.pl > $(YYMMDD)-build.v; rm -f rtl/builddate.v; fi' |
@bash -c 'if [ ! -e rtl/builddate.v ]; then cd rtl; cp ../$(YYMMDD)-build.v builddate.v; fi' |
|
.PHONY: archive |
archive: |
tar --transform s,^,$(YYMMDD)-xula/, -chjf $(YYMMDD)-xula.tjz $(BENCH) $(SW) $(RTL) $(NOTES) $(PROJ) $(BIN) $(CONSTRAINTS) |
tar --transform s,^,$(YYMMDD)-arty/, -chjf $(YYMMDD)-arty.tjz $(BENCH) $(SW) $(RTL) $(NOTES) $(PROJ) $(BIN) $(CONSTRAINTS) |
|
.PHONY: verilated |
verilated: |
verilated: datestamp |
cd rtl ; $(MAKE) --no-print-directory |
|
.PHONY: rtl |
72,7 → 72,7
|
.PHONY: sw |
sw: |
cd sw ; $(MAKE) --no-print-directory |
cd sw/host ; $(MAKE) --no-print-directory |
|
# .PHONY: bit |
# bit: |
/trunk/arty.xdc
9,69 → 9,45
|
## Clock signal |
|
set_property PACKAGE_PIN E3 [get_ports i_clk_100mhz] |
set_property IOSTANDARD LVCMOS33 [get_ports i_clk_100mhz] |
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports i_clk_100mhz] |
set_property PACKAGE_PIN E3 [get_ports {sys_clk_i}] |
set_property IOSTANDARD LVCMOS33 [get_ports {sys_clk_i}] |
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports {sys_clk_i}] |
|
##Switches |
|
set_property PACKAGE_PIN A8 [get_ports {i_sw[0]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {i_sw[0]}] |
set_property PACKAGE_PIN C11 [get_ports {i_sw[1]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {i_sw[1]}] |
set_property PACKAGE_PIN C10 [get_ports {i_sw[2]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {i_sw[2]}] |
set_property PACKAGE_PIN A10 [get_ports {i_sw[3]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {i_sw[3]}] |
set_property -dict { PACKAGE_PIN A8 IOSTANDARD LVCMOS33 } [get_ports {i_sw[0]}] |
set_property -dict { PACKAGE_PIN C11 IOSTANDARD LVCMOS33 } [get_ports {i_sw[1]}] |
set_property -dict { PACKAGE_PIN C10 IOSTANDARD LVCMOS33 } [get_ports {i_sw[2]}] |
set_property -dict { PACKAGE_PIN A10 IOSTANDARD LVCMOS33 } [get_ports {i_sw[3]}] |
|
##RGB LEDs |
|
set_property PACKAGE_PIN E1 [get_ports {o_clr_led0[0]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_clr_led0[0]}] |
set_property PACKAGE_PIN F6 [get_ports {o_clr_led0[1]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_clr_led0[1]}] |
set_property PACKAGE_PIN G6 [get_ports {o_clr_led0[2]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_clr_led0[2]}] |
set_property PACKAGE_PIN G4 [get_ports {o_clr_led1[0]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_clr_led1[0]}] |
set_property PACKAGE_PIN J4 [get_ports {o_clr_led1[1]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_clr_led1[1]}] |
set_property PACKAGE_PIN G3 [get_ports {o_clr_led1[2]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_clr_led1[2]}] |
set_property PACKAGE_PIN H4 [get_ports {o_clr_led2[0]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_clr_led2[0]}] |
set_property PACKAGE_PIN J2 [get_ports {o_clr_led2[1]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_clr_led2[1]}] |
set_property PACKAGE_PIN J3 [get_ports {o_clr_led2[2]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_clr_led2[2]}] |
set_property PACKAGE_PIN K2 [get_ports {o_clr_led3[0]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_clr_led3[0]}] |
set_property PACKAGE_PIN H6 [get_ports {o_clr_led3[1]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_clr_led3[1]}] |
set_property PACKAGE_PIN K1 [get_ports {o_clr_led3[2]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_clr_led3[2]}] |
set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports {o_clr_led0[0]}] |
set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports {o_clr_led0[1]}] |
set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports {o_clr_led0[2]}] |
set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports {o_clr_led1[0]}] |
set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports {o_clr_led1[1]}] |
set_property -dict { PACKAGE_PIN G3 IOSTANDARD LVCMOS33 } [get_ports {o_clr_led1[2]}] |
set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports {o_clr_led2[0]}] |
set_property -dict { PACKAGE_PIN J2 IOSTANDARD LVCMOS33 } [get_ports {o_clr_led2[1]}] |
set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS33 } [get_ports {o_clr_led2[2]}] |
set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports {o_clr_led3[0]}] |
set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports {o_clr_led3[1]}] |
set_property -dict { PACKAGE_PIN K1 IOSTANDARD LVCMOS33 } [get_ports {o_clr_led3[2]}] |
|
##LEDs |
|
set_property PACKAGE_PIN H5 [get_ports {o_led[0]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_led[0]}] |
set_property PACKAGE_PIN J5 [get_ports {o_led[1]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_led[1]}] |
set_property PACKAGE_PIN T9 [get_ports {o_led[2]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_led[2]}] |
set_property PACKAGE_PIN T10 [get_ports {o_led[3]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {o_led[3]}] |
set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports {o_led[0]}] |
set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports {o_led[1]}] |
set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports {o_led[2]}] |
set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports {o_led[3]}] |
|
##Buttons |
|
set_property PACKAGE_PIN D9 [get_ports {i_btn[0]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {i_btn[0]}] |
set_property PACKAGE_PIN C9 [get_ports {i_btn[1]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {i_btn[1]}] |
set_property PACKAGE_PIN B9 [get_ports {i_btn[2]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {i_btn[2]}] |
set_property PACKAGE_PIN B8 [get_ports {i_btn[3]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {i_btn[3]}] |
set_property -dict { PACKAGE_PIN D9 IOSTANDARD LVCMOS33 } [get_ports {i_btn[0]}] |
set_property -dict { PACKAGE_PIN C9 IOSTANDARD LVCMOS33 } [get_ports {i_btn[1]}] |
set_property -dict { PACKAGE_PIN B9 IOSTANDARD LVCMOS33 } [get_ports {i_btn[2]}] |
set_property -dict { PACKAGE_PIN B8 IOSTANDARD LVCMOS33 } [get_ports {i_btn[3]}] |
|
##Pmod Header JA: PModCLS (bottom) |
|
86,66 → 62,41
|
##Pmod Header JB: OLEDrgb |
|
set_property PACKAGE_PIN E15 [get_ports o_oled_cs_n] |
set_property IOSTANDARD LVCMOS33 [get_ports o_oled_cs_n] |
set_property PACKAGE_PIN E16 [get_ports o_oled_mosi] |
set_property IOSTANDARD LVCMOS33 [get_ports o_oled_mosi] |
set_property -dict { PACKAGE_PIN E15 IOSTANDARD LVCMOS33 } [get_ports o_oled_cs_n] |
set_property -dict { PACKAGE_PIN E16 IOSTANDARD LVCMOS33 } [get_ports o_oled_mosi] |
#set_property -dict { PACKAGE_PIN D15 IOSTANDARD LVCMOS33 } [get_ports { i_oled_nc }]; #IO_L12P_T1_MRCC_15 Sch=jb_p[2] |
set_property PACKAGE_PIN C15 [get_ports o_oled_sck] |
set_property IOSTANDARD LVCMOS33 [get_ports o_oled_sck] |
set_property PACKAGE_PIN J17 [get_ports o_oled_dcn] |
set_property IOSTANDARD LVCMOS33 [get_ports o_oled_dcn] |
set_property PACKAGE_PIN J18 [get_ports o_oled_reset_n] |
set_property IOSTANDARD LVCMOS33 [get_ports o_oled_reset_n] |
set_property PACKAGE_PIN K15 [get_ports o_oled_vccen] |
set_property IOSTANDARD LVCMOS33 [get_ports o_oled_vccen] |
set_property PACKAGE_PIN J15 [get_ports o_oled_pmoden] |
set_property IOSTANDARD LVCMOS33 [get_ports o_oled_pmoden] |
set_property -dict { PACKAGE_PIN C15 IOSTANDARD LVCMOS33 } [get_ports o_oled_sck] |
set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports o_oled_dcn] |
set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports o_oled_reset_n] |
set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports o_oled_vccen] |
set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports o_oled_pmoden] |
|
##Pmod Header JC: GPS (top), UART (bottom) |
|
set_property PACKAGE_PIN U12 [get_ports i_gps_3df] |
set_property IOSTANDARD LVCMOS33 [get_ports i_gps_3df] |
set_property PACKAGE_PIN V12 [get_ports o_gps_tx] |
set_property IOSTANDARD LVCMOS33 [get_ports o_gps_tx] |
set_property PACKAGE_PIN V10 [get_ports i_gps_rx] |
set_property IOSTANDARD LVCMOS33 [get_ports i_gps_rx] |
set_property PACKAGE_PIN V11 [get_ports i_gps_pps] |
set_property IOSTANDARD LVCMOS33 [get_ports i_gps_pps] |
set_property PACKAGE_PIN U14 [get_ports i_aux_rts] |
set_property IOSTANDARD LVCMOS33 [get_ports i_aux_rts] |
set_property PACKAGE_PIN V14 [get_ports o_aux_tx] |
set_property IOSTANDARD LVCMOS33 [get_ports o_aux_tx] |
set_property PACKAGE_PIN T13 [get_ports i_aux_rx] |
set_property IOSTANDARD LVCMOS33 [get_ports i_aux_rx] |
set_property PACKAGE_PIN U13 [get_ports o_aux_cts] |
set_property IOSTANDARD LVCMOS33 [get_ports o_aux_cts] |
set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports i_gps_3df] |
set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports o_gps_tx] |
set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports i_gps_rx] |
set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports i_gps_pps] |
set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports i_aux_rts] |
set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports o_aux_tx] |
set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports i_aux_rx] |
set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports o_aux_cts] |
|
##Pmod Header JD: SD-Card |
|
set_property PACKAGE_PIN D4 [get_ports {io_sd[3]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {io_sd[3]}] |
set_property PACKAGE_PIN D3 [get_ports io_sd_cmd] |
set_property IOSTANDARD LVCMOS33 [get_ports io_sd_cmd] |
set_property PACKAGE_PIN F4 [get_ports {io_sd[0]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {io_sd[0]}] |
set_property PACKAGE_PIN F3 [get_ports o_sd_sck] |
set_property IOSTANDARD LVCMOS33 [get_ports o_sd_sck] |
set_property PACKAGE_PIN E2 [get_ports {io_sd[1]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {io_sd[1]}] |
set_property PACKAGE_PIN D2 [get_ports {io_sd[2]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {io_sd[2]}] |
set_property PACKAGE_PIN H2 [get_ports i_sd_cs] |
set_property IOSTANDARD LVCMOS33 [get_ports i_sd_cs] |
set_property PACKAGE_PIN G2 [get_ports i_sd_wp] |
set_property IOSTANDARD LVCMOS33 [get_ports i_sd_wp] |
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports {io_sd[3]}] |
set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports io_sd_cmd] |
set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports {io_sd[0]}] |
set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports o_sd_sck] |
set_property -dict { PACKAGE_PIN E2 IOSTANDARD LVCMOS33 } [get_ports {io_sd[1]}] |
set_property -dict { PACKAGE_PIN D2 IOSTANDARD LVCMOS33 } [get_ports {io_sd[2]}] |
set_property -dict { PACKAGE_PIN H2 IOSTANDARD LVCMOS33 } [get_ports i_sd_cs] |
set_property -dict { PACKAGE_PIN G2 IOSTANDARD LVCMOS33 } [get_ports i_sd_wp] |
|
##USB-UART Interface |
# THESE ARE CORRECT |
set_property PACKAGE_PIN D10 [get_ports o_uart_tx] |
set_property IOSTANDARD LVCMOS33 [get_ports o_uart_tx] |
set_property PACKAGE_PIN A9 [get_ports i_uart_rx] |
set_property IOSTANDARD LVCMOS33 [get_ports i_uart_rx] |
set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports o_uart_tx] |
set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports i_uart_rx] |
# |
|
##ChipKit Single Ended Analog Inputs |
238,47 → 189,89
##Misc. ChipKit signals |
|
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { ck_ioa }]; #IO_L10N_T1_D15_14 Sch=ck_ioa |
set_property PACKAGE_PIN C2 [get_ports i_reset_btn] |
set_property IOSTANDARD LVCMOS33 [get_ports i_reset_btn] |
set_property -dict { PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports i_reset_btn] |
|
##SMSC Ethernet PHY |
|
#set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { eth_col }]; #IO_L16N_T2_A27_15 Sch=eth_col |
#set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { eth_crs }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=eth_crs |
set_property PACKAGE_PIN F16 [get_ports o_eth_mdclk] |
set_property IOSTANDARD LVCMOS33 [get_ports o_eth_mdclk] |
set_property PACKAGE_PIN K13 [get_ports io_eth_mdio] |
set_property IOSTANDARD LVCMOS33 [get_ports io_eth_mdio] |
#set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { eth_ref_clk }]; #IO_L22P_T3_A17_15 Sch=eth_ref_clk |
#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { eth_rstn }]; #IO_L20P_T3_A20_15 Sch=eth_rstn |
#set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { eth_rx_clk }]; #IO_L14P_T2_SRCC_15 Sch=eth_rx_clk |
#set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { eth_rx_dv }]; #IO_L13N_T2_MRCC_15 Sch=eth_rx_dv |
#set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[0] }]; #IO_L21N_T3_DQS_A18_15 Sch=eth_rxd[0] |
#set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[1] }]; #IO_L16P_T2_A28_15 Sch=eth_rxd[1] |
#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[2] }]; #IO_L21P_T3_DQS_15 Sch=eth_rxd[2] |
#set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxd[3] }]; #IO_L18N_T2_A23_15 Sch=eth_rxd[3] |
#set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L20N_T3_A19_15 Sch=eth_rxerr |
#set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { eth_tx_clk }]; #IO_L13P_T2_MRCC_15 Sch=eth_tx_clk |
#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { eth_tx_en }]; #IO_L19N_T3_A21_VREF_15 Sch=eth_tx_en |
#set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L15P_T2_DQS_15 Sch=eth_txd[0] |
#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L19P_T3_A22_15 Sch=eth_txd[1] |
#set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[2] }]; #IO_L17N_T2_A25_15 Sch=eth_txd[2] |
#set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { eth_txd[3] }]; #IO_L18P_T2_A24_15 Sch=eth_txd[3] |
set_property -dict { PACKAGE_PIN D17 IOSTANDARD LVCMOS33 } [get_ports { i_eth_col }]; #IO_L16N_T2_A27_15 Sch=eth_col |
set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { i_eth_crs }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=eth_crs |
set_property -dict { PACKAGE_PIN F16 IOSTANDARD LVCMOS33 } [get_ports o_eth_mdclk] |
set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports io_eth_mdio] |
set_property -dict { PACKAGE_PIN G18 IOSTANDARD LVCMOS33 } [get_ports { o_eth_ref_clk }]; #IO_L22P_T3_A17_15 Sch=eth_ref_clk |
set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { o_eth_rstn }]; #IO_L20P_T3_A20_15 Sch=eth_rstn |
set_property -dict { PACKAGE_PIN F15 IOSTANDARD LVCMOS33 } [get_ports { i_eth_rx_clk }]; #IO_L14P_T2_SRCC_15 Sch=eth_rx_clk |
set_property -dict { PACKAGE_PIN G16 IOSTANDARD LVCMOS33 } [get_ports { i_eth_rx_dv }]; #IO_L13N_T2_MRCC_15 Sch=eth_rx_dv |
set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { i_eth_rxd[0] }]; #IO_L21N_T3_DQS_A18_15 Sch=eth_rxd[0] |
set_property -dict { PACKAGE_PIN E17 IOSTANDARD LVCMOS33 } [get_ports { i_eth_rxd[1] }]; #IO_L16P_T2_A28_15 Sch=eth_rxd[1] |
set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports { i_eth_rxd[2] }]; #IO_L21P_T3_DQS_15 Sch=eth_rxd[2] |
set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { i_eth_rxd[3] }]; #IO_L18N_T2_A23_15 Sch=eth_rxd[3] |
set_property -dict { PACKAGE_PIN C17 IOSTANDARD LVCMOS33 } [get_ports { i_eth_rxerr }]; #IO_L20N_T3_A19_15 Sch=eth_rxerr |
set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { i_eth_tx_clk }]; #IO_L13P_T2_MRCC_15 Sch=eth_tx_clk |
set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { o_eth_tx_en }]; #IO_L19N_T3_A21_VREF_15 Sch=eth_tx_en |
set_property -dict { PACKAGE_PIN H14 IOSTANDARD LVCMOS33 } [get_ports { o_eth_txd[0] }]; #IO_L15P_T2_DQS_15 Sch=eth_txd[0] |
set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { o_eth_txd[1] }]; #IO_L19P_T3_A22_15 Sch=eth_txd[1] |
set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { o_eth_txd[2] }]; #IO_L17N_T2_A25_15 Sch=eth_txd[2] |
set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { o_eth_txd[3] }]; #IO_L18P_T2_A24_15 Sch=eth_txd[3] |
|
# Ethernet generated clocks from the chip |
create_clock -period 40.000 -name eth_tx_pin -add [get_ports {i_eth_tx_clk}] |
create_clock -period 40.000 -name eth_rx_pin -add [get_ports {i_eth_rx_clk}] |
|
# And crossing clocks from ethernet clocks to master clock |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/o_net_reset*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_rx_clear*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/n_tx_busy*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_tx_busy*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/txpadi/o_v*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_tx_busy*}] 12.3; |
# set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/n_*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/tx_len*}] -to [get_cells -hier -filter {NAME =~ *netctrl/n_*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/config_*}] -to [get_cells -hier -filter {NAME =~ *netctrl/n_*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/tx_cm*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_tx_cm*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/tx_cancel*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_tx_cancel*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/hw_mac*}] -to [get_cells -hier -filter {NAME =~ *netctrl/txmaci/r_hw*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/hw_mac*}] -to [get_cells -hier -filter {NAME =~ *netctrl/rxmaci/r_hw*}] 12.3; |
# set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/n_*}] -to [get_cells -hier -filter {NAME =~ *net_scope/mem*}] 12.3; |
# set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/txprei/r_*}] -to [get_cells -hier -filter {NAME =~ *net_scope/o_*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/txprei/r_*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/txprei/r_*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/txmaci/o_*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/txpadi/o_*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/txcrci/o_v*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_tx_busy*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/txpadi/o_v*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_tx_busy*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/n_rx_val*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_rx_val*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/n_rx_busy*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_rx_busy*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/n_rx_len*}] -to [get_cells -hier -filter {NAME =~ *netctrl/rx_len*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/n_rx_miss*}] -to [get_cells -hier -filter {NAME =~ *netctrl/rx_miss_pi*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/p_rx_cle*}] -to [get_cells -hier -filter {NAME =~ *netctrl/r_rx_clear*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/n_rx_crce*}] -to [get_cells -hier -filter {NAME =~ *netctrl/rx_crc_pip*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/n_rx_err*}] -to [get_cells -hier -filter {NAME =~ *netctrl/rx_err_pip*}] 12.3; |
|
# and for the scope ... if we have that configured |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *net_scope/br_config*}] -to [get_cells -hier -filter {NAME =~ *net_scope/mem*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *net_scope/br_config*}] -to [get_cells -hier -filter {NAME =~ *net_scope/waddr*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *net_scope/br_config*}] -to [get_cells -hier -filter {NAME =~ *net_scope/counter*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *net_scope/br_config*}] -to [get_cells -hier -filter {NAME =~ *net_scope/dr_*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *net_scope/br_config*}] -to [get_cells -hier -filter {NAME =~ *net_scope/q_if*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *net_scope/r_rese*}] -to [get_cells -hier -filter {NAME =~ *net_scope/q_rese*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *net_scope/waddr*}] -to [get_cells -hier -filter {NAME =~ *net_scope/mem*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *net_scope/dr_*}] -to [get_cells -hier -filter {NAME =~ *net_scope/q_of*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/n_*}] -to [get_cells -hier -filter {NAME =~ *net_scope/o_wb_*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/rxmaci/o_d*}] -to [get_cells -hier -filter {NAME =~ *net_scope/o_wb_data*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/rxmaci/r_err*}] -to [get_cells -hier -filter {NAME =~ *net_scope/o_wb_data*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/rxememi/o_v*}] -to [get_cells -hier -filter {NAME =~ *net_scope/o_wb_data*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/rxprei/o_d*}] -to [get_cells -hier -filter {NAME =~ *net_scope/o_wb_data*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/rxprei/o_v*}] -to [get_cells -hier -filter {NAME =~ *net_scope/o_wb_data*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/rxmaci*}] -to [get_cells -hier -filter {NAME =~ *net_scope/o_wb_data*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/rxmaci/o_broa*}] -to [get_cells -hier -filter {NAME =~ *net_scope/o_wb_data*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/rxcrci/o_d*}] -to [get_cells -hier -filter {NAME =~ *net_scope/o_wb_data*}] 12.3; |
set_max_delay -datapath_only -from [get_cells -hier -filter {NAME=~ *netctrl/rxcrci/o_v*}] -to [get_cells -hier -filter {NAME =~ *net_scope/o_wb_data*}] 12.3; |
|
##Quad SPI Flash |
|
set_property PACKAGE_PIN L13 [get_ports o_qspi_cs_n] |
set_property IOSTANDARD LVCMOS33 [get_ports o_qspi_cs_n] |
set_property PACKAGE_PIN K17 [get_ports {io_qspi_dat[0]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {io_qspi_dat[0]}] |
set_property PACKAGE_PIN K18 [get_ports {io_qspi_dat[1]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {io_qspi_dat[1]}] |
set_property PACKAGE_PIN L14 [get_ports {io_qspi_dat[2]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {io_qspi_dat[2]}] |
set_property PACKAGE_PIN M14 [get_ports {io_qspi_dat[3]}] |
set_property IOSTANDARD LVCMOS33 [get_ports {io_qspi_dat[3]}] |
set_property PACKAGE_PIN L16 [get_ports o_qspi_sck] |
set_property IOSTANDARD LVCMOS33 [get_ports o_qspi_sck] |
set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports o_qspi_cs_n] |
set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports {io_qspi_dat[0]}] |
set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports {io_qspi_dat[1]}] |
set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports {io_qspi_dat[2]}] |
set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports {io_qspi_dat[3]}] |
set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports o_qspi_sck] |
|
##Power Measurements |
|
292,107 → 285,69
#set_property -dict { PACKAGE_PIN A15 IOSTANDARD LVCMOS33 } [get_ports { isns0v95_p }]; #IO_L8P_T1_AD10P_15 Sch=ad_p[10] |
|
## Memory |
|
# Memory address lines |
set_property PACKAGE_PIN R2 [get_ports {o_ddr_addr[0]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[0]}] |
set_property PACKAGE_PIN M6 [get_ports {o_ddr_addr[1]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[1]}] |
set_property PACKAGE_PIN N4 [get_ports {o_ddr_addr[2]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[2]}] |
set_property PACKAGE_PIN T1 [get_ports {o_ddr_addr[3]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[3]}] |
set_property PACKAGE_PIN N6 [get_ports {o_ddr_addr[4]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[4]}] |
set_property PACKAGE_PIN R7 [get_ports {o_ddr_addr[5]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[5]}] |
set_property PACKAGE_PIN V6 [get_ports {o_ddr_addr[6]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[6]}] |
set_property PACKAGE_PIN U7 [get_ports {o_ddr_addr[7]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[7]}] |
set_property PACKAGE_PIN R8 [get_ports {o_ddr_addr[8]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[8]}] |
set_property PACKAGE_PIN V7 [get_ports {o_ddr_addr[9]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[9]}] |
set_property PACKAGE_PIN R6 [get_ports {o_ddr_addr[10]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[10]}] |
set_property PACKAGE_PIN U6 [get_ports {o_ddr_addr[11]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[11]}] |
set_property PACKAGE_PIN T6 [get_ports {o_ddr_addr[12]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[12]}] |
set_property PACKAGE_PIN T8 [get_ports {o_ddr_addr[13]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_addr[13]}] |
set_property PACKAGE_PIN R1 [get_ports {o_ddr_ba[0]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_ba[0]}] |
set_property PACKAGE_PIN P4 [get_ports {o_ddr_ba[1]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_ba[1]}] |
set_property PACKAGE_PIN P2 [get_ports {o_ddr_ba[2]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_ba[2]}] |
# |
set_property PACKAGE_PIN M4 [get_ports o_ddr_cas_n] |
set_property IOSTANDARD SSTL135 [get_ports o_ddr_cas_n] |
# Clock lines |
set_property IOSTANDARD DIFF_SSTL135 [get_ports o_ddr_ck_n] |
set_property PACKAGE_PIN U9 [get_ports o_ddr_ck_p] |
set_property IOSTANDARD DIFF_SSTL135 [get_ports o_ddr_ck_p] |
# While valid definitions below, these definitions conflict with the XDC file |
# created by the Memory Interface Generator (MIG), and so these have been |
# commented out. |
# |
set_property PACKAGE_PIN N5 [get_ports o_ddr_cke] |
set_property IOSTANDARD SSTL135 [get_ports o_ddr_cke] |
set_property PACKAGE_PIN U8 [get_ports o_ddr_cs_n] |
set_property IOSTANDARD SSTL135 [get_ports o_ddr_cs_n] |
set_property PACKAGE_PIN L1 [get_ports {o_ddr_dm[0]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_dm[0]}] |
set_property PACKAGE_PIN U1 [get_ports {o_ddr_dm[1]}] |
set_property IOSTANDARD SSTL135 [get_ports {o_ddr_dm[1]}] |
# Data (DQ) lines |
set_property PACKAGE_PIN K5 [get_ports {io_ddr_data[0]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[0]}] |
set_property PACKAGE_PIN L3 [get_ports {io_ddr_data[1]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[1]}] |
set_property PACKAGE_PIN K3 [get_ports {io_ddr_data[2]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[2]}] |
set_property PACKAGE_PIN L6 [get_ports {io_ddr_data[3]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[3]}] |
set_property PACKAGE_PIN M3 [get_ports {io_ddr_data[4]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[4]}] |
set_property PACKAGE_PIN M1 [get_ports {io_ddr_data[5]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[5]}] |
set_property PACKAGE_PIN L4 [get_ports {io_ddr_data[6]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[6]}] |
set_property PACKAGE_PIN M2 [get_ports {io_ddr_data[7]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[7]}] |
set_property PACKAGE_PIN V4 [get_ports {io_ddr_data[8]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[8]}] |
set_property PACKAGE_PIN T5 [get_ports {io_ddr_data[9]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[9]}] |
set_property PACKAGE_PIN U4 [get_ports {io_ddr_data[10]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[10]}] |
set_property PACKAGE_PIN V5 [get_ports {io_ddr_data[11]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[11]}] |
set_property PACKAGE_PIN V1 [get_ports {io_ddr_data[12]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[12]}] |
set_property PACKAGE_PIN T3 [get_ports {io_ddr_data[13]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[13]}] |
set_property PACKAGE_PIN U3 [get_ports {io_ddr_data[14]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[14]}] |
set_property PACKAGE_PIN R3 [get_ports {io_ddr_data[15]}] |
set_property IOSTANDARD SSTL135 [get_ports {io_ddr_data[15]}] |
## Memory address lines |
#set_property -dict { PACKAGE_PIN R2 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[0]}] |
#set_property -dict { PACKAGE_PIN M6 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[1]}] |
#set_property -dict { PACKAGE_PIN N4 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[2]}] |
#set_property -dict { PACKAGE_PIN T1 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[3]}] |
#set_property -dict { PACKAGE_PIN N6 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[4]}] |
#set_property -dict { PACKAGE_PIN R7 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[5]}] |
#set_property -dict { PACKAGE_PIN V6 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[6]}] |
#set_property -dict { PACKAGE_PIN U7 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[7]}] |
#set_property -dict { PACKAGE_PIN R8 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[8]}] |
#set_property -dict { PACKAGE_PIN V7 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[9]}] |
#set_property -dict { PACKAGE_PIN R6 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[10]}] |
#set_property -dict { PACKAGE_PIN U6 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[11]}] |
#set_property -dict { PACKAGE_PIN T6 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[12]}] |
#set_property -dict { PACKAGE_PIN T8 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_addr[13]}] |
#set_property -dict { PACKAGE_PIN R1 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_ba[0]}] |
#set_property -dict { PACKAGE_PIN P4 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_ba[1]}] |
#set_property -dict { PACKAGE_PIN P2 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_ba[2]}] |
# |
## Clock lines |
# |
#set_property -dict { PACKAGE_PIN U9 IOSTANDARD DIFF_SSTL135 SLEW FAST } [get_ports {ddr3_ck_p[0]}] |
#set_property -dict { PACKAGE_PIN V9 IOSTANDARD DIFF_SSTL135 SLEW FAST } [get_ports {ddr3_ck_n[0]}] |
# |
## |
#set_property -dict { PACKAGE_PIN L1 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_dm[0]}] |
#set_property -dict { PACKAGE_PIN U1 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_dm[1]}] |
## Data (DQ) lines |
#set_property -dict { PACKAGE_PIN K5 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[0]}] |
#set_property -dict { PACKAGE_PIN L3 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[1]}] |
#set_property -dict { PACKAGE_PIN K3 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[2]}] |
#set_property -dict { PACKAGE_PIN L6 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[3]}] |
#set_property -dict { PACKAGE_PIN M3 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[4]}] |
#set_property -dict { PACKAGE_PIN M1 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[5]}] |
#set_property -dict { PACKAGE_PIN L4 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[6]}] |
#set_property -dict { PACKAGE_PIN M2 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[7]}] |
#set_property -dict { PACKAGE_PIN V4 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[8]}] |
#set_property -dict { PACKAGE_PIN T5 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[9]}] |
#set_property -dict { PACKAGE_PIN U4 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[10]}] |
#set_property -dict { PACKAGE_PIN V5 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[11]}] |
#set_property -dict { PACKAGE_PIN V1 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[12]}] |
#set_property -dict { PACKAGE_PIN T3 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[13]}] |
#set_property -dict { PACKAGE_PIN U3 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[14]}] |
#set_property -dict { PACKAGE_PIN R3 IOSTANDARD SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dq[15]}] |
# DQS |
set_property IOSTANDARD DIFF_SSTL135 [get_ports {io_ddr_dqs_n[0]}] |
set_property IOSTANDARD DIFF_SSTL135 [get_ports {io_ddr_dqs_n[1]}] |
set_property IOSTANDARD DIFF_SSTL135 [get_ports {io_ddr_dqs_p[0]}] |
set_property PACKAGE_PIN N2 [get_ports {io_ddr_dqs_p[0]}] |
set_property IOSTANDARD DIFF_SSTL135 [get_ports {io_ddr_dqs_p[1]}] |
set_property PACKAGE_PIN U2 [get_ports {io_ddr_dqs_p[1]}] |
set_property PACKAGE_PIN R5 [get_ports o_ddr_odt] |
set_property IOSTANDARD SSTL135 [get_ports o_ddr_odt] |
set_property PACKAGE_PIN P3 [get_ports o_ddr_ras_n] |
set_property IOSTANDARD SSTL135 [get_ports o_ddr_ras_n] |
set_property PACKAGE_PIN K6 [get_ports o_ddr_reset_n] |
set_property IOSTANDARD SSTL135 [get_ports o_ddr_reset_n] |
set_property PACKAGE_PIN P5 [get_ports o_ddr_we_n] |
set_property IOSTANDARD SSTL135 [get_ports o_ddr_we_n] |
#Internal VREF |
#set_property -dict { PACKAGE_PIN N2 IOSTANDARD DIFF_SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dqs_p[0]}] |
#set_property -dict { PACKAGE_PIN U2 IOSTANDARD DIFF_SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dqs_p[1]}] |
#set_property -dict { PACKAGE_PIN N1 IOSTANDARD DIFF_SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dqs_n[0]}] |
#set_property -dict { PACKAGE_PIN V2 IOSTANDARD DIFF_SSTL135 SLEW FAST IN_TERM UNTUNED_SPLIT_50 } [get_ports {ddr3_dqs_n[1]}] |
## Command wires |
#set_property -dict { PACKAGE_PIN K6 IOSTANDARD SSTL135 SLEW FAST } [get_ports ddr3_reset_n] |
#set_property -dict { PACKAGE_PIN N5 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_cke[0]}] |
#set_property -dict { PACKAGE_PIN U8 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_cs_n[0]}] |
#set_property -dict { PACKAGE_PIN P3 IOSTANDARD SSTL135 SLEW FAST } [get_ports ddr3_ras_n] |
#set_property -dict { PACKAGE_PIN M4 IOSTANDARD SSTL135 SLEW FAST } [get_ports ddr3_cas_n] |
#set_property -dict { PACKAGE_PIN P5 IOSTANDARD SSTL135 SLEW FAST } [get_ports ddr3_we_n] |
#set_property -dict { PACKAGE_PIN R5 IOSTANDARD SSTL135 SLEW FAST } [get_ports {ddr3_odt[0]}] |
##Internal VREF |
set_property INTERNAL_VREF 0.675 [get_iobanks 34] |
|
|
/trunk/bench/cpp/Makefile
40,15 → 40,18
FLAGS := -Wall -Og -g |
OBJDIR := obj-pc |
RTLD := ../../rtl |
INCS := -I$(RTLD)/obj_dir/ -I$(RTLD) -I/usr/share/verilator/include |
SOURCES := eqspiflashsim.cpp eqspiflash_tb.cpp |
VERILATOR_ROOT ?= $(shell bash -c 'verilator -V|grep VERILATOR_ROOT | head -1 | sed -e " s/^.*=\s*//"') |
VROOT := $(VERILATOR_ROOT) |
INCS := -I$(RTLD)/obj_dir/ -I$(RTLD) -I$(VROOT)/include |
SOURCES := eqspiflashsim.cpp eqspiflash_tb.cpp enetctrlsim.cpp \ |
memsim.cpp sdspisim.cpp uartsim.cpp ddrsdramsim.cpp |
VOBJDR := $(RTLD)/obj_dir |
VLIB := /usr/share/verilator/include/verilated.cpp |
VLIB := $(VROOT)/include/verilated.cpp |
SIMSRCS := enetctrlsim.cpp eqspiflashsim.cpp \ |
sdspisim.cpp uartsim.cpp |
memsim.cpp sdspisim.cpp uartsim.cpp |
SIMOBJ := $(subst .cpp,.o,$(SIMSRCS)) |
SIMOBJS:= $(addprefix $(OBJDIR)/,$(SIMOBJ)) |
all: $(OBJDIR)/ fastmaster_tb eqspiflash_tb |
all: $(OBJDIR)/ busmaster_tb eqspiflash_tb enetctrl_tb |
|
$(OBJDIR)/: |
@bash -c "if [ ! -e $(OBJDIR) ]; then mkdir -p $(OBJDIR); fi" |
63,11 → 66,14
$(CXX) $(FLAGS) $(INCS) $^ $(VOBJDR)/Venetctrl__ALL.a $(VLIB) -o $@ |
|
fastmaster_tb:fastmaster_tb.cpp $(SIMOBJS) $(VOBJDR)/Vfastmaster__ALL.a |
$(CXX) $(FLAGS) $(INCS) $^ $(VOBJDR)/Vfastmaster__ALL.a $(VLIB) -o $@ |
$(CXX) -DFASTCLK $(FLAGS) $(INCS) $^ $(VOBJDR)/Vfastmaster__ALL.a $(VLIB) -o $@ |
busmaster_tb:fastmaster_tb.cpp $(SIMOBJS) $(VOBJDR)/Vbusmaster__ALL.a |
$(CXX) $(FLAGS) $(INCS) $^ $(VOBJDR)/Vbusmaster__ALL.a $(VLIB) -o $@ |
|
.PHONY: clean |
clean: |
rm ./eqspiflash_tb |
rm ./enetctrl_tb |
rm ./fastmaster_tb |
rm -f ./eqspiflash_tb |
rm -f ./enetctrl_tb |
rm -f ./fastmaster_tb |
rm -f ./busmaster_tb |
|
/trunk/bench/cpp/enetctrl_tb.cpp
62,7 → 62,7
void tick(void) { |
m_core->i_clk = 1; |
|
m_core->i_mdio = (*m_sim)(m_core->o_mdclk, |
m_core->i_mdio = (*m_sim)(0, m_core->o_mdclk, |
((m_core->o_mdwe)&(m_core->o_mdio)) |
|((m_core->o_mdwe)?0:1)); |
|
287,15 → 287,21
int main(int argc, char **argv) { |
Verilated::commandArgs(argc, argv); |
ENETCTRL_TB *tb = new ENETCTRL_TB; |
// unsigned rdv; |
unsigned v; |
// unsigned *rdbuf; |
|
tb->wb_tick(); |
tb->wb_write(0, 0x7f82); |
if ((*tb)[0] != 0x7f82) { |
printf("Somehow wrote a %04x, rather than 0x7f82\n", (*tb)[0]); |
goto test_failure; |
} |
|
tb->wb_tick(); |
if (tb->wb_read(0)!=0x7f82) |
if ((v=tb->wb_read(0))!=0x7f82) { |
printf("READ A %08x FROM THE CORE, NOT 0x7f82\n", v); |
goto test_failure; |
} |
|
// |
tb->wb_tick(); |
/trunk/bench/cpp/enetctrlsim.cpp
36,6 → 36,7
// |
// |
#include <stdio.h> |
#include <assert.h> |
#include "enetctrlsim.h" |
|
ENETCTRLSIM::ENETCTRLSIM(void) { |
48,13 → 49,13
m_halfword = 0; |
m_datareg = -1; |
PHY_ADDR = 1; |
TICKS_PER_CLOCK = 8; |
TICKS_PER_CLOCK = 4; |
for(int i=0; i<ENET_MEMWORDS; i++) |
m_mem[i] = 0; |
m_outreg = -1; |
} |
|
int ENETCTRLSIM::operator()(int clk, int data) { |
int ENETCTRLSIM::operator()(int in_reset, int clk, int data) { |
int posedge, negedge, output = 1; |
|
posedge = ((clk)&&(!m_lastclk)); |
62,6 → 63,17
|
m_tickcount++; |
|
if (in_reset) { |
m_consecutive_clocks = 0; |
m_synched = false; |
m_lastout = 1; |
m_datareg = -1; |
|
m_lastclk = clk; |
|
return 1; |
} |
|
if (posedge) { |
if ((data)&&(m_consecutive_clocks < 128)) |
m_consecutive_clocks++; |
80,6 → 92,7
m_synched = true; |
m_lastout = 1; |
m_halfword = 0; |
m_datareg = -1; |
} |
|
if ((posedge)&&(m_synched)) { |
112,6 → 125,10
printf("ENETCTRL: Unknown PHY, %d, expecting %d\n", phy, PHY_ADDR); |
if ((cmd==5)&&(phy==PHY_ADDR)) { |
int addr; |
|
if (m_datareg & 0x010000) |
printf("ERR: ENETCTRL, write command and bit 16 is active!\n"); |
assert((m_datareg & 0x010000)==0); |
addr = (m_datareg>>18)&0x1f; |
m_mem[addr] = m_datareg & 0x0ffff; |
printf("ENETCTRL: Setting MEM[%01x] = %04x\n", |
121,7 → 138,7
} |
} else if (negedge) { |
m_outreg = (m_outreg<<1)|1; |
} output = (m_outreg&0x80000000)?1:0; |
} output = (m_outreg&0x40000000)?1:0; |
|
|
m_lastclk = clk; |
/trunk/bench/cpp/enetctrlsim.h
51,7 → 51,7
ENETCTRLSIM(void); |
~ENETCTRLSIM(void) {} |
|
int operator()(int clk, int data); |
int operator()(int inreset, int clk, int data); |
int operator[](int index) const; |
}; |
|
/trunk/bench/cpp/eqspiflashsim.cpp
110,7 → 110,7
m_ireg = m_oreg = 0; |
m_sreg = 0x01c; |
m_creg = 0x001; // Initial creg on delivery |
m_config = 0x7; // Volatile configuration register |
m_vconfig = 0x7; // Volatile configuration register |
m_nvconfig = 0x0fff; // Nonvolatile configuration register |
m_quad_mode = false; |
m_mode_byte = 0; |
431,12 → 431,12
break; |
case 0x81: // Write volatile config register |
m_state = EQSPIF_WRCR; |
if (m_debug) printf("EQSPI: WRITING CONFIG REGISTER: %02x\n", m_config); |
if (m_debug) printf("EQSPI: WRITING VOLATILE CONFIG REGISTER: %02x\n", m_vconfig); |
break; |
case 0x85: // Read volatile config register |
m_state = EQSPIF_RDCR; |
if (m_debug) printf("EQSPI: READING CONFIG REGISTER: %02x\n", m_config); |
QOREG(m_config>>8); |
if (m_debug) printf("EQSPI: READING VOLATILE CONFIG REGISTER: %02x\n", m_vconfig); |
QOREG(m_vconfig); |
break; |
case 0x9e: // Read ID (fall through) |
case 0x9f: // Read ID |
508,19 → 508,19
} |
break; |
case EQSPIF_WRCR: // Write volatile config register, 0x81 |
if (m_count == 8) { |
m_config = m_ireg & 0x0ff; |
printf("Setting volatile config register to %08x\n", m_config); |
assert((m_config & 0xfb)==0x8b); |
if (m_count == 8+8) { |
m_vconfig = m_ireg & 0x0ff; |
printf("Setting volatile config register to %08x\n", m_vconfig); |
assert((m_vconfig & 0xfb)==0x8b); |
} break; |
case EQSPIF_WRNVCONFIG: // Write nonvolatile config register |
if (m_count == 8) { |
if (m_count == 8+8) { |
m_nvconfig = m_ireg & 0x0ffdf; |
printf("Setting nonvolatile config register to %08x\n", m_config); |
printf("Setting nonvolatile config register to %08x\n", m_nvconfig); |
assert((m_nvconfig & 0xffc5)==0x8fc5); |
} break; |
case EQSPIF_WREVCONFIG: // Write enhanced volatile config reg |
if (m_count == 8) { |
if (m_count == 8+8) { |
m_evconfig = m_ireg & 0x0ff; |
printf("Setting enhanced volatile config register to %08x\n", m_evconfig); |
assert((m_evconfig & 0x0d7)==0xd7); |
531,7 → 531,6
if ((m_lockregs[m_addr]&2)==0) |
m_lockregs[m_addr] = m_ireg&3; |
printf("Setting lock register[%02x] to %d\n", m_addr, m_lockregs[m_addr]); |
assert((m_config & 0xfb)==0x8b); |
} break; |
case EQSPIF_RDLOCK: |
if (m_count == 24) { |
592,7 → 591,7
QOREG(m_sreg); |
break; |
case EQSPIF_RDCR: |
if (m_debug) printf("Read CREG = %02x\n", m_creg); |
if (m_debug) printf("Read VCONF = %02x\n", m_vconfig); |
QOREG(m_creg); |
break; |
case EQSPIF_FAST_READ: |
637,7 → 636,7
// printf("EQSPIF[%08x]/QR = %02x\n", |
// m_addr-1, m_oreg); |
} else { |
printf("ERR: EQSPIF--TRYING TO READ WHILE BUSY! (count = %d)\n", m_count); |
// printf("ERR: EQSPIF--TRYING TO READ WHILE BUSY! (count = %d)\n", m_count); |
m_oreg = 0; |
} |
break; |
/trunk/bench/cpp/eqspiflashsim.h
82,7 → 82,7
char *m_mem, *m_pmem, *m_otp, *m_lockregs; |
int m_last_sck; |
unsigned m_write_count, m_ireg, m_oreg, m_sreg, m_addr, |
m_count, m_config, m_mode_byte, m_creg, |
m_count, m_vconfig, m_mode_byte, m_creg, |
m_nvconfig, m_evconfig, m_flagreg, m_nxtout[4]; |
bool m_quad_mode, m_debug, m_otp_wp; |
|
/trunk/bench/cpp/fastmaster_tb.cpp
4,10 → 4,12
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: This is a piped version of the testbench for the fastmaster |
// verilog module. The fastmaster code is designed to be a |
// complete code set implementing all of the functionality of the Digilent |
// Arty board. If done well, the programs talking to this one should be |
// Purpose: This is a piped version of the testbench for the wishbone |
// master verilog module, whether it be fastmaster.v or |
// busmaster.v. Both fastmaster.v and busmaster.v are designed to be |
// complete code sets implementing all of the functionality of the Digilent |
// Arty board---save the hardware dependent features to include the DDR3 |
// memory. If done well, the programs talking to this one should be |
// able to talk to the board and apply the same tests to the board itself. |
// |
// Creator: Dan Gisselquist, Ph.D. |
44,18 → 46,23
#include <ctype.h> |
|
#include "verilated.h" |
#ifdef FASTCLK |
#include "Vfastmaster.h" |
#define BASECLASS Vfastmaster |
#error "This should never be incldued" |
#else |
#include "Vbusmaster.h" |
#define BASECLASS Vbusmaster |
#endif |
|
#include "testb.h" |
// #include "twoc.h" |
#include "pipecmdr.h" |
#include "eqspiflashsim.h" |
#ifdef SDRAM_ACCESS |
#include "ddrsdramsim.h" |
#endif |
#include "sdspisim.h" |
#include "uartsim.h" |
#include "enetctrlsim.h" |
#include "memsim.h" |
|
#include "port.h" |
|
62,30 → 69,26
const int LGMEMSIZE = 28; |
|
// No particular "parameters" need definition or redefinition here. |
class FASTMASTER_TB : public PIPECMDR<Vfastmaster> { |
class TESTBENCH : public PIPECMDR<BASECLASS> { |
public: |
unsigned long m_tx_busy_count; |
EQSPIFLASHSIM m_flash; |
SDSPISIM m_sdcard; |
#ifdef SDRAM_ACCESS |
DDRSDRAMSIM m_sdram; |
#endif |
ENETCTRLSIM *m_mid; |
UARTSIM m_uart; |
MEMSIM m_ram; |
|
unsigned m_last_led, m_last_pic, m_last_tx_state; |
unsigned m_last_led, m_last_pic, m_last_tx_state, m_net_ticks; |
time_t m_start_time; |
bool m_last_writeout; |
bool m_last_writeout, m_cpu_started; |
int m_last_bus_owner, m_busy; |
|
FASTMASTER_TB(void) : PIPECMDR(FPGAPORT), |
#ifdef SDRAM_ACCESS |
m_sdram(LGMEMSIZE), |
#endif |
m_uart(FPGAPORT+1) |
TESTBENCH(void) : PIPECMDR(FPGAPORT), |
m_uart(FPGAPORT+1), m_ram(1<<26) |
{ |
m_start_time = time(NULL); |
m_mid = new ENETCTRLSIM; |
m_cpu_started =false; |
} |
|
void setsdcard(const char *fn) { |
106,33 → 109,21
} |
|
// Set up the bus before any clock tick |
m_core->i_clk = 1; |
|
m_core->i_qspi_dat = m_flash(m_core->o_qspi_cs_n, |
m_core->o_qspi_sck, m_core->o_qspi_dat); |
|
m_core->i_mdio = (*m_mid)(m_core->o_mdclk, |
((m_core->o_mdwe)&(m_core->o_mdio)) |
|((m_core->o_mdwe)?0:1)); |
m_core->i_mdio = (*m_mid)((m_core->o_net_reset_n==0)?1:0, m_core->o_mdclk, |
((m_core->o_mdwe)&&(!m_core->o_mdio))?0:1); |
|
#ifdef SDRAM_ACCESS |
m_core->i_ddr_data = m_sdram( |
m_core->o_ddr_reset_n, |
m_core->o_ddr_cke, |
m_core->o_ddr_cs_n, |
m_core->o_ddr_ras_n, |
m_core->o_ddr_cas_n, |
m_core->o_ddr_we_n, |
m_core->o_ddr_dqs, |
m_core->o_ddr_dm, |
m_core->o_ddr_odt, |
m_core->o_ddr_bus_oe, |
m_core->o_ddr_addr, |
m_core->o_ddr_ba, |
m_core->o_ddr_data); |
#else |
m_core->i_ddr_data = 0; |
#endif |
/* |
printf("MDIO: %d %d %d %d/%d -> %d\n", |
m_core->o_net_reset_n, |
m_core->o_mdclk, |
m_core->o_mdwe, |
m_core->o_mdio, |
((m_core->o_mdwe)&&(!m_core->o_mdio))?0:1, |
m_core->i_mdio); |
*/ |
|
m_core->i_aux_rx = m_uart(m_core->o_aux_tx, |
m_core->v__DOT__runio__DOT__aux_setup); |
142,10 → 133,51
m_core->i_sd_data &= 1; |
m_core->i_sd_data |= (m_core->o_sd_data&0x0e); |
|
// Turn the network into a simple loopback device. |
if (++m_net_ticks>5) |
m_net_ticks = 0; |
m_core->i_net_rx_clk = (m_net_ticks >= 2)&&(m_net_ticks < 5); |
m_core->i_net_tx_clk = (m_net_ticks >= 0)&&(m_net_ticks < 3); |
if (!m_core->i_net_rx_clk) { |
m_core->i_net_dv = m_core->o_net_tx_en; |
m_core->i_net_rxd = m_core->o_net_txd; |
m_core->i_net_crs = m_core->o_net_tx_en; |
} m_core->i_net_rxerr = 0; |
if (!m_core->o_net_reset_n) { |
m_core->i_net_dv = 0; |
m_core->i_net_crs= 0; |
} |
|
m_ram.apply(m_core->o_ram_cyc, m_core->o_ram_stb, |
m_core->o_ram_we, m_core->o_ram_addr, |
m_core->o_ram_wdata, m_core->i_ram_ack, |
m_core->i_ram_stall, m_core->i_ram_rdata); |
|
PIPECMDR::tick(); |
|
// #define DEBUGGING_OUTPUT |
#define DEBUGGING_OUTPUT |
#ifdef DEBUGGING_OUTPUT |
bool writeout = false; |
|
// if (m_core->o_net_tx_en) |
// writeout = true; |
|
// if (m_core->v__DOT__wbu_cyc) |
// writeout = true; |
// if (m_core->v__DOT__dwb_cyc) |
// writeout = true; |
|
if (m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__master_ce) |
writeout = true; |
if (m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__dbgv) |
writeout = true; |
if ((m_core->v__DOT__zippy__DOT__dbg_cyc)&&(m_core->v__DOT__zippy__DOT__dbg_stb)) |
writeout = true; |
if ((m_core->v__DOT__zippy__DOT__dbg_cyc)&&(m_core->v__DOT__zippy__DOT__dbg_ack)) |
writeout = true; |
if (m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf_cyc) |
writeout = true; |
|
/* |
*/ |
if ((writeout)||(m_last_writeout)) { |
158,18 → 190,19
m_core->i_tx_busy?"/BSY":" "); |
*/ |
|
/* |
printf("(%d,%d->%d),(%c:%d,%d->%d)|%c[%08x/%08x]@%08x %c%c%c", |
// To get some understanding of what is on the bus, |
// and hence some context for everything else, |
// this offers a view of the bus. |
printf("(%d,%d->%d)%s(%c:%d,%d->%d)|%c[%08x/%08x]@%08x %c%c%c", |
m_core->v__DOT__wbu_cyc, |
m_core->v__DOT__dwb_cyc, // was zip_cyc |
0, |
m_core->v__DOT__wb_cyc, |
"", // (m_core->v__DOT__wbu_zip_delay__DOT__r_stb)?"!":" ", |
// |
m_core->v__DOT__wbu_zip_arbiter__DOT__r_a_owner?'Z':'j', |
m_core->v__DOT__wbu_stb, |
// 0, // m_core->v__DOT__dwb_stb, // was zip_stb |
m_core->v__DOT__zippy__DOT__thecpu__DOT__mem_stb_gbl, |
m_core->v__DOT__wb_stb, |
m_core->v__DOT__wbu_stb, // WBU strobe |
m_core->v__DOT__zippy__DOT__ext_stb, // zip_stb |
m_core->v__DOT__wb_stb, // m_core->v__DOT__wb_stb, output of delay(ed) strobe |
// |
(m_core->v__DOT__wb_we)?'W':'R', |
m_core->v__DOT__wb_data, |
180,15 → 213,132
(m_core->v__DOT__dwb_stall)?'S': |
(m_core->v__DOT____Vcellinp__genbus____pinNumber10)?'s':' ', |
(m_core->v__DOT__wb_err)?'E':'.'); |
*/ |
|
/* |
*/ |
|
/* |
// CPU Pipeline debugging |
*/ |
printf("%s%s%s%s%s%s%s%s%s%s%s", |
// (m_core->v__DOT__zippy__DOT__dbg_ack)?"A":"-", |
// (m_core->v__DOT__zippy__DOT__dbg_stall)?"S":"-", |
// (m_core->v__DOT__zippy__DOT__sys_dbg_cyc)?"D":"-", |
(m_core->v__DOT__zippy__DOT__cpu_lcl_cyc)?"L":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__r_halted)?"Z":"-", |
(m_core->v__DOT__zippy__DOT__cpu_break)?"!":"-", |
(m_core->v__DOT__zippy__DOT__cmd_halt)?"H":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__gie)?"G":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf_cyc)?"P":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf_valid)?"V":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf_illegal)?"i":" ", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__new_pc)?"N":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__domem__DOT__r_wb_cyc_gbl)?"G":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__domem__DOT__r_wb_cyc_lcl)?"L":"-"); |
printf("|%s%s%s%s%s%s", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__r_dcdvalid)?"D":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__dcd_ce)?"d":"-", |
"x", // (m_core->v__DOT__zippy__DOT__thecpu__DOT__dcdA_stall)?"A":"-", |
"x", // (m_core->v__DOT__zippy__DOT__thecpu__DOT__dcdB_stall)?"B":"-", |
"x", // (m_core->v__DOT__zippy__DOT__thecpu__DOT__dcdF_stall)?"F":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__dcd_illegal)?"i":"-"); |
|
printf("|%s%s%s%s%s%s%s%s%s%s", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__opvalid)?"O":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__op_ce)?"k":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__op_stall)?"s":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__op_illegal)?"i":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__r_op_break)?"B":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__genblk5__DOT__r_op_lock)?"L":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__r_op_pipe)?"P":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__r_break_pending)?"p":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__r_op_gie)?"G":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__opvalid_alu)?"A":"-"); |
printf("|%s%s%s%s%s", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__alu_ce)?"a":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__alu_stall)?"s":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__doalu__DOT__genblk2__DOT__r_busy)?"B":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__r_alu_gie)?"G":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__r_alu_illegal)?"i":"-"); |
printf("|%s%s%s%2x %s%s%s %2d %2d", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__opvalid_mem)?"M":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__mem_ce)?"m":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__adf_ce_unconditional)?"!":"-", |
(m_core->v__DOT__zippy__DOT__cmd_addr), |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__bus_err)?"BE":" ", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__ibus_err_flag)?"IB":" ", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__ubus_err_flag)?"UB":" ", |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__domem__DOT__rdaddr, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__domem__DOT__wraddr); |
printf("|%s%s", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__div_busy)?"D":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__div_error)?"E":"-"); |
printf("|%s%s[%2x]%08x", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__wr_reg_ce)?"W":"-", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__wr_flags_ce)?"F":"-", |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__wr_reg_id, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__wr_gpreg_vl); |
|
// Program counter debugging |
printf(" PC0x%08x/%08x/%08x-%08x %s0x%08x", |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf_pc, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__ipc, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__upc, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__instruction, |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_early_branch)?"EB":" ", |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_branch_pc |
); |
// More in-depth |
printf("[%c%08x,%c%08x,%c%08x]", |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__r_dcdvalid)?'D':'-', |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__dcd_pc, |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__opvalid)?'O':'-', |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__op_pc, |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__alu_valid)?'A':'-', |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__r_alu_pc); |
|
// Prefetch debugging |
printf(" [PC%08x,LST%08x]->[%d%s%s](%d,%08x/%08x)->%08x@%08x", |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf_pc, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf__DOT__lastpc, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf__DOT__rvsrc, |
(m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf__DOT__rvsrc) |
?((m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf__DOT__r_v_from_pc)?"P":" ") |
:((m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf__DOT__r_v_from_pc)?"p":" "), |
(!m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf__DOT__rvsrc) |
?((m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf__DOT__r_v_from_last)?"l":" ") |
:((m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf__DOT__r_v_from_last)?"L":" "), |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf__DOT__isrc, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf__DOT__r_pc_cache, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__pf__DOT__r_last_cache, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__instruction, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__instruction_pc); |
|
// Decode Stage debugging |
// (nothing) |
|
// Op Stage debugging |
// printf(" Op(%02x,%02x->%02x)", |
// m_core->v__DOT__zippy__DOT__thecpu__DOT__dcdOp, |
// m_core->v__DOT__zippy__DOT__thecpu__DOT__opn, |
// m_core->v__DOT__zippy__DOT__thecpu__DOT__opR); |
|
printf(" %s[%02x]=%08x(%08x)", |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__wr_reg_ce?"WR":"--", |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__wr_reg_id, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__wr_gpreg_vl, |
m_core->v__DOT__zippy__DOT__genblk11__DOT__thecpu__DOT__wr_spreg_vl |
); |
|
printf(" DBG%s%s%s[%s/%02x]=%08x/%08x", |
(m_core->v__DOT__zippy__DOT__dbg_cyc)?"CYC":" ", |
(m_core->v__DOT__zippy__DOT__dbg_stb)?"STB":((m_core->v__DOT__zippy__DOT__dbg_ack)?"ACK":" "), |
((m_core->v__DOT__zippy__DOT__dbg_cyc)&&(m_core->v__DOT__zippy__DOT__dbg_stb))?((m_core->v__DOT__zippy__DOT__dbg_we)?"-W":"-R"):" ", |
(m_core->v__DOT__zippy__DOT__dbg_cyc)?" ":((m_core->v__DOT__zippy__DOT__dbg_addr)?"D":"C"), |
(m_core->v__DOT__zippy__DOT__cmd_addr), |
(m_core->v__DOT__zippy__DOT__dbg_idata), |
m_core->v__DOT__zip_dbg_data); |
|
printf(" %s,0x%08x", (m_core->i_ram_ack)?"RCK":" ", m_core->i_ram_rdata); |
|
/* |
printf(" SDSPI[%d,%d(%d),(%d)]", |
m_core->v__DOT__sdcard_controller__DOT__r_cmd_busy, |
240,13 → 390,125
} |
*/ |
|
/* |
printf("ETH[TX:%s%s%x%s]", |
(m_core->i_net_tx_clk)?"CK":" ", |
(m_core->o_net_tx_en)?" ":"(", |
m_core->o_net_txd, |
(m_core->o_net_tx_en)?" ":")"); |
printf("/%s(%04x,%08x[%08x])", |
(m_core->v__DOT__netctrl__DOT__n_tx_busy)?"BSY":" ", |
m_core->v__DOT__netctrl__DOT__n_tx_addr, |
m_core->v__DOT__netctrl__DOT__n_next_tx_data, |
m_core->v__DOT__netctrl__DOT__n_tx_data); |
printf("[RX:%s%s%s%s%x%s]", |
(m_core->i_net_rx_clk)?"CK":" ", |
(m_core->i_net_crs)?"CR":" ", |
(m_core->i_net_rxerr)?"ER":" ", |
(m_core->i_net_dv)?" ":"(", |
m_core->i_net_rxd, |
(m_core->i_net_dv)?" ":")"); |
printf("%s%s", |
(m_core->v__DOT__netctrl__DOT__n_rx_valid)?"V":" ", |
(m_core->v__DOT__netctrl__DOT__n_rx_clear)?"C":" "); |
printf("/%s%s(%04x,%s%08x@%04x)%08x", |
(m_core->v__DOT__netctrl__DOT__n_rx_busy)?"BSY":" ", |
(m_core->v__DOT__netctrl__DOT__n_rx_inpacket)?"IN":" ", |
m_core->v__DOT__netctrl__DOT__n_rx_addr, |
(m_core->v__DOT__netctrl__DOT__n_rx_wr)?"W":" ", |
m_core->v__DOT__netctrl__DOT__n_rx_wdat, |
m_core->v__DOT__netctrl__DOT__n_rx_wad, |
m_core->v__DOT__netctrl__DOT__n_rx_toggle); |
|
printf(" TXMAC %x%s -> %2x -> %x%s", |
m_core->v__DOT__netctrl__DOT__r_txd, |
(m_core->v__DOT__netctrl__DOT__r_txd_en)?"!":" ", |
(m_core->v__DOT__netctrl__DOT__txmaci__DOT__r_pos), |
m_core->v__DOT__netctrl__DOT__w_macd, |
(m_core->v__DOT__netctrl__DOT__w_macen)?"!":" "); |
printf(" TXCRC %x%s ->%2x/0x%08x -> %x%s", |
m_core->v__DOT__netctrl__DOT__w_macd, |
(m_core->v__DOT__netctrl__DOT__w_macen)?"!":" ", |
m_core->v__DOT__netctrl__DOT__txcrci__DOT__r_p, |
m_core->v__DOT__netctrl__DOT__txcrci__DOT__r_crc, |
m_core->v__DOT__netctrl__DOT__w_macd, |
(m_core->v__DOT__netctrl__DOT__w_macen)?"!":" "); |
*/ |
|
// Flash debugging support |
printf("%s/%s %s %s[%s%s%s%s%s] %s@%08x[%08x/%08x] -- SPI %s%s[%x/%x](%d,%d)", |
((m_core->v__DOT__wb_stb)&&((m_core->v__DOT__skipaddr>>3)==1))?"D":" ", |
((m_core->v__DOT__wb_stb)&&(m_core->v__DOT__flctl_sel))?"C":" ", |
(m_core->v__DOT__flashmem__DOT__bus_wb_stall)?"STALL":" ", |
(m_core->v__DOT__flash_ack)?"ACK":" ", |
(m_core->v__DOT__flashmem__DOT__bus_wb_ack)?"BS":" ", |
(m_core->v__DOT__flashmem__DOT__rd_data_ack)?"RD":" ", |
(m_core->v__DOT__flashmem__DOT__ew_data_ack)?"EW":" ", |
(m_core->v__DOT__flashmem__DOT__id_data_ack)?"ID":" ", |
(m_core->v__DOT__flashmem__DOT__ct_data_ack)?"CT":" ", |
(m_core->v__DOT__wb_we)?"W":"R", |
(m_core->v__DOT__wb_addr), |
(m_core->v__DOT__wb_data), |
(m_core->v__DOT__flash_data), |
(m_core->o_qspi_cs_n)?"CS":" ", |
(m_core->o_qspi_sck)?"CK":" ", |
(m_core->o_qspi_dat), |
(m_core->i_qspi_dat), |
(m_core->o_qspi_dat)&1, |
((m_core->i_qspi_dat)&2)?1:0), |
|
printf(" REQ[%s%s%s%s]", |
m_core->v__DOT__flashmem__DOT__rd_qspi_req?"RD":" ", |
m_core->v__DOT__flashmem__DOT__ew_qspi_req?"EW":" ", |
m_core->v__DOT__flashmem__DOT__id_qspi_req?"ID":" ", |
m_core->v__DOT__flashmem__DOT__ct_qspi_req?"CT":" "); |
|
printf(" %s[%s%2d%s%s0x%08x]", |
(m_core->v__DOT__flashmem__DOT__spi_wr)?"CMD":" ", |
(m_core->v__DOT__flashmem__DOT__spi_hold)?"HLD":" ", |
(m_core->v__DOT__flashmem__DOT__spi_len+1)*8, |
(m_core->v__DOT__flashmem__DOT__spi_dir)?"RD":"WR", |
(m_core->v__DOT__flashmem__DOT__spi_spd)?"Q":" ", |
m_core->v__DOT__flashmem__DOT__spi_word); |
|
printf(" STATE[%2x%s,%2x%s,%2x%s,%2x%s]", |
m_core->v__DOT__flashmem__DOT__rdproc__DOT__rd_state, (m_core->v__DOT__flashmem__DOT__rd_spi_wr)?"W":" ", |
m_core->v__DOT__flashmem__DOT__ewproc__DOT__wr_state, (m_core->v__DOT__flashmem__DOT__ew_spi_wr)?"W":" ", |
m_core->v__DOT__flashmem__DOT__idotp__DOT__id_state, (m_core->v__DOT__flashmem__DOT__id_spi_wr)?"W":" ", |
m_core->v__DOT__flashmem__DOT__ctproc__DOT__ctstate, (m_core->v__DOT__flashmem__DOT__ct_spi_wr)?"W":" "); |
printf("%s%s%s%s", |
(m_core->v__DOT__flashmem__DOT__rdproc__DOT__accepted)?"RD-ACC":"", |
(m_core->v__DOT__flashmem__DOT__ewproc__DOT__accepted)?"EW-ACC":"", |
(m_core->v__DOT__flashmem__DOT__idotp__DOT__accepted)?"ID-ACC":"", |
(m_core->v__DOT__flashmem__DOT__ctproc__DOT__accepted)?"CT-ACC":""); |
|
printf("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", |
(m_core->v__DOT__flashmem__DOT__preproc__DOT__pending)?" PENDING":"", |
(m_core->v__DOT__flashmem__DOT__preproc__DOT__lcl_key)?" KEY":"", |
(m_core->v__DOT__flashmem__DOT__preproc__DOT__ctreg_stb)?" CTSTB":"", |
(m_core->v__DOT__flashmem__DOT__bus_ctreq)?" BUSCTRL":"", |
(m_core->v__DOT__flashmem__DOT__bus_other_req)?" BUSOTHER":"", |
(m_core->v__DOT__flashmem__DOT__preproc__DOT__wp)?" WRWP":"", |
(m_core->v__DOT__flashmem__DOT__bus_wip)?" WIP":"", |
(m_core->v__DOT__flashmem__DOT__ewproc__DOT__cyc)?" WRCYC":"", |
(m_core->v__DOT__flashmem__DOT__bus_pipewr)?" WRPIPE":"", |
(m_core->v__DOT__flashmem__DOT__bus_endwr)?" ENDWR":"", |
(m_core->v__DOT__flashmem__DOT__ct_ack)?" CTACK":"", |
(m_core->v__DOT__flashmem__DOT__rd_bus_ack)?" RDACK":"", |
(m_core->v__DOT__flashmem__DOT__id_bus_ack)?" IDACK":"", |
(m_core->v__DOT__flashmem__DOT__ew_bus_ack)?" EWACK":"", |
(m_core->v__DOT__flashmem__DOT__preproc__DOT__lcl_ack)?" LCLACK":"", |
(m_core->v__DOT__flashmem__DOT__rdproc__DOT__r_leave_xip)?" LVXIP":"", |
(m_core->v__DOT__flashmem__DOT__preproc__DOT__new_req)?" NREQ":""); |
|
|
printf("\n"); fflush(stdout); |
} m_last_writeout = writeout; |
#endif |
} |
}; |
|
FASTMASTER_TB *tb; |
TESTBENCH *tb; |
|
void fastmaster_kill(int v) { |
tb->kill(); |
256,7 → 518,7
|
int main(int argc, char **argv) { |
Verilated::commandArgs(argc, argv); |
tb = new FASTMASTER_TB; |
tb = new TESTBENCH; |
|
// signal(SIGINT, fastmaster_kill); |
|
/trunk/bench/cpp/memsim.cpp
0,0 → 1,128
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: memsim.h |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: This creates a memory like device to act on a WISHBONE bus. |
// It doesn't exercise the bus thoroughly, but does give some |
// exercise to the bus to see whether or not the bus master |
// can control it. |
// |
// This particular version differs from the memsim version within the |
// ZipCPU project in that there is a variable delay from request to |
// completion. |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
#include <stdio.h> |
#include <assert.h> |
#include "memsim.h" |
|
MEMSIM::MEMSIM(const unsigned int nwords, const unsigned int delay) { |
unsigned int nxt; |
for(nxt=1; nxt < nwords; nxt<<=1) |
; |
m_len = nxt; m_mask = nxt-1; |
m_mem = new BUSW[m_len]; |
|
m_delay = delay; |
for(m_delay_mask=1; m_delay_mask < delay; m_delay_mask<<=1) |
; |
m_fifo_ack = new int[m_delay_mask]; |
m_fifo_data = new BUSW[m_delay_mask]; |
for(unsigned i=0; i<m_delay_mask; i++) |
m_fifo_ack[i] = 0; |
m_delay_mask-=1; |
m_head = 0; m_tail = (m_head - delay)&m_delay_mask; |
} |
|
MEMSIM::~MEMSIM(void) { |
delete[] m_mem; |
} |
|
void MEMSIM::load(const char *fname) { |
FILE *fp; |
unsigned int nr; |
|
fp = fopen(fname, "r"); |
if (!fp) { |
fprintf(stderr, "Could not open/load file \'%s\'\n", |
fname); |
perror("O/S Err:"); |
fprintf(stderr, "\tInitializing memory with zero instead.\n"); |
nr = 0; |
} else { |
nr = fread(m_mem, sizeof(BUSW), m_len, fp); |
fclose(fp); |
|
if (nr != m_len) { |
fprintf(stderr, "Only read %d of %d words\n", |
nr, m_len); |
fprintf(stderr, "\tFilling the rest with zero.\n"); |
} |
} |
|
for(; nr<m_len; nr++) |
m_mem[nr] = 0l; |
} |
|
void MEMSIM::apply(const unsigned char wb_cyc, |
const unsigned char wb_stb, const unsigned char wb_we, |
const BUSW wb_addr, const BUSW wb_data, |
unsigned char &o_ack, unsigned char &o_stall, BUSW &o_data) { |
m_head++; m_tail = (m_head - m_delay)&m_delay_mask; |
m_head&=m_delay_mask; |
o_ack = m_fifo_ack[m_tail]; |
o_data= m_fifo_data[m_tail]; |
|
m_fifo_ack[ m_head] = 0; |
m_fifo_data[m_head] = 0; |
|
o_stall= 0; |
if ((wb_cyc)&&(wb_stb)) { |
if (wb_we) |
m_mem[wb_addr & m_mask] = wb_data; |
m_fifo_ack[m_head] = 1; |
m_fifo_data[m_head] = m_mem[wb_addr & m_mask]; |
printf("MEMBUS %s[%08x] = %08x\n", |
(wb_we)?"W":"R", |
wb_addr&m_mask, |
m_mem[wb_addr&m_mask]); |
// o_ack = 1; |
} if (o_ack) { |
printf("MEMBUS -- ACK %s 0x%08x - 0x%08x\n", |
(wb_we)?"WRITE":"READ ", |
wb_addr, o_data); |
} |
} |
|
|
/trunk/bench/cpp/memsim.h
0,0 → 1,74
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: memsim.h |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: This creates a memory like device to act on a WISHBONE bus. |
// It doesn't exercise the bus thoroughly, but does give some |
// exercise to the bus to see whether or not the bus master |
// can control it. |
// |
// This particular version differs from the memsim version within the |
// ZipCPU project in that there is a variable delay from request to |
// completion. |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
#ifndef MEMSIM_H |
#define MEMSIM_H |
|
class MEMSIM { |
public: |
typedef unsigned int BUSW; |
typedef unsigned char uchar; |
|
BUSW *m_mem, m_len, m_mask, m_head, m_tail, m_delay_mask, m_delay; |
int *m_fifo_ack; |
BUSW *m_fifo_data; |
|
|
MEMSIM(const unsigned int nwords, const unsigned int delay=27); |
~MEMSIM(void); |
void load(const char *fname); |
void apply(const uchar wb_cyc, const uchar wb_stb, |
const uchar wb_we, |
const BUSW wb_addr, const BUSW wb_data, |
uchar &o_ack, uchar &o_stall, BUSW &o_data); |
void operator()(const uchar wb_cyc, const uchar wb_stb, const uchar wb_we, |
const BUSW wb_addr, const BUSW wb_data, |
uchar &o_ack, uchar &o_stall, BUSW &o_data) { |
apply(wb_cyc, wb_stb, wb_we, wb_addr, wb_data, o_ack, o_stall, o_data); |
} |
BUSW &operator[](const BUSW addr) { return m_mem[addr&m_mask]; } |
}; |
|
#endif |
/trunk/bench/cpp/testb.h
50,6 → 50,12
} |
|
virtual void tick(void) { |
// Make sure we have our evaluations straight before the top |
// of the clock. This is necessary since some of the |
// connection modules may have made changes, for which some |
// logic depends. This forces that logic to be recalculated |
// before the top of the clock. |
eval(); |
m_core->i_clk = 1; |
eval(); |
m_core->i_clk = 0; |
/trunk/doc/spec.pdf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/doc/src/spec.tex
97,14 → 97,19
Xilinx CoreGen IP, etc. Further, I wish to use all of Arty's on--board |
hardware: Flash, DDR3-SDRAM, Ethernet, and everything else at their |
full and fastest speed(s). For example, the flash will need to be |
clocked at 100~MHz, not the 50~MHz I've clocked it at before. The |
clocked at 82~MHz, not the 50~MHz I've clocked it at before. The |
memory should also be able to support pipelined 32--bit interactions |
over the Wishbone bus at a 200~MHz clock. Finally, the Ethernet |
over the Wishbone bus at a 162~MHz clock. Finally, the Ethernet |
controller should be supported by a DMA capable interface that can |
drive the ethernet at its full 100Mbps rate. |
|
\item Run using a 200~MHz clock, if for no other reason than to gain the |
experience of building logic that can run that fast. |
\item Run using a 162.5~MHz clock, if for no other reason than to gain the |
experience of building logic that can run that fast.\footnote{The |
original goal was to run at 200~MHz. However, the memory controller |
cannot run faster than 83~MHz. If we run it at 81.25~MHz and double |
that clock to get our logic clock, that now places us at 162.5~MHz. |
200~MHz is \ldots too fast for DDR3 transfers using the Artix--7 chip |
on the Arty.} |
|
\item Modify the ZipCPU to support an MMU and a data cache, and perhaps even |
a floating point unit. |
187,9 → 192,8
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 0010 10xx} & \scalebox{0.9}{\tt 0x00000128} & \hfill 4 & RTC control\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 0010 11xx} & \scalebox{0.9}{\tt 0x0000012c} & \hfill 4 & SDCard controller\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 0011 00xx} & \scalebox{0.9}{\tt 0x00000130} & \hfill 4 & GPS Clock loop control\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 0011 01xx} & \scalebox{0.9}{\tt 0x00000134} & \hfill 4 & Network packet interface\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 0011 10xx} & \scalebox{0.9}{\tt 0x00000138} & \hfill 4 & OLEDrgb control\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 0011 11xx} & \scalebox{0.9}{\tt 0x0000013c} & \hfill 4 & {\em Unused}\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 0011 01xx} & \scalebox{0.9}{\tt 0x00000134} & \hfill 4 & OLEDrgb control\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 0011 1xxx} & \scalebox{0.9}{\tt 0x00000138} & \hfill 8 & Network packet interface\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 0100 0xxx} & \scalebox{0.9}{\tt 0x00000140} & \hfill 8 & GPS Testbench\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 0100 1xxx} & \scalebox{0.9}{\tt 0x00000148} & \hfill 8 & {\em Unused}\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 0101 xxxx} & \scalebox{0.9}{\tt 0x00000150} & \hfill 16 & {\em Unused}\\\hline |
198,10 → 202,13
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 101x xxxx} & \scalebox{0.9}{\tt 0x000001a0} & \hfill 32 & Ethernet configuration registers\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 110x xxxx} & \scalebox{0.9}{\tt 0x000001c0} & \hfill 32 & Extended Flash Control Port\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 0001 111x xxxx} & \scalebox{0.9}{\tt 0x000001e0} & \hfill 32 & ICAPE2 Configuration Port\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 10xx xxxx xxxx} & \scalebox{0.9}{\tt 0x00000800} & \hfill 1k & Ethernet TX Buffer\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 11xx xxxx xxxx} & \scalebox{0.9}{\tt 0x00000c00} & \hfill 1k & Ethernet RX Buffer\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 10xx xxxx xxxx} & \scalebox{0.9}{\tt 0x00000800} & \hfill 1k & Ethernet RX Buffer\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 0000 11xx xxxx xxxx} & \scalebox{0.9}{\tt 0x00000c00} & \hfill 1k & Ethernet TX Buffer\\\hline |
\scalebox{0.9}{\tt 0000 0000 0000 1xxx xxxx xxxx xxxx} & \scalebox{0.9}{\tt 0x00008000} & \hfill 32k & On-chip Block RAM\\\hline |
\scalebox{0.9}{\tt 0000 01xx xxxx xxxx xxxx xxxx xxxx} & \scalebox{0.9}{\tt 0x00400000} & \hfill 4M & QuadSPI Flash\\\hline |
\scalebox{0.9}{\tt 0000 0100 0000 0000 0000 0000 0000} & \scalebox{0.9}{\tt 0x00400000} & & Configuration Start\\\hline |
\scalebox{0.9}{\tt 0000 0100 0111 0000 0000 0000 0000} & \scalebox{0.9}{\tt 0x00470000} & & Alternate Configuration\\\hline |
\scalebox{0.9}{\tt 0000 0100 1110 0000 0000 0000 0000} & \scalebox{0.9}{\tt 0x004e0000} & & CPU Reset Address\\\hline |
\scalebox{0.9}{\tt 01xx xxxx xxxx xxxx xxxx xxxx xxxx} & \scalebox{0.9}{\tt 0x04000000} & \hfill 64M & DDR3 SDRAM\\\hline |
\scalebox{0.9}{\tt 1000 0000 0000 0000 0000 0000 000x} & \scalebox{0.9}{\tt 0x08000000} & \hfill 2 & ZipCPU debug control port---only visible to debug WB master\\\hline |
\end{tabular} |
382,7 → 389,7
\caption{Flash control registers}\label{tbl:flctl} |
\end{center}\end{table} |
|
\chapter{Wishbone} |
\chapter{Wishbone Datasheet}\label{ch:wishbone} |
|
The master and slave interfaces have been simplified with the following |
requirement: the {\tt STB} line is not allowed to be high unless the {\tt CYC} |
390,15 → 397,19
and only act on the presence of {\tt STB}, knowing that {\tt CYC} must be |
active at the same time. |
|
\chapter{Clocks} |
\chapter{Clocks}\label{ch:clocks} |
\begin{table}\begin{center} |
\begin{clocklist} |
{\tt i\_clk\_100mhz} & Ext & \multicolumn{2}{c|}{100~MHz} & |
{\tt i\_clk\_100mhz} & Ext & \multicolumn{2}{c|}{100} & |
100~MHz Crystal Oscillator \\\hline |
{\tt s\_clk} & PLL & 200~MHz & & Internal Logic, Wishbone Clock \\\hline |
{\tt ram\_clk} & PLL & 200~MHz & & DDR3 SDRAM Clock \\\hline |
{\tt o\_sck} & Logic & 108~MHz & 50~MHz & QSPI Flash clock \\\hline |
{\tt o\_sdclk} & Logic & 50~MHz & 100~kHz & SD--Card clock \\\hline |
{\em Future }{\tt s\_clk} & PLL & 152 & 166 & Internal Logic, Wishbone Clock \\\hline |
{\tt s\_clk} & PLL & 83.33 & 75.76& DDR3 SDRAM Controller Clock \\\hline |
\multicolumn{2}{|c|}{\tt mem\_clk\_200mhz} & 200~MHz & & MIG Reference clock for PHASERs\\\hline |
{\tt ddr3\_ck\_}$x$ & DDR & 166.67 & 303 & DDR3 Command Clock\\\hline |
{\tt o\_qspi\_sck} & DDR & 95 & & QSPI Flash clock \\\hline |
{\tt o\_sd\_clk} & Logic & 50 & 0.100 & SD--Card clock \\\hline |
{\tt o\_oled\_sck} & Logic & 166 & & OLED SPI clock \\\hline |
{\tt o\_eth\_mdclk} & Logic & 25 & 2.5 & Ethernet MDIO controller clock\\\hline |
\end{clocklist} |
\caption{OpenArty clocks}\label{tbl:clocks} |
\end{center}\end{table} |
/trunk/rtl/Makefile
46,10 → 46,10
test: $(VDIRFB)/Vbusmaster__ALL.a |
|
CPUDR := cpu |
CPUSOURCESnD := zipcpu.v fastops.v pfcache.v pipemem.v \ |
pfcache.v ifastdec.v wbpriarbiter.v zipbones.v \ |
CPUSOURCESnD := zipcpu.v cpuops.v pfcache.v pipemem.v \ |
pfcache.v idecode.v wbpriarbiter.v zipbones.v \ |
zipsystem.v zipcounter.v zipjiffies.v ziptimer.v \ |
wbdmac.v icontrol.v wbwatchdog.v |
wbdmac.v icontrol.v wbwatchdog.v busdelay.v cpudefs.v |
CPUSOURCES := $(addprefix $(CPUDR)/,$(CPUSOURCESnD)) |
|
JTAGBUS := wbufifo.v wbubus.v wbucompactlines.v \ |
56,10 → 56,11
wbucompress.v wbudecompress.v wbudeword.v wbuexec.v \ |
wbuidleint.v wbuinput.v wbuoutput.v wbureadcw.v wbusixchar.v \ |
wbutohex.v |
PERIPHERALS:= enetctrl.v fastio.v rtcdate.v rtcgps.v \ |
PERIPHERALS:= enetctrl.v enetpackets.v fastio.v rtcdate.v rtcgps.v \ |
rxuart.v txuart.v eqspiflash.v lleqspi.v flash_config.v \ |
wbicapetwo.v sdspi.v gpsclock_tb.v gpsclock.v wboled.v lloled.v \ |
wbscopc.v wbscope.v memdev.v wbddrsdram.v |
wbscopc.v wbscope.v memdev.v addepreamble.v addemac.v addecrc.v \ |
addepad.v rxecrc.v rxepreambl.v rxehwmac.v rxewrite.v |
BIGMATH:= bigadd.v bigsmpy.v bigsub.v |
SOURCES := fastmaster.v builddate.v \ |
$(CPUSOURCES) $(JTAGBUS) $(PERIPHERALS) $(BIGMATH) |
/trunk/rtl/addecrc.v
0,0 → 1,104
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: addecrc.v |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: To (optionally) add a CRC to a stream of nibbles. The CRC |
// is calculated from the stream. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
module addecrc(i_clk, i_ce, i_en, i_cancel, i_v, i_d, o_v, o_d); |
localparam INVERT = 1; // Proper operation requires INVERT=1 |
input i_clk, i_ce, i_en, i_cancel; |
input i_v; |
input [3:0] i_d; |
output reg o_v; |
output reg [3:0] o_d; |
|
reg [7:0] r_p; |
reg [31:0] r_crc; |
wire [3:0] lownibble; |
wire [31:0] shifted_crc; |
|
assign lownibble = r_crc[3:0] ^ i_d; |
assign shifted_crc = { 4'h0, r_crc[31:4] }; |
|
initial o_v = 1'b0; |
always @(posedge i_clk) |
if (i_ce) |
begin |
if (((!i_v)&&(!o_v))||(i_cancel)) |
begin |
r_crc <= (INVERT==0)? 32'h00 : 32'hffffffff; |
r_p <= 8'hff; |
end else if (i_v) |
begin |
o_v <= i_v; |
r_p <= 8'hff; |
o_d <= i_d; |
|
`define CRCBIT8 32'hedb88320 |
`define CRCBIT4 32'h76dc4190 |
`define CRCBIT2 32'h3b6e20c8 |
`define CRCBIT1 32'h1db71064 |
|
// 0xedb88320 . 76dc4190 . 3b6e20c8 . 1db71064 . 0edb8832 |
case(lownibble) |
4'h0: r_crc <= shifted_crc; |
4'h1: r_crc <= shifted_crc ^ `CRCBIT1; |
4'h2: r_crc <= shifted_crc ^ `CRCBIT2; |
4'h3: r_crc <= shifted_crc ^ `CRCBIT2 ^ `CRCBIT1; |
4'h4: r_crc <= shifted_crc ^ `CRCBIT4; |
4'h5: r_crc <= shifted_crc ^ `CRCBIT4 ^ `CRCBIT1; |
4'h6: r_crc <= shifted_crc ^ `CRCBIT4 ^ `CRCBIT2; |
4'h7: r_crc <= shifted_crc ^ `CRCBIT4 ^ `CRCBIT2 ^ `CRCBIT1; |
4'h8: r_crc <= shifted_crc ^ `CRCBIT8; |
4'h9: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT1; |
4'ha: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT2; |
4'hb: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT2 ^ `CRCBIT1; |
4'hc: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT4; |
4'hd: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT4 ^ `CRCBIT1; |
4'he: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT4 ^ `CRCBIT2; |
4'hf: r_crc <= shifted_crc ^ `CRCBIT8 ^ `CRCBIT4 ^ `CRCBIT2 ^ `CRCBIT1; |
|
default: r_crc <= { 4'h0, r_crc[31:4] }; |
endcase |
end else begin |
r_p <= { r_p[6:0], 1'b0 }; |
o_v <= (i_en)?r_p[7]:1'b0; |
o_d <= r_crc[3:0] ^ ((INVERT==0)? 4'h0:4'hf); |
r_crc <= { 4'h0, r_crc[31:4] }; |
end |
end |
|
endmodule |
|
/trunk/rtl/addemac.v
0,0 → 1,122
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: addemac.v |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: To add the device hardware MAC address into a data stream |
// that doesn't have it. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
module addemac(i_clk, i_ce, i_en, i_cancel, i_hw_mac, |
i_v, i_nibble, o_v, o_nibble); |
input i_clk, i_ce, i_en, i_cancel; |
input [47:0] i_hw_mac; |
input i_v; |
input [3:0] i_nibble; |
output reg o_v; |
output reg [3:0] o_nibble; |
|
wire [47:0] mac_remapped; |
assign mac_remapped[47:44] = i_hw_mac[43:40]; |
assign mac_remapped[43:40] = i_hw_mac[47:44]; |
assign mac_remapped[39:36] = i_hw_mac[35:32]; |
assign mac_remapped[35:32] = i_hw_mac[39:36]; |
assign mac_remapped[31:28] = i_hw_mac[27:24]; |
assign mac_remapped[27:24] = i_hw_mac[31:28]; |
assign mac_remapped[23:20] = i_hw_mac[19:16]; |
assign mac_remapped[19:16] = i_hw_mac[23:20]; |
assign mac_remapped[15:12] = i_hw_mac[11: 8]; |
assign mac_remapped[11: 8] = i_hw_mac[15:12]; |
assign mac_remapped[ 7: 4] = i_hw_mac[ 3: 0]; |
assign mac_remapped[ 3: 0] = i_hw_mac[ 7: 4]; |
|
reg [47:0] r_hw; |
reg [59:0] r_buf; |
reg [5:0] r_pos; |
|
always @(posedge i_clk) |
if (i_ce) |
begin |
r_buf <= { r_buf[54:0], i_v, i_nibble }; |
|
if (((!i_v)&&(!o_v))||(i_cancel)) |
begin |
r_buf[ 4] <= 1'b0; |
r_buf[ 9] <= 1'b0; |
r_buf[14] <= 1'b0; |
r_buf[19] <= 1'b0; |
r_buf[24] <= 1'b0; |
r_buf[29] <= 1'b0; |
r_buf[34] <= 1'b0; |
r_buf[39] <= 1'b0; |
r_buf[44] <= 1'b0; |
r_buf[49] <= 1'b0; |
r_buf[54] <= 1'b0; |
r_buf[59] <= 1'b0; |
end |
|
if ((!i_v)||(i_cancel)) |
r_hw <= mac_remapped; |
else |
r_hw <= { r_hw[43:0], r_hw[47:44] }; |
|
if (((!i_v)&&(!o_v))||(i_cancel)) |
r_pos <= 6'h0; |
else if ((r_pos < 6'h18 )&&(i_en)) |
r_pos <= r_pos + 6'h1; |
else if ((r_pos < 6'h20 )&&(!i_en)) |
r_pos <= r_pos + 6'h1; |
|
if (i_en) |
begin |
if (((!i_v)&&(!o_v))||(i_cancel)) |
begin |
o_v <= 1'b0; |
end else begin |
if (r_pos < 6'hc) // six bytes, but counted as |
begin // nibbles |
{ o_v, o_nibble } <= { i_v, i_nibble }; |
end else if (r_pos < 6'h18) |
begin |
{ o_v, o_nibble } <= { 1'b1, r_hw[47:44] }; |
end else |
{ o_v, o_nibble } <= r_buf[59:55]; |
end |
end else if (r_pos < 6'h20) |
{ o_v, o_nibble } <= r_buf[19:15]; |
else |
{ o_v, o_nibble } <= { i_v, i_nibble }; |
if(i_cancel) |
o_v <= 1'b0; |
end |
|
endmodule |
/trunk/rtl/addepad.v
0,0 → 1,77
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: addepad.v |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: To force the minimum packet size of an ethernet frame to be |
// a minimum of 64 bytes. This assumes that the CRC will be |
// adding 32-bits to the packet after us, so instead of padding to |
// 64 bytes, we'll pad to 60 bytes instead. If the user is providing |
// their own CRC, they'll need to adjust the padding themselves. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
module addepad(i_clk, i_ce, i_en, i_cancel, i_v, i_d, o_v, o_d); |
input i_clk, i_ce, i_en, i_cancel; |
input i_v; // Valid |
input [3:0] i_d; // Data nibble |
output reg o_v; |
output reg [3:0] o_d; |
|
// 60 bytes translates to 120 nibbles, so let's keep track of our |
// minimum number of nibbles to transmit |
reg [119:0] r_v; |
|
initial r_v = 120'hff_ffff_ffff_ffff_ffff_ffff_ffff_ffff; |
initial o_v = 1'b0; |
always @(posedge i_clk) |
if (i_ce) |
begin |
if (((!i_v)&&(!o_v))||(i_cancel)) |
begin |
r_v <= 120'hff_ffff_ffff_ffff_ffff_ffff_ffff_ffff; |
o_v <= 1'b0; |
end else if (i_v) |
begin |
o_v <= i_v; |
r_v <= { r_v[118:0], 1'b0 }; |
end else begin |
o_v <= r_v[119]; |
r_v <= { r_v[118:0], 1'b0 }; |
end |
|
if (i_v) |
o_d <= i_d; |
else |
o_d <= 4'h0; |
end |
|
endmodule |
/trunk/rtl/addepreamble.v
0,0 → 1,88
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: addepreamble.v |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: To add the ethernet preamble to a stream of values (i.e., to |
// an ethernet packet ...) |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
module addepreamble(i_clk, i_ce, i_en, i_cancel, i_v, i_d, o_v, o_d); |
input i_clk, i_ce, i_en, i_cancel; |
input i_v; // Valid |
input [3:0] i_d; // Data nibble |
output wire o_v; |
output wire [3:0] o_d; |
|
reg [84:0] shiftreg; |
reg r_v; |
reg [3:0] r_d; |
|
initial r_v = 1'b0; |
always @(posedge i_clk) |
if (i_ce) |
begin |
shiftreg <= { shiftreg[79:0], { i_v, i_d }}; |
r_v <= shiftreg[84]; |
r_d <= shiftreg[83:80]; |
if (((!i_v)&&(!o_v))||(i_cancel)) |
begin |
shiftreg <= { 5'h00, 5'h15, 5'h15, 5'h15, 5'h15, |
5'h15, 5'h15, 5'h15, 5'h15, |
5'h15, 5'h15, 5'h15, 5'h15, |
5'h15, 5'h15, 5'h15, 5'h1d }; |
if (!i_en) |
begin |
shiftreg[ 4] <= 1'b0; |
shiftreg[ 9] <= 1'b0; |
shiftreg[14] <= 1'b0; |
shiftreg[19] <= 1'b0; |
shiftreg[24] <= 1'b0; |
shiftreg[29] <= 1'b0; |
shiftreg[34] <= 1'b0; |
shiftreg[39] <= 1'b0; |
shiftreg[44] <= 1'b0; |
shiftreg[49] <= 1'b0; |
shiftreg[54] <= 1'b0; |
shiftreg[59] <= 1'b0; |
shiftreg[64] <= 1'b0; |
shiftreg[69] <= 1'b0; |
shiftreg[74] <= 1'b0; |
shiftreg[79] <= 1'b0; |
end |
end |
end |
|
assign o_v = r_v; |
assign o_d = r_d; |
|
endmodule |
/trunk/rtl/builddate.v
38,4 → 38,4
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
`define DATESTAMP 32'h20160909 |
`define DATESTAMP 32'h20161015 |
/trunk/rtl/busmaster.v
74,10 → 74,11
// SCOPE POSITION ZERO |
// |
`ifdef FLASH_ACCESS |
`define FLASH_SCOPE // Position zero |
`else |
// `define FLASH_SCOPE // Position zero |
`endif |
`ifdef ZIPCPU |
// `define CPU_SCOPE // Position zero |
`ifndef FLASH_SCOPE |
`define CPU_SCOPE // Position zero |
`endif |
`endif |
// |
84,18 → 85,24
// SCOPE POSITION ONE |
// |
// `define GPS_SCOPE // Position one |
`ifdef ICAPE_ACCESS |
`define CFG_SCOPE // Position one |
`endif |
// `ifdef ICAPE_ACCESS |
// `define CFG_SCOPE // Position one |
// `endif |
// `define WBU_SCOPE |
// |
// SCOPE POSITION TWO |
// |
`ifdef SDRAM_ACCESS |
`define SDRAM_SCOPE // Position two |
// `define SDRAM_SCOPE // Position two |
`endif |
// `define ENET_SCOPE |
// |
// SCOPE POSITION THREE |
// |
`ifdef ETHERNET_ACCESS |
`define ENET_SCOPE |
`endif |
// |
// |
module busmaster(i_clk, i_rst, |
// CNC |
i_rx_stb, i_rx_data, o_tx_stb, o_tx_data, i_tx_busy, |
119,6 → 126,10
i_ram_dbg, |
// The SD Card |
o_sd_sck, o_sd_cmd, o_sd_data, i_sd_cmd, i_sd_data, i_sd_detect, |
// Ethernet control (packets) lines |
o_net_reset_n, i_net_rx_clk, i_net_col, i_net_crs, i_net_dv, |
i_net_rxd, i_net_rxerr, |
i_net_tx_clk, o_net_tx_en, o_net_txd, |
// Ethernet control (MDIO) lines |
o_mdclk, o_mdio, o_mdwe, i_mdio, |
// OLED Control interface (roughly SPI) |
127,7 → 138,7
// The GPS PMod |
i_gps_pps, i_gps_3df |
); |
parameter ZA=24, ZIPINTS=14; |
parameter ZA=28, ZIPINTS=14, RESET_ADDRESS=28'h04e0000; |
input i_clk, i_rst; |
// The bus commander, via an external uart port |
input i_rx_stb; |
182,6 → 193,14
input i_sd_cmd; |
input [3:0] i_sd_data; |
input i_sd_detect; |
// Ethernet control |
output wire o_net_reset_n; |
input i_net_rx_clk, i_net_col, i_net_crs, i_net_dv; |
input [3:0] i_net_rxd; |
input i_net_rxerr; |
input i_net_tx_clk; |
output wire o_net_tx_en; |
output wire [3:0] o_net_txd; |
// Ethernet control (MDIO) |
output wire o_mdclk, o_mdio, o_mdwe; |
input i_mdio; |
226,6 → 245,9
// Oh, and the debug control for the ZIP CPU |
wire wbu_zip_sel, zip_dbg_ack, zip_dbg_stall; |
wire [31:0] zip_dbg_data; |
`ifdef WBU_SCOPE |
wire [31:0] wbu_debug; |
`endif |
wbubus genbus(i_clk, i_rx_stb, i_rx_data, |
wbu_cyc, wbu_stb, wbu_we, wbu_addr, wbu_data, |
(wbu_zip_sel)?zip_dbg_ack:wbu_ack, |
233,9 → 255,18
wbu_err, |
(wbu_zip_sel)?zip_dbg_data:wbu_idata, |
w_interrupt, |
o_tx_stb, o_tx_data, i_tx_busy); |
o_tx_stb, o_tx_data, i_tx_busy |
// , wbu_debug |
); |
|
`ifdef WBU_SCOPE |
// assign o_dbg = (wbu_ack)&&(wbu_cyc); |
assign wbu_debug = { wbu_cyc, wbu_stb, wbu_we, wbu_ack, wbu_stall, |
wbu_err, wbu_zip_sel, |
wbu_addr[8:0], |
wbu_data[7:0], |
wbu_idata[7:0] }; |
`endif |
|
wire zip_cpu_int; // True if the CPU suddenly halts |
`ifdef ZIPCPU |
264,7 → 295,7
gpsrx_int, rtc_pps |
}; |
|
zipsystem #( .RESET_ADDRESS(24'h0480000), |
zipsystem #( .RESET_ADDRESS(RESET_ADDRESS), |
.ADDRESS_WIDTH(ZA), |
.LGICACHE(10), |
.START_HALTED(1), |
280,13 → 311,13
((wbu_stb)&&(wbu_zip_sel)),wbu_we, wbu_addr[0], |
wbu_data, |
zip_dbg_ack, zip_dbg_stall, zip_dbg_data |
`ifdef CPU_DEBUG |
`ifdef CPU_SCOPE |
, zip_scope_data |
`endif |
); |
`else // ZIP_SYSTEM |
wire w_zip_cpu_int_ignored; |
zipbones #( .RESET_ADDRESS(24'h08000), |
zipbones #( .RESET_ADDRESS(RESET_ADDRESS), |
.ADDRESS_WIDTH(ZA), |
.LGICACHE(10), |
.START_HALTED(1), |
301,7 → 332,7
((wbu_stb)&&(wbu_zip_sel)),wbu_we, wbu_addr[0], |
wbu_data, |
zip_dbg_ack, zip_dbg_stall, zip_dbg_data |
`ifdef CPU_DEBUG |
`ifdef CPU_SCOPE |
, zip_scope_data |
`endif |
); |
328,7 → 359,7
zip_cyc, zip_stb, zip_we, zip_addr, zip_data, |
zip_ack, zip_stall, zip_err, |
// The UART interface Master |
(wbu_cyc)&&(~wbu_zip_sel), (wbu_stb)&&(~wbu_zip_sel), wbu_we, |
(wbu_cyc)&&(!wbu_zip_sel), (wbu_stb)&&(!wbu_zip_sel), wbu_we, |
wbu_addr, wbu_data, |
wbu_ack, wbu_stall, wbu_err, |
// Common bus returns |
423,26 → 454,24
// line. |
wire io_ack, oled_ack, |
rtc_ack, sdcard_ack, |
netp_ack, gps_ack, mio_ack, cfg_ack, netb_ack, |
net_ack, gps_ack, mio_ack, cfg_ack, |
mem_ack, flash_ack, ram_ack; |
reg many_ack, slow_many_ack; |
reg slow_ack, scop_ack; |
wire [5:0] ack_list; |
assign ack_list = { ram_ack, flash_ack, mem_ack, netb_ack, netp_ack, slow_ack }; |
wire [4:0] ack_list; |
assign ack_list = { ram_ack, flash_ack, mem_ack, net_ack, slow_ack }; |
initial many_ack = 1'b0; |
always @(posedge i_clk) |
many_ack <= ((ack_list != 6'h20) |
&&(ack_list != 6'h10) |
&&(ack_list != 6'h8) |
&&(ack_list != 6'h4) |
&&(ack_list != 6'h2) |
&&(ack_list != 6'h1) |
&&(ack_list != 6'h0)); |
many_ack <= ((ack_list != 5'h10) |
&&(ack_list != 5'h8) |
&&(ack_list != 5'h4) |
&&(ack_list != 5'h2) |
&&(ack_list != 5'h1) |
&&(ack_list != 5'h0)); |
/* |
assign many_ack = ( { 2'h0, ram_ack} |
+{2'h0, flash_ack } |
+{2'h0, mem_ack } |
+{2'h0, netb_ack } |
+{2'h0, slow_ack } > 3'h1 ); |
*/ |
|
471,7 → 500,7
// |
wire [31:0] io_data, oled_data, |
rtc_data, sdcard_data, |
netp_data, gps_data, mio_data, cfg_data, netb_data, |
net_data, gps_data, mio_data, cfg_data, |
mem_data, flash_data, ram_data; |
reg [31:0] slow_data, scop_data; |
|
479,10 → 508,10
always @(posedge i_clk) |
if ((ram_ack)||(flash_ack)) |
wb_idata <= (ram_ack)?ram_data:flash_data; |
else if ((mem_ack)||(netb_ack)) |
wb_idata <= (mem_ack)?mem_data:netb_data; |
else if ((mem_ack)||(net_ack)) |
wb_idata <= (mem_ack)?mem_data:net_data; |
else |
wb_idata <= (netp_ack)?netp_data: slow_data; |
wb_idata <= slow_data; |
|
// 7 control lines, 8x32 data lines |
always @(posedge i_clk) |
503,7 → 532,7
// |
wire io_stall, scop_stall, oled_stall, |
rtc_stall, sdcard_stall, |
netp_stall, gps_stall, mio_stall, cfg_stall, netb_stall, |
net_stall, gps_stall, mio_stall, cfg_stall, netb_stall, |
mem_stall, flash_stall, ram_stall, |
many_stall; |
assign wb_stall = (wb_cyc)&&( |
511,12 → 540,12
||((scop_sel)&&(scop_stall)) // Never stalls |
||((rtc_sel)&&(rtc_stall)) // Never stalls |
||((sdcard_sel)&&(sdcard_stall))// Never stalls |
||((netp_sel)&&(netp_stall)) |
||((netp_sel)&&(net_stall)) // Never stalls |
||((gps_sel)&&(gps_stall)) //(maybe? never stalls?) |
||((oled_sel)&&(oled_stall)) // Never stalls |
||((mio_sel)&&(mio_stall)) |
||((cfg_sel)&&(cfg_stall)) |
||((netb_sel)&&(netb_stall)) // Never stalls |
||((netb_sel)&&(net_stall)) // Never stalls |
||((mem_sel)&&(mem_stall)) // Never stalls |
||((flash_sel|flctl_sel)&&(flash_stall)) |
||((ram_sel)&&(ram_stall))); |
741,7 → 770,7
// |
`ifdef OLEDRGB_ACCESS |
wboled |
.#( .CBITS(4))// Div ck by 2^4=16, words take 200ns@81.25MHz |
#( .CBITS(4))// Div ck by 2^4=16, words take 200ns@81.25MHz |
rgbctrl(i_clk, |
wb_cyc, (wb_stb)&&(oled_sel), wb_we, |
wb_addr[1:0], wb_data, |
837,39 → 866,39
// ETHERNET DEVICE ACCESS |
// |
`ifdef ETHERNET_ACCESS |
reg r_mio_ack, r_netb_ack, r_netp_ack; |
always @(posedge i_clk) |
r_mio_ack <= (wb_stb)&&(mio_sel); |
always @(posedge i_clk) |
r_netp_ack <= (wb_stb)&&(netp_sel); |
assign mio_ack = r_mio_ack; |
assign netp_ack = r_netp_ack; |
`ifdef ENET_SCOPE |
wire [31:0] txnet_data; |
`endif |
|
assign mio_data = 32'h00; |
assign netp_data = 32'h00; |
assign mio_stall = 1'b0; |
assign netp_stall= 1'b0; |
assign enet_rx_int = 1'b0; |
assign enet_tx_int = 1'b0; |
enetpackets #(12) |
netctrl(i_clk, i_rst, wb_cyc,(wb_stb)&&((netp_sel)||(netb_sel)), |
wb_we, { (netb_sel), wb_addr[10:0] }, wb_data, |
net_ack, net_stall, net_data, |
o_net_reset_n, |
i_net_rx_clk, i_net_col, i_net_crs, i_net_dv, i_net_rxd, |
i_net_rxerr, |
i_net_tx_clk, o_net_tx_en, o_net_txd, |
enet_rx_int, enet_tx_int |
`ifdef ENET_SCOPE |
, txnet_data |
`endif |
); |
|
wire [31:0] mdio_debug; |
enetctrl #(2) |
mdio(i_clk, i_rst, wb_cyc, (wb_stb)&&(netb_sel), wb_we, |
wb_addr[4:0], wb_data[15:0], |
netb_ack, netb_stall, netb_data, |
o_mdclk, o_mdio, i_mdio, o_mdwe); |
mdio(i_clk, i_rst, wb_cyc, (wb_stb)&&(mio_sel), wb_we, |
wb_addr[4:0], wb_data[15:0], |
mio_ack, mio_stall, mio_data, |
o_mdclk, o_mdio, i_mdio, o_mdwe, |
mdio_debug); |
`else |
reg r_mio_ack, r_netb_ack, r_netp_ack; |
reg r_mio_ack; |
always @(posedge i_clk) |
r_mio_ack <= (wb_stb)&&(mio_sel); |
always @(posedge i_clk) |
r_netp_ack <= (wb_stb)&&(netp_sel); |
assign mio_ack = r_mio_ack; |
assign netp_ack = r_netp_ack; |
|
assign mio_data = 32'h00; |
assign netp_data = 32'h00; |
assign mio_stall = 1'b0; |
assign netp_stall= 1'b0; |
assign enet_rx_int = 1'b0; |
assign enet_tx_int = 1'b0; |
|
880,8 → 909,8
// consumes resources for us so we have an idea of what might be |
// available when we do have ETHERNET_ACCESS defined. |
// |
memdev #(11) enet_buffers(i_clk, wb_cyc, (wb_stb)&&(netb_sel), wb_we, |
wb_addr[10:0], wb_data, netb_ack, netb_stall, netb_data); |
memdev #(11) enet_buffers(i_clk, wb_cyc, (wb_stb)&&((netb_sel)||(netp_sel)), wb_we, |
wb_addr[10:0], wb_data, net_ack, net_stall, net_data); |
assign o_mdclk = 1'b1; |
assign o_mdio = 1'b1; |
assign o_mdwe = 1'b1; |
921,9 → 950,9
// FLASH MEMORY ACCESS |
// |
`ifdef FLASH_ACCESS |
`ifdef FLASH_SCOPE |
// `ifdef FLASH_SCOPE |
wire [31:0] flash_debug; |
`endif |
// `endif |
wire w_ignore_cmd_accepted; |
eqspiflash flashmem(i_clk, i_rst, |
wb_cyc,(wb_stb)&&(flash_sel),(wb_stb)&&(flctl_sel),wb_we, |
931,9 → 960,9
flash_ack, flash_stall, flash_data, |
o_qspi_sck, o_qspi_cs_n, o_qspi_mod, o_qspi_dat, i_qspi_dat, |
flash_int, w_ignore_cmd_accepted |
`ifdef FLASH_SCOPE |
// `ifdef FLASH_SCOPE |
, flash_debug |
`endif |
// `endif |
); |
`else |
assign o_qspi_sck = 1'b1; |
1028,15 → 1057,16
wire [31:0] scop_cpu_data; |
wire scop_cpu_ack, scop_cpu_stall, scop_cpu_interrupt; |
wire scop_cpu_trigger; |
// assign scop_cpu_trigger = zip_scope_data[30]; |
assign scop_cpu_trigger = (wb_stb)&&(mem_sel)&&(~wb_we) |
&&(wb_err)||(zip_scope_data[31]); |
wbscope #(5'd13) cpuscope(i_clk, 1'b1,(scop_cpu_trigger), zip_scope_data, |
// Wishbone interface |
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b00)), |
wb_we, wb_addr[0], wb_data, |
scop_cpu_ack, scop_cpu_stall, scop_cpu_data, |
scop_cpu_interrupt); |
assign scop_cpu_trigger = (zip_scope_data[31]); |
wbscope #( .LGMEM(5'd13), |
.DEFAULT_HOLDOFF(32)) |
cpuscope(i_clk, 1'b1,(scop_cpu_trigger),zip_scope_data, |
// Wishbone interface |
i_clk, wb_cyc, |
((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b00)), |
wb_we, wb_addr[0], wb_data, |
scop_cpu_ack, scop_cpu_stall, scop_cpu_data, |
scop_cpu_interrupt); |
|
assign scop_a_data = scop_cpu_data; |
assign scop_a_ack = scop_cpu_ack; |
1047,9 → 1077,8
wire [31:0] scop_flash_data; |
wire scop_flash_ack, scop_flash_stall, scop_flash_interrupt; |
wire scop_flash_trigger; |
// assign scop_cpu_trigger = zip_scope_data[30]; |
assign scop_flash_trigger = (wb_stb)&&((flash_sel)||(flctl_sel)); |
wbscope #(5'd13) flashscope(i_clk, 1'b1, |
wbscope #(5'd11) flashscope(i_clk, 1'b1, |
(scop_flash_trigger), flash_debug, |
// Wishbone interface |
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b00)), |
1120,6 → 1149,22
assign scop_b_ack = scop_cfg_ack; |
assign scop_b_interrupt = scop_cfg_interrupt; |
`else |
`ifdef WBU_SCOPE |
wire [31:0] scop_wbu_data; |
wire scop_wbu_ack, scop_wbu_stall, scop_wbu_interrupt; |
wbscope #(5'd10,32,1) wbuscope(i_clk, 1'b1, (flash_sel)&&(wb_stb), |
wbu_debug, |
// Wishbone interface |
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b01)), |
wb_we, wb_addr[0], wb_data, |
scop_wbu_ack, scop_wbu_stall, scop_wbu_data, |
scop_wbu_interrupt); |
|
assign scop_b_data = scop_wbu_data; |
assign scop_b_stall = scop_wbu_stall; |
assign scop_b_ack = scop_wbu_ack; |
assign scop_b_interrupt = scop_wbu_interrupt; |
`else |
assign scop_b_data = 32'h00; |
assign scop_b_stall = 1'b0; |
assign scop_b_interrupt = 1'b0; |
1130,6 → 1175,7
assign scop_b_ack = r_scop_b_ack; |
`endif |
`endif |
`endif |
|
// |
// SCOPE C |
1145,7 → 1191,7
assign sdram_trigger = (ram_sel)&&(wb_stb); |
assign sdram_debug= i_ram_dbg; |
|
wbscope #(5'd10,32,1) ramscope(i_clk, 1'b1, sdram_trigger, sdram_debug, |
wbscope #(5'd9,32,1) ramscope(i_clk, 1'b1, sdram_trigger, sdram_debug, |
// Wishbone interface |
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b10)), |
wb_we, wb_addr[0], wb_data, |
1173,7 → 1219,37
wire [31:0] scop_d_data; |
wire scop_d_ack, scop_d_stall, scop_d_interrupt; |
// |
//`else |
`ifdef ENET_SCOPE |
wire [31:0] scop_net_data; |
wire scop_net_ack, scop_net_stall, scop_net_interrupt; |
|
/* |
wbscope #(5'd8,32,1) |
net_scope(i_clk, 1'b1, !mdio_debug[1], mdio_debug, |
// Wishbone interface |
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b11)), |
wb_we, wb_addr[0], wb_data, |
scop_net_ack, scop_net_stall, scop_net_data, |
scop_net_interrupt); |
*/ |
|
// 5'd8 is sufficient for small packets, and indeed the minimum for |
// watching any packets--as the minimum packet size is 64 bytes, or |
// 128 nibbles. |
wbscope #(5'd9,32,0) |
net_scope(i_net_rx_clk, 1'b1, txnet_data[31], txnet_data, |
// Wishbone interface |
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b11)), |
wb_we, wb_addr[0], wb_data, |
scop_net_ack, scop_net_stall, scop_net_data, |
scop_net_interrupt); |
|
assign scop_d_ack = scop_net_ack; |
assign scop_d_stall = scop_net_stall; |
assign scop_d_data = scop_net_data; |
assign scop_d_interrupt = scop_net_interrupt; |
|
`else |
assign scop_d_data = 32'h00; |
assign scop_d_stall = 1'b0; |
assign scop_d_interrupt = 1'b0; |
1182,7 → 1258,7
always @(posedge i_clk) |
r_scop_d_ack <= (wb_stb)&&(scop_sel)&&(wb_addr[2:1] == 2'b11); |
assign scop_d_ack = r_scop_d_ack; |
//`endif |
`endif |
|
reg all_scope_interrupts; |
always @(posedge i_clk) |
/trunk/rtl/cpu/busdelay.v
1,20 → 1,41
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: busdelay.v |
// |
// Project: Zip CPU -- a small, lightweight, RISC CPU soft core |
// |
// Purpose: Delay any access to the wishbone bus by a single clock. This |
// particular version of the busdelay builds off of some previous |
// work, but also delays and buffers the stall line as well. It is |
// designed to allow pipelined accesses (1 access/clock) to still work, |
// while also providing for single accesses. |
// Purpose: Delay any access to the wishbone bus by a single clock. |
// |
// When the first Zip System would not meet the timing requirements of |
// the board it was placed upon, this bus delay was added to help out. |
// It may no longer be necessary, having cleaned some other problems up |
// first, but it will remain here as a means of alleviating timing |
// problems. |
// |
// The specific problem takes place on the stall line: a wishbone master |
// *must* know on the first clock whether or not the bus will stall. |
// |
// |
// After a period of time, I started a new design where the timing |
// associated with this original bus clock just wasn't ... fast enough. |
// I needed to delay the stall line as well. A new busdelay was then |
// written and debugged whcih delays the stall line. (I know, you aren't |
// supposed to delay the stall line--but what if you *have* to in order |
// to meet timing?) This new logic has been merged in with the old, |
// and the DELAY_STALL line can be set to non-zero to use it instead |
// of the original logic. Don't use it if you don't need it: it will |
// consume resources and slow your bus down more, but if you do need |
// it--don't be afraid to use it. |
// |
// Both versions of the bus delay will maintain a single access per |
// clock when pipelined, they only delay the time between the strobe |
// going high and the actual command being accomplished. |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
32,7 → 53,7
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
module busdelay(i_clk, |
// The input bus |
41,7 → 62,7
// The delayed bus |
o_dly_cyc, o_dly_stb, o_dly_we, o_dly_addr, o_dly_data, |
i_dly_ack, i_dly_stall, i_dly_data, i_dly_err); |
parameter AW=32, DW=32; |
parameter AW=32, DW=32, DELAY_STALL = 0; |
input i_clk; |
// Input/master bus |
input i_wb_cyc, i_wb_stb, i_wb_we; |
48,12 → 69,11
input [(AW-1):0] i_wb_addr; |
input [(DW-1):0] i_wb_data; |
output reg o_wb_ack; |
output reg o_wb_stall; |
output wire o_wb_stall; |
output reg [(DW-1):0] o_wb_data; |
output reg o_wb_err; |
output wire o_wb_err; |
// Delayed bus |
output reg o_dly_cyc, o_dly_we; |
output wire o_dly_stb; |
output reg o_dly_cyc, o_dly_stb, o_dly_we; |
output reg [(AW-1):0] o_dly_addr; |
output reg [(DW-1):0] o_dly_data; |
input i_dly_ack; |
61,36 → 81,100
input [(DW-1):0] i_dly_data; |
input i_dly_err; |
|
reg loaded; |
initial o_dly_cyc = 1'b0; |
initial loaded = 1'b0; |
generate |
if (DELAY_STALL != 0) |
begin |
reg r_stb, r_we, r_rtn_stall, r_rtn_err; |
reg [(DW-1):0] r_data; |
reg [(AW-1):0] r_addr; |
|
always @(posedge i_clk) |
o_wb_stall <= (loaded)&&(i_dly_stall); |
initial o_dly_cyc = 1'b0; |
initial r_rtn_stall= 1'b0; |
initial r_stb = 1'b0; |
always @(posedge i_clk) |
begin |
o_dly_cyc <= (i_wb_cyc); |
|
if (!i_dly_stall) |
begin |
r_we <= i_wb_we; |
r_addr <= i_wb_addr; |
r_data <= i_wb_data; |
|
initial o_dly_cyc = 1'b0; |
always @(posedge i_clk) |
o_dly_cyc <= (i_wb_cyc); |
// Add the i_wb_cyc criteria here, so we can simplify the o_wb_stall |
// criteria below, which would otherwise *and* these two. |
always @(posedge i_clk) |
loaded <= (i_wb_stb)||((loaded)&&(i_dly_stall)&&(~i_dly_err)&&(i_wb_cyc)); |
assign o_dly_stb = loaded; |
always @(posedge i_clk) |
if (~i_dly_stall) |
o_dly_we <= i_wb_we; |
always @(posedge i_clk) |
if (~i_dly_stall) |
o_dly_addr<= i_wb_addr; |
always @(posedge i_clk) |
if (~i_dly_stall) |
o_dly_data <= i_wb_data; |
always @(posedge i_clk) |
o_wb_ack <= (i_dly_ack)&&(o_dly_cyc)&&(i_wb_cyc); |
always @(posedge i_clk) |
o_wb_data <= i_dly_data; |
if (r_stb) |
begin |
o_dly_we <= r_we; |
o_dly_addr <= r_addr; |
o_dly_data <= r_data; |
o_dly_stb <= 1'b1; |
r_rtn_stall <= 1'b0; |
r_stb <= 1'b0; |
end else begin |
o_dly_we <= i_wb_we; |
o_dly_addr <= i_wb_addr; |
o_dly_data <= i_wb_data; |
o_dly_stb <= i_wb_stb; |
r_stb <= 1'b0; |
r_rtn_stall <= 1'b0; |
end |
end else if ((!r_stb)&&(!o_wb_stall)) |
begin |
r_we <= i_wb_we; |
r_addr <= i_wb_addr; |
r_data <= i_wb_data; |
r_stb <= i_wb_stb; |
|
always @(posedge i_clk) |
o_wb_err <= (i_dly_err)&&(o_dly_cyc)&&(i_wb_cyc); |
r_rtn_stall <= i_wb_stb; |
end |
|
if (!i_wb_cyc) |
begin |
o_dly_stb <= 1'b0; |
r_stb <= 1'b0; |
r_rtn_stall <= 1'b0; |
end |
|
o_wb_ack <= (i_dly_ack)&&(i_wb_cyc)&&(o_dly_cyc); |
o_wb_data <= i_dly_data; |
r_rtn_err <= (i_dly_err)&&(i_wb_cyc)&&(o_dly_cyc); |
end |
|
assign o_wb_stall = r_rtn_stall; |
assign o_wb_err = r_rtn_err; |
|
end else begin |
|
initial o_dly_cyc = 1'b0; |
initial o_dly_stb = 1'b0; |
|
always @(posedge i_clk) |
o_dly_cyc <= i_wb_cyc; |
// Add the i_wb_cyc criteria here, so we can simplify the |
// o_wb_stall criteria below, which would otherwise *and* |
// these two. |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_stb <= ((i_wb_cyc)&&(i_wb_stb)); |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_we <= i_wb_we; |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_addr<= i_wb_addr; |
always @(posedge i_clk) |
if (~o_wb_stall) |
o_dly_data <= i_wb_data; |
always @(posedge i_clk) |
o_wb_ack <= (i_dly_ack)&&(o_dly_cyc)&&(i_wb_cyc); |
always @(posedge i_clk) |
o_wb_data <= i_dly_data; |
|
// Our only non-delayed line, yet still really delayed. Perhaps |
// there's a way to register this? |
// o_wb_stall <= (i_wb_cyc)&&(i_wb_stb) ... or some such? |
// assign o_wb_stall=((i_wb_cyc)&&(i_dly_stall)&&(o_dly_stb));//&&o_cyc |
assign o_wb_stall = ((i_dly_stall)&&(o_dly_stb));//&&o_cyc |
assign o_wb_err = i_dly_err; |
end endgenerate |
|
endmodule |
/trunk/rtl/cpu/cpudefs.v
97,7 → 97,7
// mode. |
// |
// |
// `define OPT_DIVIDE |
`define OPT_DIVIDE |
// |
// |
// |
273,6 → 273,6
`define INCLUDE_ACCOUNTING_COUNTERS |
// |
// |
// `define DEBUG_SCOPE |
`define DEBUG_SCOPE |
// |
`endif // CPUDEFS_H |
/trunk/rtl/cpu/zipcpu.v
7,7 → 7,9
// Purpose: This is the top level module holding the core of the Zip CPU |
// together. The Zip CPU is designed to be as simple as possible. |
// (actual implementation aside ...) The instruction set is about as |
// RISC as you can get, there are only 16 instruction types supported. |
// RISC as you can get, with only 26 instruction types currently supported. |
// (There are still 8-instruction Op-Codes reserved for floating point, |
// and 5 which can be used for transactions not requiring registers.) |
// Please see the accompanying spec.pdf file for a description of these |
// instructions. |
// |
26,10 → 28,11
// |
// 4. Write-back Results |
// |
// Further information about the inner workings of this CPU may be |
// found in the spec.pdf file. (The documentation within this file |
// had become out of date and out of sync with the spec.pdf, so look |
// to the spec.pdf for accurate and up to date information.) |
// Further information about the inner workings of this CPU, such as |
// what causes pipeline stalls, may be found in the spec.pdf file. (The |
// documentation within this file had become out of date and out of sync |
// with the spec.pdf, so look to the spec.pdf for accurate and up to date |
// information.) |
// |
// |
// In general, the pipelining is controlled by three pieces of logic |
103,8 → 106,8
// |
`define CPU_CC_REG 4'he |
`define CPU_PC_REG 4'hf |
`define CPU_CLRCACHE_BIT 14 // Floating point error flag, set on error |
`define CPU_PHASE_BIT 13 // Floating point error flag, set on error |
`define CPU_CLRCACHE_BIT 14 // Set to clear the I-cache, automatically clears |
`define CPU_PHASE_BIT 13 // Set if we are executing the latter half of a VLIW |
`define CPU_FPUERR_BIT 12 // Floating point error flag, set on error |
`define CPU_DIVERR_BIT 11 // Divide error flag, set on divide by zero |
`define CPU_BUSERR_BIT 10 // Bus error flag, set on error |
206,8 → 209,8
// (BUS, TRAP,ILL,BREAKEN,STEP,GIE,SLEEP ), V, N, C, Z |
reg [3:0] flags, iflags; |
wire [14:0] w_uflags, w_iflags; |
reg trap, break_en, step, gie, sleep, r_halted, |
break_pending; |
reg trap, break_en, step, gie, sleep, r_halted; |
wire break_pending; |
wire w_clear_icache; |
`ifdef OPT_ILLEGAL_INSTRUCTION |
reg ill_err_u, ill_err_i; |
279,13 → 282,14
// |
// Now, let's read our operands |
reg [4:0] alu_reg; |
reg [3:0] opn; |
reg [4:0] opR; |
wire [3:0] opn; |
wire [4:0] opR; |
reg [31:0] r_opA, r_opB; |
reg [(AW-1):0] op_pc; |
wire [31:0] w_opA, w_opB; |
wire [31:0] opA_nowait, opB_nowait, opA, opB; |
reg opR_wr, opR_cc, opF_wr, op_gie; |
reg opR_wr, opF_wr; |
wire op_gie, opR_cc; |
wire [14:0] opFl; |
reg [5:0] r_opF; |
wire [7:0] opF; |
301,7 → 305,7
wire op_illegal; |
assign op_illegal = 1'b0; |
`endif |
reg op_break; |
wire op_break; |
wire op_lock; |
|
|
311,7 → 315,7
// Variable declarations |
// |
// |
reg [(AW-1):0] alu_pc; |
wire [(AW-1):0] alu_pc; |
reg r_alu_pc_valid, mem_pc_valid; |
wire alu_pc_valid; |
wire alu_phase; |
320,9 → 324,8
wire [3:0] alu_flags; |
wire alu_valid, alu_busy; |
wire set_cond; |
reg alu_wr, alF_wr, alu_gie; |
wire alu_illegal_op; |
wire alu_illegal; |
reg alu_wr, alF_wr; |
wire alu_gie, alu_illegal_op, alu_illegal; |
|
|
|
473,7 → 476,7
`ifdef OPT_PIPELINED |
assign alu_stall = (((~master_ce)||(mem_rdbusy)||(alu_busy))&&(opvalid_alu)) //Case 1&2 |
||((opvalid)&&(op_lock)&&(op_lock_stall)) |
||((opvalid)&&(op_break)) |
||((opvalid)&&(op_break)) // || op_illegal |
||(wr_reg_ce)&&(wr_write_cc) |
||(div_busy)||(fpu_busy); |
assign alu_ce = (master_ce)&&(opvalid_alu)&&(~alu_stall) |
744,14 → 747,19
`endif |
|
always @(posedge i_clk) |
`ifdef OPT_PIPELINED |
if (op_change_data_ce) |
`endif |
begin |
`ifdef OPT_PIPELINED |
if ((wr_reg_ce)&&(wr_reg_id == dcdA)) |
r_opA <= wr_gpreg_vl; |
else if (dcdA_pc) |
else |
`endif |
if (dcdA_pc) |
r_opA <= w_pcA_v; |
else if (dcdA_cc) |
r_opA <= { w_cpu_info, w_opA[22:15], (dcdA[4])?w_uflags:w_iflags }; |
r_opA <= { w_cpu_info, w_opA[22:16], 1'b0, (dcdA[4])?w_uflags:w_iflags }; |
else |
r_opA <= w_opA; |
`ifdef OPT_PIPELINED |
775,18 → 783,22
endgenerate |
|
assign w_opBnI = (~dcdB_rd) ? 32'h00 |
: (((wr_reg_ce)&&(wr_reg_id == dcdB)) ? wr_gpreg_vl |
`ifdef OPT_PIPELINED |
: ((wr_reg_ce)&&(wr_reg_id == dcdB)) ? wr_gpreg_vl |
`endif |
: ((dcdB_pc) ? w_pcB_v |
: ((dcdB_cc) ? { w_cpu_info, w_opB[22:15], // w_opB[31:14], |
(dcdB[4])?w_uflags:w_iflags} |
: w_opB))); |
: ((dcdB_cc) ? { w_cpu_info, w_opB[22:16], // w_opB[31:14], |
1'b0, (dcdB[4])?w_uflags:w_iflags} |
: w_opB)); |
|
always @(posedge i_clk) |
`ifdef OPT_PIPELINED |
if (op_change_data_ce) |
r_opB <= w_opBnI + dcdI; |
`ifdef OPT_PIPELINED |
else if ((wr_reg_ce)&&(opB_id == wr_reg_id)&&(opB_rd)) |
r_opB <= wr_gpreg_vl; |
`else |
r_opB <= w_opBnI + dcdI; |
`endif |
|
// The logic here has become more complex than it should be, no thanks |
799,9 → 811,11
// below, arriving at what we finally want in the (now wire net) |
// opF. |
always @(posedge i_clk) |
`ifdef OPT_PIPELINED |
if (op_ce) // Cannot do op_change_data_ce here since opF depends |
// upon being either correct for a valid op, or correct |
// for the last valid op |
`endif |
begin // Set the flag condition codes, bit order is [3:0]=VNCZ |
case(dcdF[2:0]) |
3'h0: r_opF <= 6'h00; // Always |
836,7 → 850,7
initial opvalid_div = 1'b0; |
initial opvalid_fpu = 1'b0; |
always @(posedge i_clk) |
if (i_rst) |
if ((i_rst)||(clear_pipeline)) |
begin |
opvalid <= 1'b0; |
opvalid_alu <= 1'b0; |
865,7 → 879,7
opvalid_div <= (dcdDV)&&(w_opvalid); |
opvalid_fpu <= (dcdFP)&&(w_opvalid); |
`endif |
end else if ((clear_pipeline)||(adf_ce_unconditional)||(mem_ce)) |
end else if ((adf_ce_unconditional)||(mem_ce)) |
begin |
opvalid <= 1'b0; |
opvalid_alu <= 1'b0; |
883,12 → 897,19
// to be, step through it, and then replace it back. In this fashion, |
// a debugger can step through code. |
// assign w_op_break = (dcd_break)&&(r_dcdI[15:0] == 16'h0001); |
initial op_break = 1'b0; |
`ifdef OPT_PIPELINED |
reg r_op_break; |
|
initial r_op_break = 1'b0; |
always @(posedge i_clk) |
if (i_rst) op_break <= 1'b0; |
else if (op_ce) op_break <= (dcd_break); // &&(dcdvalid) |
if (i_rst) r_op_break <= 1'b0; |
else if (op_ce) r_op_break <= (dcd_break); //||dcd_illegal &&(dcdvalid) |
else if ((clear_pipeline)||(~opvalid)) |
op_break <= 1'b0; |
r_op_break <= 1'b0; |
assign op_break = r_op_break; |
`else |
assign op_break = dcd_break; |
`endif |
|
`ifdef OPT_PIPELINED |
generate |
935,13 → 956,14
`else |
op_illegal <= (dcdvalid)&&((dcd_illegal)||(dcd_lock)); |
`endif |
`endif |
else if(alu_ce) |
op_illegal <= 1'b0; |
`endif |
|
// No generate on EARLY_BRANCHING here, since if EARLY_BRANCHING is not |
// set, dcd_early_branch will simply be a wire connected to zero and |
// this logic should just optimize. |
`ifdef OPT_PIPELINED |
always @(posedge i_clk) |
if (op_ce) |
begin |
949,22 → 971,47
&&(~dcd_early_branch)&&(~dcd_illegal); |
opR_wr <= (dcdR_wr)&&(~dcd_early_branch)&&(~dcd_illegal); |
end |
`else |
always @(posedge i_clk) |
begin |
opF_wr <= (dcdF_wr)&&((~dcdR_cc)||(~dcdR_wr)) |
&&(~dcd_early_branch)&&(~dcd_illegal); |
opR_wr <= (dcdR_wr)&&(~dcd_early_branch)&&(~dcd_illegal); |
end |
`endif |
|
`ifdef OPT_PIPELINED |
reg [3:0] r_opn; |
reg [4:0] r_opR; |
reg r_opR_cc; |
reg r_op_gie; |
always @(posedge i_clk) |
if (op_change_data_ce) |
begin |
opn <= dcdOp; // Which ALU operation? |
r_opn <= dcdOp; // Which ALU operation? |
// opM <= dcdM; // Is this a memory operation? |
// What register will these results be written into? |
opR <= dcdR; |
opR_cc <= (dcdR_cc)&&(dcdR_wr)&&(dcdR[4]==dcd_gie); |
r_opR <= dcdR; |
r_opR_cc <= (dcdR_cc)&&(dcdR_wr)&&(dcdR[4]==dcd_gie); |
// User level (1), vs supervisor (0)/interrupts disabled |
op_gie <= dcd_gie; |
r_op_gie <= dcd_gie; |
|
|
// |
op_pc <= (dcd_early_branch)?dcd_branch_pc:dcd_pc; |
end |
assign opn = r_opn; |
assign opR = r_opR; |
assign op_gie = r_op_gie; |
assign opR_cc = r_opR_cc; |
`else |
assign opn = dcdOp; |
assign opR = dcdR; |
assign op_gie = dcd_gie; |
// With no pipelining, there is no early branching. We keep it |
always @(posedge i_clk) |
op_pc <= (dcd_early_branch)?dcd_branch_pc:dcd_pc; |
`endif |
assign opFl = (op_gie)?(w_uflags):(w_iflags); |
|
`ifdef OPT_VLIW |
1166,11 → 1213,19
assign alu_phase = 1'b0; |
`endif |
|
`ifdef OPT_PIPELINED |
always @(posedge i_clk) |
if (adf_ce_unconditional) |
alu_reg <= opR; |
else if ((i_halt)&&(i_dbg_we)) |
alu_reg <= i_dbg_reg; |
`else |
always @(posedge i_clk) |
if ((i_halt)&&(i_dbg_we)) |
alu_reg <= i_dbg_reg; |
else |
alu_reg <= opR; |
`endif |
|
// |
// DEBUG Register write access starts here |
1182,14 → 1237,25
reg [31:0] dbg_val; |
always @(posedge i_clk) |
dbg_val <= i_dbg_data; |
`ifdef OPT_PIPELINED |
reg r_alu_gie; |
|
always @(posedge i_clk) |
if ((adf_ce_unconditional)||(mem_ce)) |
alu_gie <= op_gie; |
r_alu_gie <= op_gie; |
assign alu_gie = r_alu_gie; |
|
reg [(AW-1):0] r_alu_pc; |
always @(posedge i_clk) |
if ((adf_ce_unconditional) |
||((master_ce)&&(opvalid_mem)&&(~clear_pipeline) |
&&(~mem_stalled))) |
alu_pc <= op_pc; |
r_alu_pc <= op_pc; |
assign alu_pc = r_alu_pc; |
`else |
assign alu_gie = op_gie; |
assign alu_pc = op_pc; |
`endif |
|
`ifdef OPT_ILLEGAL_INSTRUCTION |
reg r_alu_illegal; |
1395,14 → 1461,21
else if ((wr_reg_ce)&&(wr_write_scc)) |
break_en <= wr_spreg_vl[`CPU_BREAK_BIT]; |
|
initial break_pending = 1'b0; |
`ifdef OPT_PIPELINED |
reg r_break_pending; |
|
initial r_break_pending = 1'b0; |
always @(posedge i_clk) |
if ((i_rst)||(clear_pipeline)||(~opvalid)) |
break_pending <= 1'b0; |
r_break_pending <= 1'b0; |
else if (op_break) |
break_pending <= (~alu_busy)&&(~div_busy)&&(~fpu_busy)&&(~mem_busy); |
r_break_pending <= (~alu_busy)&&(~div_busy)&&(~fpu_busy)&&(~mem_busy); |
else |
break_pending <= 1'b0; |
r_break_pending <= 1'b0; |
assign break_pending = r_break_pending; |
`else |
assign break_pending = op_break; |
`endif |
|
|
assign o_break = ((break_en)||(~op_gie))&&(break_pending) |
1737,6 → 1810,7
else if (i_dbg_reg[3:0] == `CPU_CC_REG) |
begin |
o_dbg_reg[14:0] <= (i_dbg_reg[4])?w_uflags:w_iflags; |
o_dbg_reg[15] <= 1'b0; |
o_dbg_reg[31:23] <= w_cpu_info; |
o_dbg_reg[`CPU_GIE_BIT] <= gie; |
end |
1750,6 → 1824,7
else if (i_dbg_reg[3:0] == `CPU_CC_REG) |
begin |
o_dbg_reg[14:0] <= (i_dbg_reg[4])?w_uflags:w_iflags; |
o_dbg_reg[15] <= 1'b0; |
o_dbg_reg[31:23] <= w_cpu_info; |
o_dbg_reg[`CPU_GIE_BIT] <= gie; |
end |
1759,6 → 1834,7
always @(posedge i_clk) |
o_dbg_cc <= { o_break, bus_err, gie, sleep }; |
|
`ifdef OPT_PIPELINED |
always @(posedge i_clk) |
r_halted <= (i_halt)&&( |
// To be halted, any long lasting instruction must |
1769,6 → 1845,10
&&((opvalid)||(i_rst)||(dcd_illegal)) |
// Decode stage must be either valid, in reset, or ill |
&&((dcdvalid)||(i_rst)||(pf_illegal))); |
`else |
always @(posedge i_clk) |
r_halted <= (i_halt)&&((opvalid)||(i_rst)); |
`endif |
assign o_dbg_stall = ~r_halted; |
|
// |
1782,85 → 1862,41
assign o_i_count = (alu_pc_valid)&&(~clear_pipeline); |
|
`ifdef DEBUG_SCOPE |
reg [31:0] r_stack; |
// CLRPIP: If clear_pipeline, produce address ... can be 28 bits |
// DATWR: If write value, produce 4-bits of register ID, 27 bits of value |
// STALL: If neither, produce pipeline stall information |
// ADDR: If bus is valid, no ack, return the bus address |
reg debug_trigger; |
initial debug_trigger = 1'b0; |
always @(posedge i_clk) |
if ((wr_reg_ce)&&(wr_reg_id == 5'h0d)) |
r_stack <= wr_gpreg_vl; |
reg r_stack_pre, r_stack_post; |
always @(posedge i_clk) |
r_stack_pre <= (r_stack == 32'h03fff); |
always @(posedge i_clk) |
r_stack_post <= (r_stack == 32'h03eeb); |
debug_trigger <= (!i_halt)&&(o_break); |
|
wire [31:0] debug_flags; |
assign debug_flags = { debug_trigger, 3'b101, |
master_ce, i_halt, o_break, sleep, |
gie, ibus_err_flag, trap, ill_err_i, |
r_clear_icache, pf_valid, pf_illegal, dcd_ce, |
dcdvalid, dcd_stalled, op_ce, opvalid, |
op_pipe, alu_ce, alu_busy, alu_wr, |
alu_illegal, alF_wr, mem_ce, mem_we, |
mem_busy, mem_pipe_stalled, (new_pc), (dcd_early_branch) }; |
|
always @(posedge i_clk) |
o_debug <= { |
/* |
o_break, i_wb_err, pf_pc[1:0], |
flags, |
pf_valid, dcdvalid, opvalid, alu_valid, mem_valid, |
op_ce, alu_ce, mem_ce, |
// |
master_ce, opvalid_alu, opvalid_mem, |
// |
alu_stall, mem_busy, op_pipe, mem_pipe_stalled, |
mem_we, |
// ((opvalid_alu)&&(alu_stall)) |
// ||((opvalid_mem)&&(~op_pipe)&&(mem_busy)) |
// ||((opvalid_mem)&&( op_pipe)&&(mem_pipe_stalled))); |
// opA[23:20], opA[3:0], |
gie, sleep, wr_reg_ce, wr_gpreg_vl[4:0] |
*/ |
/* |
i_rst, master_ce, (new_pc), |
((dcd_early_branch)&&(dcdvalid)), |
pf_valid, pf_illegal, |
op_ce, dcd_ce, dcdvalid, dcd_stalled, |
pf_cyc, pf_stb, pf_we, pf_ack, pf_stall, pf_err, |
pf_pc[7:0], pf_addr[7:0] |
*/ |
|
(i_wb_err)||(r_stack_post), (gie)||(r_stack_pre), (alu_illegal)||(r_stack_post), |
(new_pc)||((dcd_early_branch)&&(~clear_pipeline)), |
mem_busy, |
(mem_busy)?{ (o_wb_gbl_stb|o_wb_lcl_stb), o_wb_we, |
o_wb_addr[8:0] } |
: { instruction[31:21] }, |
pf_valid, (pf_valid) ? alu_pc[14:0] |
:{ pf_cyc, pf_stb, pf_pc[12:0] } |
|
/* |
i_wb_err, gie, new_pc, dcd_early_branch, // 4 |
pf_valid, pf_cyc, pf_stb, instruction_pc[0], // 4 |
instruction[30:27], // 4 |
dcd_gie, mem_busy, o_wb_gbl_cyc, o_wb_gbl_stb, // 4 |
dcdvalid, |
((dcd_early_branch)&&(~clear_pipeline)) // 15 |
? dcd_branch_pc[14:0]:pf_pc[14:0] |
*/ |
}; |
begin |
if ((i_halt)||(!master_ce)||(debug_trigger)||(o_break)) |
o_debug <= debug_flags; |
else if ((mem_valid)||((~clear_pipeline)&&(~alu_illegal) |
&&(((alu_wr)&&(alu_valid)) |
||(div_valid)||(fpu_valid)))) |
o_debug <= { debug_trigger, 1'b0, wr_reg_id[3:0], wr_gpreg_vl[25:0]}; |
else if (clear_pipeline) |
o_debug <= { debug_trigger, 3'b100, pf_pc[27:0] }; |
else if ((o_wb_gbl_stb)|(o_wb_lcl_stb)) |
o_debug <= {debug_trigger, 2'b11, o_wb_gbl_stb, o_wb_we, |
(o_wb_we)?o_wb_data[26:0] : o_wb_addr[26:0] }; |
else |
o_debug <= debug_flags; |
end |
`endif |
|
/* |
always @(posedge i_clk) |
o_debug <= { |
// External control interaction (4b) |
i_halt, i_rst, i_clear_cache, o_break, |
// Bus interaction (8b) |
pf_cyc,(o_wb_gbl_cyc|o_wb_lcl_cyc), o_wb_gbl_stb, o_wb_lcl_stb, |
o_wb_we, i_wb_ack, i_wb_stall, i_wb_err, |
// PC control (4b) |
gie, new_pc, dcd_early_branch, 1'b0, |
// Our list of pipeline stage values (8b) |
pf_valid, pf_illegal, dcdvalid, opvalid, alu_valid, mem_valid, |
alu_pc_valid, mem_pc_valid, |
// Our list of circuit enables ... (8b) |
(new_pc)||((dcd_early_branch)&&(~clear_pipeline)), |
dcd_ce, op_ce, alu_ce, mem_ce, wr_reg_ce, wr_flags_ce, |
1'b0, |
// Useful PC values (64b) |
((dcd_early_branch)&&(~clear_pipeline)) |
? dcd_branch_pc[15:0]:pf_pc[15:0], |
(gie)?upc[15:0]:ipc[15:0], instruction_pc[15:0], instruction[31:16] }; |
*/ |
|
endmodule |
/trunk/rtl/enetctrl.v
47,7 → 47,8
module enetctrl(i_clk, i_rst, |
i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, |
o_wb_ack, o_wb_stall, o_wb_data, |
o_mdclk, o_mdio, i_mdio, o_mdwe); |
o_mdclk, o_mdio, i_mdio, o_mdwe, |
o_debug); |
parameter CLKBITS=3; // = 3 for 200MHz source clock, 2 for 100 MHz |
input i_clk, i_rst; |
input i_wb_cyc, i_wb_stb, i_wb_we; |
60,6 → 61,8
output wire o_mdclk; |
output reg o_mdio, o_mdwe; |
// |
output wire [31:0] o_debug; |
// |
parameter PHYADDR = 5'h01; |
|
|
83,7 → 86,7
reg rclk, zclk; |
initial zclk = 0; |
always @(posedge i_clk) |
zclk <= &clk_counter; |
zclk <= (&clk_counter[(CLKBITS-1):1])&&(!clk_counter[0]); |
initial rclk = 0; |
always @(posedge i_clk) |
rclk <= (~clk_counter[(CLKBITS-1)])&&(&clk_counter[(CLKBITS-2):0]); |
90,6 → 93,7
|
// Step 3: Read from our input port |
// Note: I read on the falling edge, he changes on the rising edge |
reg in_idle; |
always @(posedge i_clk) |
if (zclk) |
read_reg <= { read_reg[14:0], i_mdio }; |
107,7 → 111,6
if (zclk) |
o_mdio <= write_reg[15]; |
|
reg in_idle; |
initial in_idle = 1'b0; |
always @(posedge i_clk) |
in_idle <= (ctrl_state == `ECTRL_IDLE); |
145,7 → 148,7
always @(posedge i_clk) |
begin |
o_wb_ack <= 1'b0; |
if ((zclk)&&(~zreg_pos)) |
if ((zclk)&&(!zreg_pos)) |
reg_pos <= reg_pos - 1; |
if (zclk) |
write_reg <= { write_reg[14:0], 1'b1 }; |
165,12 → 168,16
o_mdwe <= 1'b1; // Write |
write_reg <= { 4'he, PHYADDR, r_addr, 2'b11 }; |
if (write_pending) |
begin |
write_reg[15:12] <= { 4'h5 }; |
else if (read_pending) |
write_reg[0] <= 1'b0; |
end else if (read_pending) |
write_reg[15:12] <= { 4'h6 }; |
if (read_pending || write_pending) |
if (!zclk) |
write_reg[15] <= 1'b1; |
reg_pos <= 6'h0f; |
if ((zclk)&&(read_pending || write_pending)) |
begin |
reg_pos <= 6'h0f; |
ctrl_state <= `ECTRL_ADDRESS; |
end end |
`ECTRL_ADDRESS: begin |
206,4 → 213,12
endcase |
end |
|
assign o_debug = { |
o_wb_stall,i_wb_stb,i_wb_we, i_wb_addr, // 8 bits |
o_wb_ack, rclk, o_wb_data[5:0], // 8 bits |
zreg_pos, zclk, reg_pos, // 8 bits |
read_pending, ctrl_state, // 4 bits |
o_mdclk, o_mdwe, o_mdio, i_mdio // 4 bits |
}; |
|
endmodule |
/trunk/rtl/enetpackets.v
0,0 → 1,757
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: enetpackets.v |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: To communicate between the Ethernet PHY, and thus to coordinate |
// (and direct/arrange for) the transmission, and receiption, of |
// packets via the Ethernet interface. |
// |
// |
// Using this interface requires four registers to be properly configured. |
// These are the receive and transmit control registers, as well as the |
// hardware MAC register(s). |
// |
// |
// To use the interface, after the system has been alive for a full |
// second, drop the reset line. Do this by writing to the transmit |
// register a value with zero length, zero command, and the RESET bit as |
// zero. |
// |
// This interface is big endian. Therefore, the most significant byte |
// in each word will be transmitted first. If the interface references |
// a number of octets less than a multiple of four, the least significant |
// octets in the last word will not be transmitted/were not received. |
// |
// To transmit, |
// 1. set the source MAC address in the two mac registers. These |
// are persistent across packets, so once set (whether for |
// transmit or receive) they need not be set again. |
// 2. Fill the packet buffer with your packet. In general, the |
// first 32-bit word must contain the hardware MAC address |
// of your destination, spilling into the 16-bits of the |
// next word. The bottom 16-bits of that second word |
// must also contain the EtherType (0x0800 for IP, |
// 0x0806 for ARP, etc.) The third word will begin your |
// user data. |
// 3. Write a 0x4000 plus the number of bytes in your buffer to |
// the transmit command register. If your packet is less |
// than 64 bytes, it will automatically be paddedd to 64 |
// bytes before being sent. |
// 4. Once complete, the controller will raise an interrupt |
// line to note that the interface is idle. |
// OPTIONS: |
// You can turn off the internal insertion of the hardware source |
// MAC by turning the respective bit on in the transmit command |
// register. If you do this, half of the second word and all the |
// third word must contain the hardware MAC. The third word must |
// contain the EtherType, both in the top and bottom sixteen bits. |
// The Fourth word will begin user data. |
// |
// You can also turn off the automatic insertion of the FCS, or |
// ethernet CRC. Doing this means that you will need to both |
// guarantee for yourself that the packet has a minimum of 64 |
// bytes in length, and that the last four bytes contain the |
// CRC. |
// |
// To Receive: |
// The receiver is always on. Receiving is really just a matter |
// of pulling the received packet from the interface, and resetting |
// the interface for the next packet. |
// |
// If the VALID bit is set, the receive interface has a valid |
// packet within it. Write a zero to this bit to reset the |
// interface to accept the next packet. |
// |
// If a packet with a CRC error is received, the CRC error bit |
// will be set. Likewise if a packet has been missed, usually |
// because the buffer was full when it started, the miss bit |
// will be set. Finally, if an error occurrs while receiving |
// a packet, the error bit will be set. These bits may be cleared |
// by writing a one to each of them--something that may be done |
// when clearing the interface for the next packet. |
// OPTIONS: |
// The same options that apply to the transmitter apply to the |
// receiver: |
// |
// HWMAC. If the hardware MAC is turned on, the receiver will |
// only accept packets to either 1) our network address, or 2) |
// a broadcast address. Further, the first two words will be |
// adjusted to contain the source MAC and the EtherType, so that |
// the user information begins on the third word. If this feature |
// is turned off, all packets will be received, and the first |
// three words will contain the destination and then source |
// MAC. The fourth word will contain the EtherType in the lowest, |
// 16 bits, meaning user data will begin on the fifth word. |
// |
// HWCRC. If the HWCRC is turned on, the receiver will only |
// detect packets that pass their CRC check. Further, the packet |
// length (always in octets) will not include the CRC. However, |
// the CRC will still be left/written to packet memory either way. |
// |
// Registers: |
// 0 Receiver control |
// 13'h0 |CRCerr|MISS|ERR|BUSY|VALID |14-bit length (in octets)| |
// |
// 1 Transmitter control |
// 14'h0 |NET_RST|SW-MAC-CHK|SW-CRCn|BUSY/CMD | 14 bit length(in octets)| |
// |
// 2 // MAC address (high) ?? |
// 3 // MAC address (low) ?? |
// 4 Number of receive packets missed (buffer was full) |
// 5 Number of receive packets ending in error |
// 6 Number of receive packets with invalid CRCs |
// 7 (Number of transmit collisions ??) |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
// `define RX_SYNCHRONOUS_WITH_WB_CLK |
`ifdef RX_SYNCHRONOUS_WITH_WB_CLK |
`define RXCLK i_wb_clk |
`else |
`define RXCLK i_net_rx_clk |
`endif |
// `define TX_SYNCHRONOUS_WITH_WB_CLK |
`ifdef TX_SYNCHRONOUS_WITH_WB_CLK |
`define TXCLK i_wb_clk |
`else |
`define TXCLK i_net_tx_clk |
`endif |
module enetpackets(i_wb_clk, i_reset, |
i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, |
o_wb_ack, o_wb_stall, o_wb_data, |
// |
o_net_reset_n, |
i_net_rx_clk, i_net_col, i_net_crs, i_net_dv, i_net_rxd, i_net_rxerr, |
i_net_tx_clk, o_net_tx_en, o_net_txd, |
// |
o_rx_int, o_tx_int, |
// |
o_debug |
); |
parameter MEMORY_ADDRESS_WIDTH = 12; // Log_2 octet width:11..14 |
localparam MAW =((MEMORY_ADDRESS_WIDTH>14)? 14: // width of words |
((MEMORY_ADDRESS_WIDTH<11)? 11:MEMORY_ADDRESS_WIDTH))-2; |
input i_wb_clk, i_reset; |
// |
input i_wb_cyc, i_wb_stb, i_wb_we; |
input [(MAW+1):0] i_wb_addr; // 1-bit for ctrl/data, 1 for tx/rx |
input [31:0] i_wb_data; |
// |
output reg o_wb_ack; |
output wire o_wb_stall; |
output reg [31:0] o_wb_data; |
// |
output reg o_net_reset_n; |
// |
input i_net_rx_clk, i_net_col, i_net_crs, i_net_dv; |
input [3:0] i_net_rxd; |
input i_net_rxerr; |
// |
input i_net_tx_clk; |
output wire o_net_tx_en; |
output wire [3:0] o_net_txd; |
// |
output wire o_rx_int, o_tx_int; |
// |
output wire [31:0] o_debug; |
|
reg wr_ctrl; |
reg [2:0] wr_addr; |
reg [31:0] wr_data; |
always @(posedge i_wb_clk) |
begin |
wr_ctrl<=((i_wb_stb)&&(i_wb_we)&&(i_wb_addr[(MAW+1):MAW] == 2'b00)); |
wr_addr <= i_wb_addr[2:0]; |
wr_data <= i_wb_data; |
end |
|
reg [31:0] txmem [0:((1<<MAW)-1)]; |
reg [31:0] rxmem [0:((1<<MAW)-1)]; |
|
reg [(MAW+1):0] tx_len; |
|
`ifdef RX_SYNCHRONOUS_WITH_WB_CLK |
wire [(MAW+1):0] rx_len; |
`else |
(* ASYNC_REG = "TRUE" *) reg [(MAW+1):0] rx_len; |
`endif |
|
reg tx_cmd, tx_cancel; |
`ifdef TX_SYNCHRONOUS_WITH_WB_CLK |
wire tx_busy, tx_complete; |
`else |
reg tx_busy, tx_complete; |
`endif |
reg config_hw_crc, config_hw_mac; |
reg rx_crcerr, rx_err, rx_miss, rx_clear; |
`ifdef RX_SYNCHRONOUS_WITH_WB_CLK |
wire rx_valid, rx_busy; |
`else |
reg rx_valid, rx_busy; |
`endif |
reg rx_wb_valid, pre_ack, pre_cmd, tx_nzero_cmd; |
reg [4:0] caseaddr; |
reg [31:0] rx_wb_data, tx_wb_data; |
reg rx_err_stb, rx_miss_stb, rx_crc_stb; |
|
reg [47:0] hw_mac; |
reg p_rx_clear; |
reg [7:0] clear_pipe; |
|
initial config_hw_crc = 0; |
initial config_hw_mac = 0; |
initial o_net_reset_n = 1'b0; |
initial tx_cmd = 1'b0; |
initial tx_cancel = 1'b0; |
initial rx_crcerr = 1'b0; |
initial rx_err = 1'b0; |
initial rx_miss = 1'b0; |
initial rx_clear = 1'b0; |
always @(posedge i_wb_clk) |
begin |
// if (i_wb_addr[(MAW+1):MAW] == 2'b10) |
// Writes to rx memory not allowed here |
if ((i_wb_stb)&&(i_wb_we)&&(i_wb_addr[(MAW+1):MAW] == 2'b11)) |
txmem[i_wb_addr[(MAW-1):0]] <= i_wb_data; |
|
// Set the err bits on these conditions (filled out below) |
if (rx_err_stb) |
rx_err <= 1'b1; |
if (rx_miss_stb) |
rx_miss <= 1'b1; |
if (rx_crc_stb) |
rx_crcerr <= 1'b1; |
|
if ((wr_ctrl)&&(wr_addr==3'b000)) |
begin // RX command register |
rx_crcerr<= (!wr_data[18])&&(!rx_crcerr); |
rx_err <= (!wr_data[17])&&(!rx_err); |
rx_miss <= (!wr_data[16])&&(!rx_miss); |
// busy bit cannot be written to |
rx_clear <= rx_clear || (wr_data[14]); |
// Length bits are cleared when invalid |
end else if (!rx_valid) |
rx_clear <= 1'b0; |
|
clear_pipe <= { clear_pipe[6:0], rx_clear }; |
p_rx_clear <= |clear_pipe; |
|
if ((tx_busy)||(tx_cancel)) |
tx_cmd <= 1'b0; |
if (!tx_busy) |
tx_cancel <= 1'b0; |
pre_cmd <= 1'b0; |
if ((wr_ctrl)&&(wr_addr==3'b001)) |
begin // TX command register |
|
// Reset bit must be held down to be valid |
o_net_reset_n <= (!wr_data[17]); |
config_hw_mac <= (!wr_data[16]); |
config_hw_crc <= (!wr_data[15]); |
pre_cmd <= (wr_data[14]); |
tx_cancel <= (tx_busy)&&(!wr_data[14]); |
// 14'h0 | SW-CRCn |NET-RST|BUSY/CMD | 14 bit length(in octets)| |
tx_len <= wr_data[(MAW+1):0]; |
end |
tx_nzero_cmd <= ((pre_cmd)&&(tx_len != 0)); |
if (tx_nzero_cmd) |
tx_cmd <= 1'b1; |
if (!o_net_reset_n) |
tx_cancel <= 1'b1; |
if (!o_net_reset_n) |
tx_cmd <= 1'b0; |
|
if ((wr_ctrl)&&(wr_addr==3'b010)) |
hw_mac[47:32] <= wr_data[15:0]; |
if ((wr_ctrl)&&(wr_addr==3'b011)) |
hw_mac[31:0] <= wr_data[31:0]; |
end |
|
wire [31:0] w_tx_ctrl; |
wire [31:0] w_rx_ctrl; |
wire [3:0] w_maw; |
|
assign w_maw = MAW+2; // Number of bits in the packet length field |
assign w_rx_ctrl = { 4'h0, w_maw, {(24-19){1'b0}}, rx_crcerr, rx_err, |
rx_miss, rx_busy, (rx_valid)&&(!rx_clear), |
{(14-MAW-2){1'b0}}, rx_len }; |
|
assign w_tx_ctrl = { 4'h0, w_maw, {(24-18){1'b0}}, |
!o_net_reset_n,!config_hw_mac, |
!config_hw_crc, tx_busy, |
{(14-MAW-2){1'b0}}, tx_len }; |
|
reg [31:0] counter_rx_miss, counter_rx_err, counter_rx_crc; |
initial counter_rx_miss = 32'h00; |
initial counter_rx_err = 32'h00; |
initial counter_rx_crc = 32'h00; |
|
// Reads from the bus ... always done, regardless of i_wb_we |
always @(posedge i_wb_clk) |
begin |
rx_wb_data <= rxmem[i_wb_addr[(MAW-1):0]]; |
rx_wb_valid <= (i_wb_addr[(MAW-1):0] <= { rx_len[(MAW+1):2] }); |
tx_wb_data <= txmem[i_wb_addr[(MAW-1):0]]; |
pre_ack <= i_wb_stb; |
caseaddr <= {i_wb_addr[(MAW+1):MAW], i_wb_addr[2:0] }; |
|
casez(caseaddr) |
5'h00: o_wb_data <= w_rx_ctrl; |
5'h01: o_wb_data <= w_tx_ctrl; |
5'h02: o_wb_data <= {16'h00, hw_mac[47:32] }; |
5'h03: o_wb_data <= hw_mac[31:0]; |
5'h04: o_wb_data <= counter_rx_miss; |
5'h05: o_wb_data <= counter_rx_err; |
5'h06: o_wb_data <= counter_rx_crc; |
5'h07: o_wb_data <= 32'h00; |
5'b10???: o_wb_data <= (rx_wb_valid)?rx_wb_data:32'h00; |
5'b11???: o_wb_data <= tx_wb_data; |
default: o_wb_data <= 32'h00; |
endcase |
o_wb_ack <= pre_ack; |
end |
|
///////////////////////////////////// |
// |
// |
// |
// Transmitter code |
// |
// |
// |
///////////////////////////////////// |
`ifdef TX_SYNCHRONOUS_WITH_WB_CLK |
reg [(MAW+1):0] n_tx_len; |
wire n_tx_cmd, n_tx_cancel; |
assign n_tx_cmd = tx_cmd; |
assign n_tx_cancel = tx_cancel; |
`else |
(* ASYNC_REG = "TRUE" *) reg [(MAW+1):0] n_tx_len; |
(* ASYNC_REG = "TRUE" *) reg r_tx_cmd, r_tx_cancel; |
reg n_tx_cmd, n_tx_cancel; |
always @(posedge `TXCLK) |
begin |
r_tx_cmd <= tx_cmd; |
r_tx_cancel <= tx_cancel; |
|
n_tx_cmd <= r_tx_cmd; |
n_tx_cancel <= r_tx_cancel; |
end |
`endif |
|
`ifdef TX_SYNCHRONOUS_WITH_WB_CLK |
reg last_tx_clk, tx_clk_stb; |
(* ASYNC_REG = "TRUE" *) reg r_tx_clk; |
always @(posedge i_wb_clk) |
r_tx_clk <= i_net_tx_clk; |
always @(posedge i_wb_clk) |
last_tx_clk <= r_tx_clk; |
always @(posedge i_wb_clk) |
tx_clk_stb <= (r_tx_clk)&&(!last_tx_clk); |
`else |
wire tx_clk_stb, last_tx_clk; |
|
assign tx_clk_stb = 1'b1; |
assign last_tx_clk= 1'b0; |
`endif |
|
wire [(MAW+2):0] rd_tx_addr; |
assign rd_tx_addr = (n_tx_addr+8); |
|
reg [(MAW+2):0] n_tx_addr; |
reg [31:0] n_tx_data, n_next_tx_data; |
reg n_tx_complete; |
`ifdef TX_SYNCHRONOUSH_WITH_WB |
reg n_tx_busy, n_tx_config_hw_mac, n_tx_config_hw_crc; |
`else |
(* ASYNC_REG = "TRUE" *) reg n_tx_busy, |
n_tx_config_hw_mac, n_tx_config_hw_crc; |
`endif |
(* ASYNC_REG = "TRUE" *) reg r_tx_crs; |
reg n_tx_crs; |
always @(posedge `TXCLK) |
begin |
r_tx_crs <= i_net_crs; |
n_tx_crs <= r_tx_crs; |
end |
|
wire [31:0] n_remap_tx_data; |
assign n_remap_tx_data[31:28] = n_next_tx_data[27:24]; |
assign n_remap_tx_data[27:24] = n_next_tx_data[31:28]; |
assign n_remap_tx_data[23:20] = n_next_tx_data[19:16]; |
assign n_remap_tx_data[19:16] = n_next_tx_data[23:20]; |
assign n_remap_tx_data[15:12] = n_next_tx_data[11: 8]; |
assign n_remap_tx_data[11: 8] = n_next_tx_data[15:12]; |
assign n_remap_tx_data[ 7: 4] = n_next_tx_data[ 3: 0]; |
assign n_remap_tx_data[ 3: 0] = n_next_tx_data[ 7: 4]; |
|
reg r_txd_en; |
reg [3:0] r_txd; |
initial r_txd_en = 1'b0; |
|
initial n_tx_busy = 1'b0; |
initial n_tx_complete = 1'b0; |
always @(posedge `TXCLK) |
begin |
if (tx_clk_stb) |
begin |
// While this operation doesn't strictly need to |
// operate *only* if tx_clk_stb is true, by doing so |
// our code stays compatible with both synchronous |
// to wishbone and synchronous to tx clk options. |
n_next_tx_data <= txmem[(!n_tx_busy)?0:rd_tx_addr[(MAW+2):3]]; |
end |
|
|
if (n_tx_cancel) |
n_tx_busy <= 1'b0; |
else if (!n_tx_busy) |
n_tx_busy <= (n_tx_cmd)&&(!i_net_crs); |
else if (n_tx_addr >= { n_tx_len,1'b0 }) |
n_tx_busy <= 1'b0; |
|
if (!n_tx_busy) |
begin |
n_tx_addr <= {{(MAW+2){1'b0}},1'b1}; |
n_tx_data <= { n_remap_tx_data[27:0], 4'h0 }; |
if (n_tx_complete) |
n_tx_complete <= (!n_tx_cmd); |
r_txd_en <= (!n_tx_complete)&&(n_tx_cmd)&&(!i_net_crs); |
r_txd <= n_remap_tx_data[31:28]; |
n_tx_config_hw_mac <= config_hw_mac; |
n_tx_config_hw_crc <= config_hw_crc; |
n_tx_len <= tx_len; |
end else if (!r_txd_en) |
r_txd_en <= (!n_tx_crs); |
else if (tx_clk_stb) begin |
n_tx_addr <= n_tx_addr + 1'b1; |
r_txd <= n_tx_data[31:28]; |
if (n_tx_addr[2:0] == 3'h7) |
n_tx_data <= n_remap_tx_data; |
else |
n_tx_data <= { n_tx_data[27:0], 4'h0 }; |
if (n_tx_addr >= { n_tx_len,1'b0 }) |
n_tx_complete <= 1'b1; |
r_txd_en <= (n_tx_addr < { n_tx_len, 1'b0 }); |
end |
end |
|
wire n_tx_config_hw_preamble; |
assign n_tx_config_hw_preamble = 1'b1; |
|
wire w_macen, w_paden, w_txcrcen; |
wire [3:0] w_macd, w_padd, w_txcrcd; |
|
`ifndef TX_BYPASS_HW_MAC |
addemac txmaci(`TXCLK, tx_clk_stb, n_tx_config_hw_mac, n_tx_cancel, |
hw_mac, r_txd_en, r_txd, w_macen, w_macd); |
`else |
assign w_macen = r_txd_en; |
assign w_macd = r_txd; |
`endif |
|
`ifndef TX_BYPASS_PADDING |
addepad txpadi(`TXCLK, tx_clk_stb, 1'b1, n_tx_cancel, |
w_macen, w_macd, w_paden, w_padd); |
`else |
assign w_paden = w_macen; |
assign w_padd = w_macd; |
`endif |
|
`ifndef TX_BYPASS_HW_CRC |
addecrc txcrci(`TXCLK, tx_clk_stb, n_tx_config_hw_crc, n_tx_cancel, |
w_paden, w_padd, w_txcrcen, w_txcrcd); |
`else |
assign w_txcrcen = w_macen; |
assign w_txcrcd = w_macd; |
`endif |
|
addepreamble txprei(`TXCLK, tx_clk_stb, n_tx_config_hw_preamble, n_tx_cancel, |
w_txcrcen, w_txcrcd, o_net_tx_en, o_net_txd); |
|
`ifdef TX_SYNCRONOUS_WITH_WB_CLK |
assign tx_busy = n_tx_busy; |
assign tx_complete = n_tx_complete; |
`else |
(* ASYNC_REG = "TRUE" *) reg r_tx_busy, r_tx_complete; |
always @(posedge i_wb_clk) |
begin |
r_tx_busy <= (n_tx_busy || o_net_tx_en || w_txcrcen || w_macen || w_paden); |
tx_busy <= r_tx_busy; |
|
r_tx_complete <= n_tx_complete; |
tx_busy <= r_tx_busy; |
end |
`endif |
|
|
|
|
|
///////////////////////////////////// |
// |
// |
// |
// Receiver code |
// |
// |
// |
///////////////////////////////////// |
`ifdef RX_SYNCHRONOUS_WITH_WB_CLK |
reg last_rx_clk, rx_clk_stb; |
(* ASYNC_REG="TRUE" *) reg r_rx_clk; |
always @(posedge i_wb_clk) |
r_rx_clk <= i_net_rx_clk; |
always @(posedge i_wb_clk) |
last_rx_clk <= r_rx_clk; |
always @(posedge i_wb_clk) |
rx_clk_stb <= (r_rx_clk)&&(!last_rx_clk); |
|
`else |
wire rx_clk_stb, last_rx_clk; |
assign rx_clk_stb = 1'b1; |
assign last_rx_clk = 1'b0; |
`endif |
|
|
`ifdef RX_SYNCHRONOUS_WITH_WB_CLK |
wire n_rx_clear; |
reg n_rx_config_hw_mac, n_rx_config_hw_crc; |
assign n_rx_clear = rx_clear; |
`else |
(* ASYNC_REG = "TRUE" *) reg n_rx_config_hw_mac, n_rx_config_hw_crc; |
(* ASYNC_REG = "TRUE" *) reg r_rx_clear; |
reg n_rx_clear; |
always @(posedge `RXCLK) |
begin |
r_rx_clear <= (p_rx_clear)||(!o_net_reset_n); |
n_rx_clear <= r_rx_clear; |
end |
`endif |
|
|
reg n_rx_net_err; |
wire w_npre, w_rxmin, w_rxcrc, w_rxmac, w_rxip; |
wire [3:0] w_npred, w_rxmind, w_rxcrcd, w_rxmacd, w_rxipd; |
wire w_minerr, w_rxcrcerr, w_macerr, w_broadcast, w_iperr; |
`ifndef RX_BYPASS_HW_PREAMBLE |
rxepreambl rxprei(`RXCLK, rx_clk_stb, 1'b1, (n_rx_net_err), |
i_net_dv, i_net_rxd, w_npre, w_npred); |
`else |
assign w_npre = i_net_dv; |
assign w_npred = i_net_rxerr; |
`endif |
|
`ifdef RX_HW_MINLENGTH |
// Insist on a minimum of 64-byte packets |
rxeminlen rxmini(`RXCLK, rx_clk_stb, 1'b1, (n_rx_net_err), |
w_npre, w_npred, w_rxmin, w_rxmind, w_minerr); |
`else |
assign w_rxmin = w_npre; |
assign w_rxmind= w_npred; |
assign w_minerr= 1'b0; |
`endif |
|
`ifndef RX_BYPASS_HW_CRC |
rxecrc rxcrci(`RXCLK, rx_clk_stb, n_rx_config_hw_crc, (n_rx_net_err), |
w_rxmin, w_rxmind, w_rxcrc, w_rxcrcd, w_rxcrcerr); |
`else |
assign w_rxcrc = w_rxmin; |
assign w_rxcrcd = w_rxmind; |
assign w_rxcrcerr= 1'b0; |
`endif |
|
`ifndef RX_BYPASS_HW_RMMAC |
rxehwmac rxmaci(`RXCLK, rx_clk_stb, n_rx_config_hw_mac, (n_rx_net_err), hw_mac, |
w_rxcrc, w_rxcrcd, |
w_rxmac, w_rxmacd, |
w_macerr, w_broadcast); |
`else |
assign w_rxmac = w_rxcrc; |
assign w_rxmacd = w_rxcrcd; |
`endif |
|
`ifdef RX_HW_IPCHECK |
// Check: if this packet is an IP packet, is the IP header checksum |
// valid? |
`else |
assign w_rxip = w_rxmac; |
assign w_rxipd = w_rxmacd; |
assign w_iperr = 1'b0; |
`endif |
|
wire w_rxwr; |
wire [(MAW-1):0] w_rxaddr; |
wire [31:0] w_rxdata; |
wire [(MAW+1):0] w_rxlen; |
|
rxewrite #(MAW) rxememi(`RXCLK, 1'b1, (n_rx_net_err), w_rxip, w_rxipd, |
w_rxwr, w_rxaddr, w_rxdata, w_rxlen); |
|
reg last_rxwr, n_rx_valid, n_rxmiss, n_eop, n_rx_busy, n_rx_crcerr, |
n_rx_err, n_rx_broadcast, n_rx_miss; |
reg [(MAW+1):0] n_rx_len; |
|
initial n_rx_valid = 1'b0; |
initial n_rx_clear = 1'b1; |
initial n_rx_miss = 1'b0; |
always @(posedge `RXCLK) |
begin |
if ((w_rxwr)&&(!n_rx_valid)) |
rxmem[w_rxaddr] <= w_rxdata; |
|
// n_rx_net_err goes true as soon as an error is detected, |
// and stays true as long as valid data is coming in |
n_rx_net_err <= (i_net_dv)&&((i_net_rxerr)||(i_net_col) |
||(w_minerr)||(w_macerr)||(w_rxcrcerr) |
||(n_rx_net_err) |
||((w_rxwr)&&(n_rx_valid))); |
|
last_rxwr <= w_rxwr; |
n_eop <= (!w_rxwr)&&(last_rxwr)&&(!n_rx_net_err); |
|
n_rx_busy <= (!n_rx_net_err)&&((i_net_dv)||(w_npre)||(w_rxmin) |
||(w_rxcrc)||(w_rxmac)||(w_rxip)||(w_rxwr)); |
|
// Oops ... we missed a packet |
n_rx_miss <= (n_rx_valid)&&(w_rxwr)|| |
((n_rx_miss)&&(!n_rx_clear)); |
|
n_rx_crcerr <= ((w_rxcrcerr)&&(!n_rx_net_err)) |
||((n_rx_crcerr)&&(!n_rx_clear)); |
|
n_rx_err <= ((n_rx_err)&&(!n_rx_clear)) |
||((i_net_rxerr)||(i_net_col)||(w_minerr)); |
|
n_rx_broadcast <= (w_broadcast)||((n_rx_broadcast)&&(!n_rx_clear)); |
|
if (n_rx_clear) |
begin |
n_rx_valid <= 1'b0; |
n_rx_len <= 0; |
end else if (n_eop) |
begin |
n_rx_valid <= 1'b1; |
n_rx_len <= w_rxlen - ((n_rx_config_hw_crc)?{{(MAW-1){1'b0}},3'h4}:0); |
end |
// else n_rx_valid = n_rx_valid; |
|
if ((!i_net_dv)||(n_rx_clear)) |
begin |
n_rx_config_hw_mac <= config_hw_mac; |
n_rx_config_hw_crc <= config_hw_crc; |
end |
end |
|
`ifdef RX_SYNCHRONOUS_WITH_WB_CLK |
assign rx_busy = n_rx_busy; |
assign rx_valid = n_rx_valid; |
assign rx_len = n_rx_len; |
`else |
reg r_rx_busy, r_rx_valid; |
always @(posedge i_wb_clk) |
begin |
r_rx_valid <= n_rx_valid; |
rx_valid <= r_rx_valid; |
|
r_rx_busy <= n_rx_busy; |
rx_busy <= r_rx_busy; |
|
rx_len <= n_rx_len; |
end |
|
`endif |
|
reg [3:0] rx_err_pipe, rx_miss_pipe, rx_crc_pipe; |
always @(posedge i_wb_clk) |
begin |
rx_err_pipe <= { rx_err_pipe[ 2:0],(n_rx_err)&&(rx_clk_stb) }; |
rx_miss_pipe <= { rx_miss_pipe[2:0],(n_rx_miss)&&(rx_clk_stb) }; |
rx_crc_pipe <= { rx_crc_pipe[ 2:0],(n_rx_crcerr)&&(rx_clk_stb) }; |
rx_err_stb <= (rx_err_pipe[ 3:2] == 2'b01); |
rx_miss_stb <= (rx_miss_pipe[3:2] == 2'b01); |
rx_crc_stb <= (rx_crc_pipe[ 3:2] == 2'b01); |
end |
|
always @(posedge i_wb_clk) |
if (o_net_reset_n) |
counter_rx_miss <= 32'h0; |
else if (rx_miss_stb) |
counter_rx_miss <= counter_rx_miss + 32'h1; |
always @(posedge i_wb_clk) |
if (o_net_reset_n) |
counter_rx_err <= 32'h0; |
else if (rx_err_stb) |
counter_rx_err <= counter_rx_err + 32'h1; |
always @(posedge i_wb_clk) |
if (o_net_reset_n) |
counter_rx_crc <= 32'h0; |
else if (rx_crc_stb) |
counter_rx_crc <= counter_rx_crc + 32'h1; |
|
assign o_tx_int = !tx_busy; |
assign o_rx_int = (rx_valid)&&(!rx_clear); |
assign o_wb_stall = 1'b0; |
|
wire [31:0] rxdbg; |
wire rx_trigger; // reg rx_trigger; |
/* |
always @(posedge `RXCLK) |
begin |
if ((n_rx_clear)&&(!rx_trigger)) |
rx_trigger <= 1'b1; |
else if (!n_rx_clear) |
rx_trigger <= 1'b0; |
end |
*/ |
assign rx_trigger = i_net_dv; |
|
assign rxdbg = { rx_trigger, n_eop, w_rxwr, |
w_npre, w_npred, |
w_rxcrc, w_rxcrcd, |
w_macerr, w_broadcast, w_rxmac, w_rxmacd, |
n_rx_clear, i_net_rxerr, n_rx_miss, n_rx_net_err,// 4 bits |
n_rx_valid, n_rx_busy, i_net_crs, i_net_dv, // 4 bits |
i_net_rxd }; // 4 bits |
|
|
wire [31:0] txdbg; |
assign txdbg = { n_tx_cmd, i_net_dv, rx_busy, n_rx_err, i_net_rxd, |
{(24-(MAW+3)-10){1'b0}}, |
n_tx_addr[(MAW+2):0], |
tx_clk_stb, n_tx_cancel, |
n_tx_cmd, n_tx_complete, n_tx_busy, o_net_tx_en, |
o_net_txd |
}; |
|
assign o_debug = rxdbg; |
endmodule |
/trunk/rtl/fastmaster.v
219,12 → 219,12
gpsrx_int, rtc_pps |
}; |
|
zipsystem #( .RESET_ADDRESS(24'h08000), |
zipsystem #( .RESET_ADDRESS(24'h0480000), |
.ADDRESS_WIDTH(ZA), |
.LGICACHE(10), |
.START_HALTED(1), |
.START_HALTED(0), |
.EXTERNAL_INTERRUPTS(ZIPINTS), |
.HIGHSPEED_CPU(1)) |
.HIGHSPEED_CPU(0)) |
zippy(i_clk, i_rst, |
// Zippys wishbone interface |
zip_cyc, zip_stb, zip_we, w_zip_addr, zip_data, |
349,13 → 349,14
assign mem_sel = (skipaddr[4:2]==3'b001); |
assign netb_sel = (skipaddr[4:1]==4'b0001); |
assign io_sel = (~|skipaddr)&&(wb_addr[7:5]==3'b000); |
assign scop_sel = (~|skipaddr)&&(wb_addr[7:3]==5'b00100); |
assign rtc_sel = (~|skipaddr)&&(wb_addr[7:2]==6'b001010); |
assign sdcard_sel= (~|skipaddr)&&(wb_addr[7:2]==6'b001011); |
assign netp_sel = (~|skipaddr)&&(wb_addr[7:2]==6'b001101); |
assign oled_sel = (~|skipaddr)&&(wb_addr[7:2]==6'b001110); |
assign gps_sel = (~|skipaddr)&&( (wb_addr[7:2]==6'b001100) |
|| (wb_addr[7:3]==5'b01000)); |
assign scop_sel = (~|skipaddr)&&(wb_addr[7:3]==5'b0010_0); |
assign rtc_sel = (~|skipaddr)&&(wb_addr[7:2]==6'b0010_10); |
assign sdcard_sel= (~|skipaddr)&&(wb_addr[7:2]==6'b0010_11); |
//assign gps_sel = (~|skipaddr)&&(wb_addr[7:2]==6'b0011_00); |
assign oled_sel = (~|skipaddr)&&(wb_addr[7:2]==6'b0011_01); |
assign netp_sel = (~|skipaddr)&&(wb_addr[7:3]==5'b0011_1); |
assign gps_sel = (~|skipaddr)&&( (wb_addr[7:2]==6'b0011_00) |
|| (wb_addr[7:3]==5'b0100_0)); |
assign mio_sel = (~|skipaddr)&&(wb_addr[7:5]==3'b101); |
assign flctl_sel = (~|skipaddr)&&(wb_addr[7:5]==3'b110); |
assign cfg_sel = (~|skipaddr)&&(wb_addr[7:5]==3'b111); |
547,7 → 548,7
||((single_sel_a)&&(single_sel_b)) |
||((single_sel_a)&&(many_sel_a)) |
||((single_sel_b)&&(many_sel_b)); |
assign wb_err = (wb_cyc)&&(sel_err || many_ack || slow_many_ack); |
assign wb_err = (wb_cyc)&&(sel_err || many_ack || slow_many_ack||ram_err); |
|
|
// Finally, if we ever encounter a bus error, knowing the address of |
623,18 → 624,9
(!dbg_counter_cyc[25])|w_led[1], |
(!dbg_counter_err[25])|w_led[0] }; |
*/ |
assign o_led = w_led; |
|
reg [25:0] dbg_counter_sdram; |
always @(posedge i_clk) |
if ((ram_sel)&&(wb_stb)) |
dbg_counter_sdram <= 0; |
else if (wb_stb) |
dbg_counter_sdram[25] <= 1'b1; |
else if (!dbg_counter_sdram[25]) |
dbg_counter_sdram <= dbg_counter_sdram+26'h1; |
assign o_led = { w_led[3:1], w_led[0] | (!dbg_counter_sdram[25]) }; |
|
|
// |
// |
// Real Time Clock (RTC) device level access |
643,7 → 635,9
wire gps_tracking, ck_pps; |
wire [63:0] gps_step; |
`ifdef RTC_ACCESS |
rtcgps #(32'h15798f) // 2^48 / 200MHz |
rtcgps |
// #(32'h15798f) // 2^48 / 200MHz |
#(32'h1a6e3a) // 2^48 / 162.5 MHz |
thertc(i_clk, |
wb_cyc, (wb_stb)&&(rtc_sel), wb_we, |
wb_addr[1:0], wb_data, |
698,7 → 692,9
// |
// |
`ifdef OLEDRGB_ACCESS |
wboled rgbctrl(i_clk, |
wboled |
.#( .CBITS(5))// Div ck by 2^5=32, words take 200ns@162.5MHz |
rgbctrl(i_clk, |
wb_cyc, (wb_stb)&&(oled_sel), wb_we, |
wb_addr[1:0], wb_data, |
oled_ack, oled_stall, oled_data, |
754,7 → 750,9
// |
// GPS CLOCK CONTROL |
// |
gpsclock ppsck(i_clk, 1'b0, gps_pps, ck_pps, gps_led, |
gpsclock #( |
.DEFAULT_STEP(32'h81a6e39b) // 162.5 MHz |
) ppsck(i_clk, 1'b0, gps_pps, ck_pps, gps_led, |
(wb_stb)&&(gps_sel)&&(~wb_addr[3]), |
wb_we, wb_addr[1:0], |
wb_data, gck_ack, gck_stall, gck_data, |
865,7 → 863,8
// |
// There is no option to turn this off--this RAM must always be |
// present in the design. |
memdev #(15) // 32kW, or 128kB, 15 address lines |
memdev #(.AW(15), |
.EXTRACLOCK(1)) // 32kW, or 128kB, 15 address lines |
blkram(i_clk, wb_cyc, (wb_stb)&&(mem_sel), wb_we, wb_addr[14:0], |
wb_data, mem_ack, mem_stall, mem_data); |
|
962,8 → 961,8
&&(wb_err)||(zip_scope_data[31]); |
wbscope #(5'd13) cpuscope(i_clk, 1'b1,(scop_cpu_trigger), zip_scope_data, |
// Wishbone interface |
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b00)), wb_we, wb_addr[0], |
wb_data, |
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b00)), |
wb_we, wb_addr[0], wb_data, |
scop_cpu_ack, scop_cpu_stall, scop_cpu_data, |
scop_cpu_interrupt); |
|
981,8 → 980,8
wbscope #(5'd13) flashscope(i_clk, 1'b1, |
(scop_flash_trigger), flash_debug, |
// Wishbone interface |
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b00)), wb_we, wb_addr[0], |
wb_data, |
i_clk, wb_cyc, ((wb_stb)&&(scop_sel)&&(wb_addr[2:1]==2'b00)), |
wb_we, wb_addr[0], wb_data, |
scop_flash_ack, scop_flash_stall, scop_flash_data, |
scop_flash_interrupt); |
|
1131,7 → 1130,7
// else. |
assign scop_stall = ((wb_addr[2:1]==2'b0)?scop_a_stall |
: ((wb_addr[2:1]==2'b01)?scop_b_stall |
: ((wb_addr[2:1]==2'b11)?scop_c_stall |
: ((wb_addr[2:1]==2'b10)?scop_c_stall |
: scop_d_stall))); // Will always be 1'b0; |
initial scop_ack = 1'b0; |
always @(posedge i_clk) |
/trunk/rtl/flash_config.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: flashconfig.v |
// |
14,7 → 14,7
// Creator: Dan Gisselquist |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// |
37,7 → 37,7
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
`ifndef FLASH_CONFIG_V |
`define FLASH_CONFIG_V |
/trunk/rtl/lleqspi.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: lleqspi.v |
// |
13,7 → 13,7
// Creator: Dan Gisselquist |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
36,7 → 36,7
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
`define EQSPI_IDLE 3'h0 |
`define EQSPI_START 3'h1 |
`define EQSPI_BITS 3'h2 |
/trunk/rtl/memdev.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: memdev.v |
// |
16,7 → 16,7
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
34,7 → 34,7
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
module memdev(i_clk, i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, |
/trunk/rtl/rtcdate.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: rtcdate.v |
// |
26,7 → 26,7
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// |
49,7 → 49,7
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
module rtcdate(i_clk, i_ppd, i_wb_cyc, i_wb_stb, i_wb_we, i_wb_data, |
o_wb_ack, o_wb_stall, o_wb_data); |
input i_clk; |
/trunk/rtl/rtcgps.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: rtcgps.v |
// |
15,7 → 15,7
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
38,7 → 38,9
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
module rtcgps(i_clk, |
// Wishbone interface |
i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, |
/trunk/rtl/toplevel.v
54,7 → 54,11
i_uart_rx, o_uart_tx, |
// Quad-SPI Flash control |
o_qspi_sck, o_qspi_cs_n, io_qspi_dat, |
// Missing: Ethernet |
// Ethernet |
o_eth_rstn, o_eth_ref_clk, |
i_eth_rx_clk, i_eth_col, i_eth_crs, i_eth_rx_dv, i_eth_rxd, i_eth_rxerr, |
i_eth_tx_clk, o_eth_tx_en, o_eth_txd, |
// Ethernet (MDIO) |
o_eth_mdclk, io_eth_mdio, |
// Memory |
ddr3_reset_n, ddr3_cke, ddr3_ck_p, ddr3_ck_n, |
84,7 → 88,14
// Quad SPI flash |
output wire o_qspi_sck, o_qspi_cs_n; |
inout [3:0] io_qspi_dat; |
// Ethernet // Not yet implemented |
// Ethernet |
output wire o_eth_rstn, o_eth_ref_clk; |
input i_eth_rx_clk, i_eth_col, i_eth_crs, i_eth_rx_dv; |
input [3:0] i_eth_rxd; |
input i_eth_rxerr; |
input i_eth_tx_clk; |
output wire o_eth_tx_en; |
output [3:0] o_eth_txd; |
// Ethernet control (MDIO) |
output wire o_eth_mdclk; |
inout wire io_eth_mdio; |
118,6 → 129,15
input i_aux_rx, i_aux_rts; |
output wire o_aux_tx, o_aux_cts; |
|
wire eth_tx_clk, eth_rx_clk; |
`ifdef VERILATOR |
wire s_clk, s_reset; |
assign s_clk = sys_clk_i; |
|
assign eth_tx_clk = i_eth_tx_clk; |
assign eth_rx_clk = i_eth_rx_clk; |
|
`else |
// Build our master clock |
wire s_clk, sys_clk, mem_clk_200mhz, |
clk1_unused, clk2_unused, enet_clk, clk4_unnused, |
130,8 → 150,8
.CLKFBOUT_MULT(8), // Multiply value for all CLKOUT (2-64) |
.CLKOUT0_DIVIDE(8), // 100 MHz (Clock for MIG) |
.CLKOUT1_DIVIDE(4), // 200 MHz (MIG Reference clock) |
.CLKOUT2_DIVIDE(32), // 50 MHz (Unused) |
.CLKOUT3_DIVIDE(64), // 25 MHz (Unused/Ethernet clock) |
.CLKOUT2_DIVIDE(16), // 50 MHz (Unused) |
.CLKOUT3_DIVIDE(32), // 25 MHz (Ethernet reference clk) |
.CLKOUT4_DIVIDE(32), // 50 MHz (Unused clock?) |
.CLKOUT5_DIVIDE(24), // 66 MHz |
// CLKOUT0_DUTY_CYCLE -- Duty cycle for each CLKOUT |
171,6 → 191,14
// BUFG memref_buffer(.I(mem_clk_200mhz_nobuf),.O(mem_clk_200mhz)); |
IBUF sysclk_buf(.I(sys_clk_i[0]), .O(sys_clk)); |
|
BUFG eth_rx(.I(i_eth_rx_clk), .O(eth_rx_clk)); |
// assign eth_rx_clk = i_eth_rx_clk; |
|
|
BUFG eth_tx(.I(i_eth_tx_clk), .O(eth_tx_clk)); |
// assign eth_tx_clk = i_eth_tx_clk; |
`endif |
|
// |
// |
// UART interface |
194,6 → 222,7
// logic fashion, we synchronize this wire by registering it first |
// to pre_reset, and then to pwr_reset (the actual reset wire). |
// |
wire s_reset; // Ultimate system reset wire |
reg [7:0] pre_reset; |
reg pwr_reset; |
// Since all our stuff is synchronous to the clock that comes out of |
213,10 → 242,14
initial pwr_reset = 1'b0; |
always @(posedge sys_clk) |
pwr_reset <= pre_reset[7]; |
`ifdef VERILATOR |
assign s_reset = pwr_reset; |
`else |
// |
// Of course, this only goes into the memory controller. The true |
// device reset comes out of that memory controller, synchronized to |
// our memory generator provided clock(s) |
`endif |
|
wire w_ck_uart, w_uart_tx; |
rxuart rcv(s_clk, s_reset, bus_uart_setup, i_uart_rx, |
286,6 → 319,11
ram_dbg, |
// SD Card |
o_sd_sck, w_sd_cmd, w_sd_data, io_sd_cmd, io_sd, i_sd_cs, |
// Ethernet |
o_eth_rstn, |
eth_rx_clk, i_eth_col, i_eth_crs, i_eth_rx_dv, |
i_eth_rxd, i_eth_rxerr, |
eth_tx_clk, o_eth_tx_en, o_eth_txd, |
// Ethernet control (MDIO) lines |
o_eth_mdclk, w_mdio, w_mdwe, io_eth_mdio, |
// OLEDRGB PMod wires |
322,6 → 360,13
// |
wire [3:0] i_qspi_pedge, i_qspi_nedge; |
|
`ifdef VERILATOR |
assign o_qspi_sck = w_qspi_sck; |
assign o_qspi_cs_n = w_qspi_cs_n; |
; |
(); |
[*]; |
`else |
xoddr xqspi_sck( s_clk, { w_qspi_sck, w_qspi_sck }, o_qspi_sck); |
xoddr xqspi_csn( s_clk, { w_qspi_cs_n, w_qspi_cs_n },o_qspi_cs_n); |
// |
337,8 → 382,12
xioddr xqspi_d3( s_clk, (qspi_bmod!=2'b11), |
(qspi_bmod[1])?{ qspi_dat[3], qspi_dat[3] }:2'b11, |
{ i_qspi_pedge[3], i_qspi_nedge[3] }, io_qspi_dat[3]); |
`endif |
reg [3:0] r_qspi_dat; |
always @(posedge s_clk) |
r_qspi_dat <= i_qspi_pedge; |
assign i_qspi_dat = r_qspi_dat; |
|
assign i_qspi_dat = i_qspi_pedge; |
// |
// Proposed QSPI mode select, to allow dual I/O mode |
// 000 Normal SPI mode |
352,6 → 401,17
|
// |
// |
// Generate a reference clock for the network |
// |
// |
`ifdef VERILATOR |
assign o_eth_ref_clk = i_eth_tx_clk; |
`else |
xoddr e_ref_clk( enet_clk, { 1'b1, 1'b0 }, o_eth_ref_clk ); |
`endif |
|
// |
// |
// Wires for setting up the SD Card Controller |
// |
// |
375,7 → 435,7
// Now, to set up our memory ... |
// |
// |
migsdram rami( |
migsdram #(.AXIDWIDTH(5)) rami( |
.i_clk(mem_clk_nobuf), .i_clk_200mhz(mem_clk_200mhz_nobuf), |
.o_sys_clk(s_clk), .i_rst(pwr_reset), .o_sys_reset(s_reset), |
.i_wb_cyc(ram_cyc), .i_wb_stb(ram_stb), .i_wb_we(ram_we), |
/trunk/rtl/wbicapetwo.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbicapetwo.v |
// |
68,9 → 68,9
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
86,8 → 86,9
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
`define MBOOT_IDLE 5'h00 |
`define MBOOT_START 5'h01 |
`define MBOOT_READ 5'h06 |
/trunk/rtl/wbqspiflash.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbspiflash.v |
// |
27,7 → 27,7
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
50,8 → 50,9
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
`include "flash_config.v" |
// |
`define WBQSPI_RESET 0 |
/trunk/rtl/wbscopc.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbscopc.v |
// |
61,7 → 61,7
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// |
84,7 → 84,7
// http://www.gnu.org/licenses/gpl.html |
// |
// |
///////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
module wbscopc(i_clk, i_ce, i_trigger, i_data, |
/trunk/rtl/wbscope.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbscope.v |
// |
58,7 → 58,7
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015, Gisselquist Technology, LLC |
// |
81,12 → 81,15
// http://www.gnu.org/licenses/gpl.html |
// |
// |
///////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
module wbscope(i_clk, i_ce, i_trigger, i_data, |
i_wb_clk, i_wb_cyc, i_wb_stb, i_wb_we, i_wb_addr, i_wb_data, |
o_wb_ack, o_wb_stall, o_wb_data, |
o_interrupt); |
parameter LGMEM = 5'd10, BUSW = 32, SYNCHRONOUS=1; |
parameter LGMEM = 5'd10, BUSW = 32, SYNCHRONOUS=1, |
DEFAULT_HOLDOFF = ((1<<(LGMEM-1))-4); |
// The input signals that we wish to record |
input i_clk, i_ce, i_trigger; |
input [(BUSW-1):0] i_data; |
109,7 → 112,7
bw_disable_trigger, bw_reset_complete; |
reg [22:0] br_config; |
wire [19:0] bw_holdoff; |
initial br_config = ((1<<(LGMEM-1))-4); |
initial br_config = DEFAULT_HOLDOFF; |
always @(posedge i_wb_clk) |
if ((i_wb_cyc)&&(i_wb_stb)&&(~i_wb_addr)) |
begin |
135,7 → 138,8
assign bw_reset_complete = bw_reset_request; |
end else begin |
reg r_reset_complete; |
reg [2:0] r_iflags, q_iflags; |
(* ASYNC_REG = "TRUE" *) reg [2:0] q_iflags; |
reg [2:0] r_iflags; |
|
// Resets are synchronous to the bus clock, not the data clock |
// so do a clock transfer here |
152,7 → 156,8
assign dw_manual_trigger = r_iflags[1]; |
assign dw_disable_trigger = r_iflags[0]; |
|
reg q_reset_complete, qq_reset_complete; |
(* ASYNC_REG = "TRUE" *) reg q_reset_complete; |
reg qq_reset_complete; |
// Pass an acknowledgement back from the data clock to the bus |
// clock that the reset has been accomplished |
initial q_reset_complete = 1'b0; |
190,7 → 195,7
// |
// Writes take place on the data clock |
reg dr_stopped; |
reg [19:0] counter; // This is unsigned |
(* ASYNC_REG="TRUE" *) reg [19:0] counter;// This is unsigned |
initial dr_stopped = 1'b0; |
initial counter = 20'h0000; |
always @(posedge i_clk) |
252,7 → 257,8
// for many clocks. Swapping is thus easy--two flip flops to |
// protect against meta-stability and we're done. |
// |
reg [2:0] q_oflags, r_oflags; |
(* ASYNC_REG = "TRUE" *) reg [2:0] q_oflags; |
reg [2:0] r_oflags; |
initial q_oflags = 3'h0; |
initial r_oflags = 3'h0; |
always @(posedge i_wb_clk) |
/trunk/rtl/wbufifo.v
33,7 → 33,7
// |
// |
module wbufifo(i_clk, i_rst, i_wr, i_data, i_rd, o_data, o_empty_n, o_err); |
parameter BW=66, LGFLEN=10, FLEN=(1<<LGFLEN); |
parameter BW=66, LGFLEN=10; |
input i_clk, i_rst; |
input i_wr; |
input [(BW-1):0] i_data; |
42,6 → 42,8
output reg o_empty_n; |
output wire o_err; |
|
localparam FLEN=(1<<LGFLEN); |
|
reg [(BW-1):0] fifo[0:(FLEN-1)]; |
reg [(LGFLEN-1):0] r_first, r_last; |
|
/trunk/rtl/wbureadcw.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: wbureadcw.v |
// |
15,7 → 15,7
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
33,7 → 33,7
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
// Goal: single clock pipeline, 50 slices or less |
/trunk/rtl/wbusixchar.v
1,4 → 1,4
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
// Filename: wbusixchar.v |
21,7 → 21,7
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
39,7 → 39,7
// http://www.gnu.org/licenses/gpl.html |
// |
// |
/////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
// |
/trunk/sw/board/arty.ld
0,0 → 1,71
/******************************************************************************* |
* |
* Filename: arty.ld |
* |
* Project: OpenArty, an entirely open SoC based upon the Arty platform |
* |
* Purpose: This script provides a description of the memory on the Arty, |
* for the purposes of where to place programs in memory during |
* linking. |
* |
* Creator: Dan Gisselquist, Ph.D. |
* Gisselquist Technology, LLC |
* |
******************************************************************************** |
* |
* Copyright (C) 2016, Gisselquist Technology, LLC |
* |
* This program is free software (firmware): you can redistribute it and/or |
* modify it under the terms of the GNU General Public License as published |
* by the Free Software Foundation, either version 3 of the License, or (at |
* your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, but WITHOUT |
* ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
* for more details. |
* |
* License: GPL, v3, as defined and found on www.gnu.org, |
* http://www.gnu.org/licenses/gpl.html |
* |
* |
*******************************************************************************/ |
|
ENTRY(_start) |
|
MEMORY |
{ |
blkram (wx) : ORIGIN = 0x0008000, LENGTH = 0x0008000 |
flash (rx) : ORIGIN = 0x0400000, LENGTH = 0x0400000 |
sdram (wx) : ORIGIN = 0x4000000, LENGTH = 0x4000000 |
} |
|
_flash = ORIGIN(flash); |
_blkram = ORIGIN(blkram); |
_sdram = ORIGIN(sdram); |
_top_of_stack = ORIGIN(blkram) + LENGTH(blkram) - 1; |
|
SECTIONS |
{ |
.rocode 0x4e0000 : { |
_boot_address = .; |
*(.start) *(.boot) |
} > flash |
_kernel_image_start = . ; |
.fastcode : { |
*(.kernel) |
_kernel_image_end = . ; |
}> blkram AT> flash |
_sdram_image_start = . ; |
.ramcode : { |
*(.text) |
*(.rodata*) *(.strings) |
*(.data) *(COMMON) *(.bss) |
}> sdram AT> flash |
_sdram_image_end = . ; |
.bss : { |
*(.bss) |
_bss_image_end = . ; |
} > sdram |
_top_of_heap = .; |
} |
/trunk/sw/board/artyboard.h
0,0 → 1,168
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: artyboard.h |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: A description of the hardware and I/O parts and pieces specific |
// to the OpenArty distribution, for the purpose of writing |
// ZipCPU software that will run on the board. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
|
#ifndef ARTYBOARD_H |
#define ARTYBOARD_H |
|
|
// BUS Interrupts |
#define BUS_BUTTON 0x0001 |
#define BUS_SWITCH 0x0002 |
#define BUS_PPS 0x0004 |
#define BUS_RTC 0x0008 |
#define BUS_NETRX 0x0010 |
#define BUS_NETTX 0x0020 |
#define BUS_UARTRX 0x0040 |
#define BUS_UARTTX 0x0080 |
#define BUS_GPIO 0x0100 |
#define BUS_FLASH 0x0200 |
#define BUS_SCOPE 0x0400 |
#define BUS_GPSRX 0x0800 |
#define BUS_SDCARD 0x1000 |
#define BUS_OLED 0x2000 |
#define BUS_ZIP 0x4000 |
// That's our maximum number of interrupts. Any more, and we'll need to |
// remove one. Don't forget, the primary interrupt source will be the SYS_ |
// interrupts, and there's another set of AUX_ interrupts--both available if |
// the ZipSystem is in use. |
|
typedef struct { |
volatile unsigned s_ctrl, s_data; |
} SCOPE; |
#define SCOPE_NO_RESET 0x80000000 |
#define SCOPE_TRIGGER (SCOPE_NO_RESET|0x08000000) |
#define SCOPE_MANUAL SCOPE_TRIGGER |
#define SCOPE_DISABLE 0x04000000 |
|
typedef struct { |
volatile unsigned sd_ctrl, sd_data, sd_fifo[2]; |
} SDCARD; |
|
typedef struct { |
volatile unsigned r_clock, r_stopwach, r_timer, r_alarm; |
} RTC; |
|
typedef struct { |
volatile unsigned g_alpha, g_beta, g_gamma, g_step; |
} GPSTRACKER; |
|
typedef struct { |
volatile unsigned rxcmd, txcmd; |
volatile long mac; |
volatile unsigned rxmiss, rxerr, rxcrc, txcol; |
#define ENET_TXGO 0x004000 |
#define ENET_TXBUSY 0x004000 |
#define ENET_NOHWCRC 0x008000 |
#define ENET_NOHWMAC 0x010000 |
#define ENET_RESET 0x020000 |
#define ENET_TXCMD(LEN) ((LEN)|ENET_TXBIT) |
#define ENET_TXCLR 0x038000 |
#define ENET_TXCANCEL 0x000000 |
#define ENET_RXAVAIL 0x004000 |
#define ENET_RXBUSY 0x008000 |
#define ENET_RXERR 0x010000 |
#define ENET_RXMISS 0x020000 |
#define ENET_RXCRC 0x040000 |
#define ENET_RXLEN rxcmd & 0x0ffff |
#define ENET_RXCLR 0x004000 |
#define ENET_RXCLRERR 0x078000 |
#define ENET_TXBUFLN(NET) (1<<(NET.txcmd>>24)) |
#define ENET_RXBUFLN(NET) (1<<(NET.rxcmd>>24)) |
} ENETPACKET; |
|
typedef struct { |
volatile unsigned o_ctrl, o_a, o_b, o_data; |
} OLEDRGB; |
|
typedef struct { |
volatile unsigned tb_maxcount, tb_jump; |
volatile unsigned long tb_err, tb_count, tb_step; |
} GPSTB; |
|
typedef struct { |
volatile unsigned e_v[32]; |
} ENETMDIO; |
|
typedef struct { |
volatile unsigned f_ereg, f_status, f_nvconfig, f_vconfig, |
f_evconfig, f_flags, f_lock, f_; |
volatile unsigned f_id[5], f_unused[3]; |
volatile unsigned f_otpc, f_otp[16]; |
} EFLASHCTRL; |
|
typedef struct { |
volatile int io_version, io_pic; |
volatile unsigned *io_buserr; |
volatile unsigned io_pwrcount; |
volatile unsigned io_btnsw; |
volatile unsigned io_ledctrl; |
volatile unsigned io_auxsetup, io_gpssetup; |
unsigned io_reserved[32-18]; |
volatile unsigned io_clrled[4]; |
volatile unsigned io_rtcdate; |
volatile unsigned io_gpio; |
volatile unsigned io_uart_rx, io_uart_tx; |
volatile unsigned io_gps_rx, io_gps_tx; |
SCOPE io_scope[4]; |
RTC io_rtc; |
SDCARD io_sd; |
GPSTRACKER io_gps; |
OLEDRGB io_oled; |
ENETPACKET io_enet; |
GPSTB io_gpstb; |
unsigned io_ignore_1[8+16+64]; |
ENETMDIO io_netmdio; |
EFLASHCTRL io_eflash; |
volatile unsigned io_icape2[32]; |
volatile unsigned io_enet_rx[1024]; |
volatile unsigned io_enet_tx[1024]; |
} IOSPACE; |
|
static IOSPACE * const sys = (IOSPACE *)0x0100; |
|
static SDCARD * const sd = (SDCARD *)0x0120; |
|
#define BKRAM (void *)0x0008000 |
#define FLASH (void *)0x0400000 |
#define SDRAM (void *)0x4000000 |
#define CLOCKFREQHZ 80000000 |
#define RAMWORDS 0x800000 |
|
#endif |
/trunk/sw/board/exstartup.c
0,0 → 1,243
#include "artyboard.h" |
#include "zipsys.h" |
|
asm("\t.section\t.start\n" |
"\t.global\t_start\n" |
"_start:\n" |
"\tLDI\t_top_of_stack,SP\n" |
"\tMOV\t_after_bootloader(PC),R0\n" |
"\tBRA\tbootloader\n" |
"_after_bootloader:\n" |
"\tLDI\t_top_of_stack,SP\n" |
"\tOR\t0x4000,CC\n" // Clear the data cache |
"\tMOV\t_kernel_exit(PC),R0\n" |
"\tBRA\tentry\n" |
"_kernel_exit:\n" |
"\tHALT\n" |
"\tBRA\t_kernel_exit\n" |
"\t.section\t.text"); |
|
extern int _sdram_image_end, _sdram_image_start, _sdram, |
_blkram, _flash, _bss_image_end, |
_kernel_image_start, _kernel_image_end; |
|
extern void bootloader(void) __attribute__ ((section (".boot"))); |
|
// #define USE_DMA |
void bootloader(void) { |
int zero = 0; |
|
#ifdef USE_DMA |
zip->dma.ctrl= DMACLEAR; |
zip->dma.rd = _kernel_image_start; |
if (_kernel_image_end != _sdram_image_start) { |
zip->dma.len = _kernel_image_end - _blkram; |
zip->dma.wr = _blkram; |
zip->dma.ctrl= DMACCOPY; |
|
zip->pic = SYSINT_DMAC; |
while((zip->pic & SYSINT_DMAC)==0) |
; |
} |
|
zip->dma.len = &_sdram_image_end - _sdram; |
zip->dma.wr = _sdram; |
zip->dma.ctrl= DMACCOPY; |
|
zip->pic = SYSINT_DMAC; |
while((zip->pic & SYSINT_DMAC)==0) |
; |
|
if (_bss_image_end != _sdram_image_end) { |
zip->dma.len = _bss_image_end - _sdram_image_end; |
zip->dma.rd = &zero; |
// zip->dma.wr // Keeps the same value |
zip->dma.ctrl = DMACCOPY; |
|
zip->pic = SYSINT_DMAC; |
while((zip->pic & SYSINT_DMAC)==0) |
; |
} |
#else |
int *rdp = &_kernel_image_start, *wrp = &_blkram; |
|
// |
// Load any part of the image into block RAM, but *only* if there's a |
// block RAM section in the image. Based upon our LD script, the |
// block RAM should be filled from _blkram to _kernel_image_end. |
// It starts at _kernel_image_start --- our last valid address within |
// the flash address region. |
// |
if (&_kernel_image_end != &_sdram_image_start) { |
for(int i=0; i< &_kernel_image_end - &_blkram; i++) |
*wrp++ = *rdp++; |
} |
|
// |
// Now, we move on to the SDRAM image. We'll here load into SDRAM |
// memory up to the end of the SDRAM image, _sdram_image_end. |
// As with the last pointer, this one is also created for us by the |
// linker. |
// |
wrp = &_sdram; |
for(int i=0; i< &_sdram_image_end - &_sdram; i++) |
*wrp++ = *rdp++; |
|
// |
// Finally, we load BSS. This is the segment that only needs to be |
// cleared to zero. It is available for global variables, but some |
// initialization is expected within it. We start writing where |
// the valid SDRAM context, i.e. the non-zero contents, end. |
// |
for(int i=0; i<&_bss_image_end - &_sdram_image_end; i++) |
*wrp++ = 0; |
#endif |
} |
|
void idle_task(void) { |
while(1) |
zip_idle(); |
} |
|
void entry(void) { |
const unsigned red = 0x0ff0000, green = 0x0ff00, blue = 0x0ff, |
white = 0x070707, black = 0, dimgreen = 0x1f00, |
second = 81250000; |
int i, sw; |
|
int user_context[16]; |
for(i=0; i<15; i++) |
user_context[i] = 0; |
user_context[15] = (unsigned)idle_task; |
zip_restore_context(user_context); |
|
for(i=0; i<4; i++) |
sys->io_clrled[i] = red; |
sys->io_ledctrl = 0x0ff; |
|
// Clear the PIC |
// |
// Acknowledge all interrupts, turn off all interrupts |
// |
zip->pic = 0x7fff7fff; |
while(sys->io_pwrcount < (second >> 4)) |
; |
|
// Repeating timer, every 250ms |
// zip->tma = (second/4) | 0x80000000; |
zip->tma = 1024 | 0x80000000; |
// Restart the PIC -- listening for SYSINT_TMA only |
zip->pic = SYSINT_TMA; |
zip->pic = EINT(SYSINT_TMA)|SYSINT_TMA; |
zip_rtu(); |
|
sys->io_clrled[0] = green; |
sys->io_ledctrl = 0x010; |
|
zip->pic = SYSINT_TMA; |
zip->pic = EINT(SYSINT_TMA)|SYSINT_TMA; |
zip_rtu(); |
|
sys->io_clrled[0] = dimgreen; |
sys->io_clrled[1] = green; |
sys->io_scope[0].s_ctrl = 32 | SCOPE_TRIGGER; |
sys->io_ledctrl = 0x020; |
|
zip->pic = SYSINT_TMA; |
zip->pic = EINT(SYSINT_TMA)|SYSINT_TMA; |
zip_rtu(); |
|
sys->io_clrled[1] = dimgreen; |
sys->io_clrled[2] = green; |
sys->io_ledctrl = 0x040; |
|
zip->pic = SYSINT_TMA; |
zip->pic = EINT(SYSINT_TMA); |
zip_rtu(); |
|
sys->io_clrled[2] = dimgreen; |
sys->io_clrled[3] = green; |
sys->io_ledctrl = 0x080; |
|
zip->pic = SYSINT_TMA; |
zip->pic = EINT(SYSINT_TMA); |
zip_rtu(); |
|
sys->io_clrled[3] = dimgreen; |
|
zip->pic = SYSINT_TMA; |
zip->pic = EINT(SYSINT_TMA); |
zip_rtu(); |
|
for(i=0; i<4; i++) |
sys->io_clrled[i] = black; |
|
// Wait one second ... |
for(i=0; i<4; i++) { |
zip->pic = SYSINT_TMA; |
zip->pic = EINT(SYSINT_TMA); |
zip_rtu(); |
} |
|
sw = sys->io_btnsw & 0x0f; |
for(int i=0; i<4; i++) |
sys->io_clrled[i] = (sw & (1<<i)) ? white : black; |
|
|
// Wait another two second ... |
for(i=0; i<8; i++) { |
zip->pic = SYSINT_TMA; |
zip->pic = EINT(SYSINT_TMA); |
zip_rtu(); |
} |
|
// Blink all the LEDs |
// First turn them on |
sys->io_ledctrl = 0x0ff; |
// Then wait a quarter second |
zip->pic = SYSINT_TMA; |
zip->pic = EINT(SYSINT_TMA)|SYSINT_TMA; |
zip_rtu(); |
// Then turn the back off |
sys->io_ledctrl = 0x0f0; |
// and wait another quarter second |
zip->pic = SYSINT_TMA; |
zip->pic = EINT(SYSINT_TMA)|SYSINT_TMA; |
zip_rtu(); |
|
// Now, read buttons, and flash an LED on any button being held |
// down ... ? neat? |
|
// zip->tma = 20000000; // 1/4 second -- already set |
while(1) { |
unsigned btn, ledc; |
|
zip->pic = SYSINT_TMA; |
zip->pic = EINT(SYSINT_TMA); |
zip_rtu(); |
// If the button is pressed, toggle the LED |
// Otherwise, turn the LED off. |
// |
// First, get all the pressed buttons |
btn = (sys->io_btnsw >> 4) & 0x0f; |
sys->io_btnsw = 0x0f0; |
|
// Of any LEDs that are on, or buttons on, toggle their values |
ledc = (sys->io_ledctrl | btn)&0x0f; |
// Make sure we set everything |
ledc |= 0x0f0; |
// Now issue the command |
sys->io_ledctrl = ledc; |
// That way, at the end, the toggle will leave them in the |
// off position. |
// sys->io_ledctrl = 0xf0 | ((sys->io_ledctrl&1)^1); |
|
sw = sys->io_btnsw & 0x0f; |
for(int i=0; i<4; i++) |
sys->io_clrled[i] = (sw & (1<<i)) ? white : black; |
|
} |
|
zip_halt(); |
} |
|
/trunk/sw/board/zipsys.h
0,0 → 1,136
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: zipsys.h |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: Declare the capabilities and memory structure of the ZipSystem |
// for programs that must interact with it. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
#ifndef ZIPSYS_H |
#define ZIPSYS_H |
|
typedef struct { |
volatile unsigned ck, mem, pf, icnt; |
} ZIPTASKCTRS; |
|
typedef struct { |
volatile int ctrl, len; |
volatile int *rd, *wr; |
} ZIPDMA; |
|
#define DMACLEAR 0xffed0000 |
#define DMACCOPY 0x0fed0000 |
|
typedef struct { |
volatile int pic, wdt, err, apic, tma, tmb, tmc, |
jiffies; |
ZIPTASKCTRS m, u; |
ZIPDMA dma; |
} ZIPSYS; |
|
#define ZIPSYS_ADDR 0xc0000000 |
|
#define SYSINT_DMAC 0x0001 |
#define SYSINT_JIFFIES 0x0002 |
#define SYSINT_TMC 0x0004 |
#define SYSINT_TMB 0x0008 |
#define SYSINT_TMA 0x0010 |
#define SYSINT_AUX 0x0020 |
#define SYSINT_BRD 0x0040 |
// |
#define SYSINT_CK 0x0080 |
#define SYSINT_FLASH 0x0100 |
#define SYSINT_SCOP 0x0200 |
#define SYSINT_GPIO 0x0400 |
#define SYSINT_PWM 0x0800 |
#define SYSINT_UARTRX 0x1000 |
#define SYSINT_UARTTX 0x2000 |
#define SYSINT_SDCARD 0x4000 |
|
|
#define ALTINT_UIC 0x001 |
#define ALTINT_UTC 0x008 |
#define ALTINT_MIC 0x010 |
#define ALTINT_MTC 0x080 |
|
|
#define CC_Z 0x0001 |
#define CC_C 0x0002 |
#define CC_N 0x0004 |
#define CC_V 0x0008 |
#define CC_SLEEP 0x0010 |
#define CC_GIE 0x0020 |
#define CC_STEP 0x0040 |
#define CC_BREAK 0x0080 |
#define CC_ILL 0x0100 |
#define CC_TRAPBIT 0x0200 |
#define CC_BUSERR 0x0400 |
#define CC_DIVERR 0x0800 |
#define CC_FPUERR 0x1000 |
#define CC_IPHASE 0x2000 |
|
// extern void zip_break(void); |
extern void zip_rtu(void); |
extern void zip_halt(void); |
extern void zip_idle(void); |
extern void zip_syscall(void); |
extern void zip_restore_context(int *); |
extern void zip_save_context(int *); |
extern int zip_bitrev(int v); |
extern unsigned zip_cc(void); |
extern unsigned zip_ucc(void); |
|
extern int _top_of_heap[1]; |
|
extern void save_context(int *); |
extern void restore_context(int *); |
extern int syscall(int,int,int,int); |
|
#ifndef NULL |
#define NULL ((void *)0) |
#endif |
|
#define EINT(A) (0x80000000|(A<<16)) |
#define DINT(A) (0x80000000|(A<<16)) |
|
static ZIPSYS *const zip = (ZIPSYS *)(ZIPSYS_ADDR); |
|
static inline void DISABLE_INTS(void) { |
zip->pic = 0; |
} |
|
static inline void ENABLE_INTS(void) { |
zip->pic = 0x80000000; |
} |
|
#endif |
/trunk/sw/host/Makefile
37,18 → 37,22
## |
## |
.PHONY: all |
PROGRAMS := wbregs netuart wbsettime dumpflash wbprogram eqspiscope |
all: $(PROGRAMS) |
PROGRAMS := wbregs netuart wbsettime dumpflash wbprogram netsetup manping zipload zipstate zipdbg |
SCOPES := eqspiscope etxscope erxscope cpuscope |
all: $(PROGRAMS) $(SCOPES) |
CXX := g++ |
OBJDIR := obj-pc |
BUSOBJS := $(OBJDIR)/ttybus.o $(OBJDIR)/llcomms.o $(OBJDIR)/regdefs.o |
SOURCES := wbregs.cpp wbprogram.cpp netuart.cpp wbsettime.cpp \ |
SOURCES := wbregs.cpp wbprogram.cpp netuart.cpp wbsettime.cpp \ |
ttybus.cpp llcomms.cpp dumpflash.cpp eqspiscope.cpp flashdrvr.cpp \ |
portbus.cpp regdefs.cpp scopecls.cpp sdramscope.cpp ttybus.cpp \ |
cfgscope.cpp |
# ziprun.cpp zipload.cpp |
regdefs.cpp scopecls.cpp sdramscope.cpp ttybus.cpp \ |
cfgscope.cpp zipload.cpp zipstate.cpp zipdbg.cpp \ |
erxscope.cpp etxscope.cpp netsetup.cpp cpuscope.cpp \ |
mdioscope.cpp manping.cpp |
# ziprun.cpp |
HEADERS := llcomms.h ttybus.h devbus.h |
OBJECTS := $(addprefix $(OBJDIR)/,$(subst .cpp,.o,$(SOURCES))) |
ZIPD := ../../../../../zipcpu/trunk/sw/zasm |
|
%.o: $(OBJDIR)/%.o |
$(OBJDIR)/%.o: %.cpp |
73,8 → 77,14
$(CXX) -g $^ -o $@ |
mtest: $(OBJDIR)/mtest.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
manping: $(OBJDIR)/manping.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
wbregs: $(OBJDIR)/wbregs.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
zipstate: $(OBJDIR)/zipstate.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
netsetup: $(OBJDIR)/netsetup.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
dumpflash: $(OBJDIR)/dumpflash.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
eqspiscope: $(OBJDIR)/eqspiscope.o $(OBJDIR)/scopecls.o $(BUSOBJS) |
81,20 → 91,43
$(CXX) -g $^ -o $@ |
sdramscope: $(OBJDIR)/sdramscope.o $(OBJDIR)/scopecls.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
wbprogram: $(OBJDIR)/wbprogram.o $(OBJDIR)/flashdrvr.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
zipload: $(OBJDIR)/zipload.o $(OBJDIR)/flashdrvr.o $(BUSOBJS) |
$(CXX) -g $^ -lelf -o $@ |
|
|
## SCOPES |
cfgscope: $(OBJDIR)/cfgscope.o $(OBJDIR)/scopecls.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
wbprogram: $(OBJDIR)/wbprogram.o $(OBJDIR)/flashdrvr.o $(BUSOBJS) |
cpuscope: $(OBJDIR)/cpuscope.o $(OBJDIR)/scopecls.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
# ziprun: $(OBJDIR)/ziprun.o $(OBJDIR)/flashdrvr.o $(BUSOBJS) |
# $(CXX) -g $^ -lelf -o $@ |
# zipdbg: zipdbg.cpp $(ZIPD)/zparser.cpp $(ZIPD)/zopcodes.cpp $(ZIPD)/twoc.cpp $(BUSOBJS) |
# $(CXX) -g -I../bench/cpp -I $(ZIPD)/ $^ -lncurses -o $@ |
# zipstate: zipstate.cpp $(BUSOBJS) |
# $(CXX) -g $^ -o $@ |
erxscope: $(OBJDIR)/erxscope.o $(OBJDIR)/scopecls.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
etxscope: $(OBJDIR)/etxscope.o $(OBJDIR)/scopecls.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
mdioscope: $(OBJDIR)/mdioscope.o $(OBJDIR)/scopecls.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
wbuscope: $(OBJDIR)/wbuscope.o $(OBJDIR)/scopecls.o $(BUSOBJS) |
$(CXX) -g $^ -o $@ |
|
DBGRAW := zparser.cpp zopcodes.cpp twoc.cpp |
DBGSRCS := $(addprefix $(ZIPD)/,$(DBGRAW)) |
DBGOBJS := $(addprefix $(OBJDIR)/,$(subst .cpp,.o,$(DBGRAW))) |
$(OBJDIR)/zipdbg.o: zipdbg.cpp |
$(CXX) -g -I$(ZIPD) -c $< -o $@ |
$(OBJDIR)/zparser.o: $(ZIPD)/zparser.cpp |
$(CXX) -g -I$(ZIPD) -c $< -o $@ |
$(OBJDIR)/zopcodes.o: $(ZIPD)/zopcodes.cpp |
$(CXX) -g -I$(ZIPD) -c $< -o $@ |
$(OBJDIR)/twoc.o: $(ZIPD)/twoc.cpp |
$(CXX) -g -I$(ZIPD) -c $< -o $@ |
zipdbg: $(OBJDIR)/zipdbg.o $(BUSOBJS) $(DBGOBJS) |
$(CXX) -g -I$(ZIPD) $^ -lcurses -o $@ |
|
define build-depends |
@echo "Building dependency file(s)" |
@$(CXX) $(CPPFLAGS) -MM $(SOURCES) > $(OBJDIR)/xdepends.txt |
$(CXX) $(CPPFLAGS) -I$(ZIPD) -MM $(SOURCES) > $(OBJDIR)/xdepends.txt |
@sed -e 's/^.*.o: /$(OBJDIR)\/&/' < $(OBJDIR)/xdepends.txt > $(OBJDIR)/depends.txt |
@rm $(OBJDIR)/xdepends.txt |
endef |
/trunk/sw/host/eqspiscope.cpp
69,7 → 69,7
// int m_oword[2], m_iword[2], m_p; |
public: |
EQSPISCOPE(FPGA *fpga, unsigned addr, bool vecread) |
: SCOPE(fpga, addr, false, false) {}; |
: SCOPE(fpga, addr, false, vecread) {}; |
~EQSPISCOPE(void) {} |
virtual void decode(DEVBUS::BUSW val) const { |
int cyc, cstb, dstb, ack, back, accepted, valid, word, |
/trunk/sw/host/etxscope.cpp
0,0 → 1,112
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: etxscope.cpp |
// |
// Project: XuLA2-LX25 SoC based upon the ZipCPU |
// |
// Purpose: This file decodes the debug bits produced by the enetpackets.v |
// Verilog module, and stored in a Wishbone Scope. It is useful |
// for determining if the packet transmitter works at all or not. |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <strings.h> |
#include <ctype.h> |
#include <string.h> |
#include <signal.h> |
#include <assert.h> |
|
#include "port.h" |
#include "regdefs.h" |
#include "scopecls.h" |
|
#define WBSCOPE R_NETSCOPE |
#define WBSCOPEDATA R_NETSCOPED |
|
FPGA *m_fpga; |
void closeup(int v) { |
m_fpga->kill(); |
exit(0); |
} |
|
class ETXSCOPE : public SCOPE { |
public: |
ETXSCOPE(FPGA *fpga, unsigned addr, bool vecread = true) |
: SCOPE(fpga, addr, false, vecread) {}; |
~ETXSCOPE(void) {} |
virtual void decode(DEVBUS::BUSW val) const { |
int trigger, addr, cancel, cmd, complete, busy, en, txd; |
int lrxclk, ltxclk, txstb; |
|
trigger = (val>>31)&1; |
ltxclk = (val>>30)&1; |
lrxclk = (val>>29)&1; |
addr = (val>>10)&0x0ffff; |
txstb = (val>> 9)&1; |
cancel = (val>> 8)&1; |
cmd = (val>> 7)&1; |
complete= (val>> 6)&1; |
busy = (val>> 5)&1; |
en = (val>> 4)&1; |
txd = (val )&15; |
|
printf("%s %s %s ", |
(lrxclk)?"LRX":" ", |
(ltxclk)?"LTX":" ", |
(txstb)?"TXSTB":" "); |
printf("%s %04x %s%s%s%s %s/%x", |
(trigger)?"TR":" ", |
(addr), |
(cancel)?"X":" ", |
(cmd)?" CMD":" ", |
(complete)?"DON":" ", |
(busy)?"BSY":" ", |
(en)?"EN":" ", txd); |
} |
}; |
|
int main(int argc, char **argv) { |
FPGAOPEN(m_fpga); |
|
signal(SIGSTOP, closeup); |
signal(SIGHUP, closeup); |
|
ETXSCOPE *scope = new ETXSCOPE(m_fpga, WBSCOPE); |
if (!scope->ready()) { |
printf("Scope is not yet ready:\n"); |
scope->decode_control(); |
} else |
scope->read(); |
delete m_fpga; |
} |
|
/trunk/sw/host/flashdrvr.cpp
190,8 → 190,10
|
if (!verify_config()) { |
set_config(); |
if (!verify_config()) |
if (!verify_config()) { |
printf("Invalid configuration, cannot program flash\n"); |
return false; |
} |
} |
|
// Work through this one sector at a time. |
223,6 → 225,7
m_fpga->readi(base, ln, sbuf); |
|
dp = &data[base-addr]; |
SETSCOPE; |
for(unsigned i=0; i<ln; i++) { |
if ((sbuf[i]&dp[i]) != dp[i]) { |
printf("\nNEED-ERASE @0x%08x ... %08x != %08x (Goal)\n", |
/trunk/sw/host/llcomms.cpp
1,8 → 1,8
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
// Filename: llcomms.cpp |
// |
// Project: UART to WISHBONE FPGA library |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: This is the C++ program on the command side that will interact |
// with a UART on an FPGA, both sending and receiving characters. |
10,12 → 10,36
// library to accomplish the actual connection to and |
// transmission to/from the board. |
// |
// Creator: Dan Gisselquist |
// Gisselquist Tecnology, LLC |
// |
// Copyright: 2015 |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
#include <sys/socket.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
/trunk/sw/host/llcomms.h
1,9 → 1,8
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
// Filename: llcomms.cpp |
// |
// Project: UART to WISHBONE FPGA library |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: This is the C++ program on the command side that will interact |
// with a UART on an FPGA, both sending and receiving characters. |
11,12 → 10,35
// library to accomplish the actual connection to and |
// transmission to/from the board. |
// |
// Creator: Dan Gisselquist |
// Gisselquist Tecnology, LLC |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
// Copyright: 2015 |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
#ifndef LLCOMMS_H |
#define LLCOMMS_H |
|
/trunk/sw/host/manping.cpp
0,0 → 1,438
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: manping.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: To command the network to ping a target. |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <strings.h> |
#include <ctype.h> |
#include <string.h> |
#include <signal.h> |
#include <assert.h> |
|
#include "port.h" |
#include "regdefs.h" |
|
#define TXGO 0x04000 |
#define NOHWCRC 0x08000 |
#define NOHWMAC 0x10000 |
#define NETRESET 0x20000 |
|
// |
// Define DONT_INVERT for debugging only, as it will break the interface |
// test |
// |
// #define DONT_INVERT |
|
|
FPGA *m_fpga; |
void closeup(int v) { |
m_fpga->kill(); |
exit(0); |
} |
|
void usage(void) { |
printf("USAGE: manping EN:RX:xx:xx:xx:xx AR:TY:EN:TX:xx:xx de.st.ip.x ar.ty.ip.x\n"); |
} |
|
bool strtoenetaddr(char *s, unsigned char *addr) { |
char *p, *c; |
|
p = s; |
addr[0] = (unsigned char)(strtoul(p, NULL, 16)&0x0ff); |
c = strchr(p,':'); |
if((!c) || ((c-p)>=3)) |
return false; |
|
p = c+1; |
addr[1] = (unsigned char)(strtoul(p, NULL, 16)&0x0ff); |
c = strchr(p,':'); |
if((!c) || ((c-p)>=3)) |
return false; |
|
p = c+1; |
addr[2] = (unsigned char)(strtoul(p, NULL, 16)&0x0ff); |
c = strchr(p,':'); |
if((!c) || ((c-p)>=3)) |
return false; |
|
p = c+1; |
addr[3] = (unsigned char)(strtoul(p, NULL, 16)&0x0ff); |
c = strchr(p,':'); |
if((!c) || ((c-p)>=3)) |
return false; |
|
p = c+1; |
addr[4] = (unsigned char)(strtoul(p, NULL, 16)&0x0ff); |
c = strchr(p,':'); |
if((!c) || ((c-p)>=3)) |
return false; |
|
p = c+1; |
addr[5] = (unsigned char)(strtoul(p, NULL, 16)&0x0ff); |
|
return true; |
} |
|
bool strtoinetaddr(char *s, unsigned char *addr) { |
char *p, *c; |
|
p = s; |
addr[0] = (unsigned char)(strtoul(p, NULL, 10)&0x0ff); |
c = strchr(p,'.'); |
if((!c) || ((c-p)>3)) |
return false; |
|
p = c+1; |
addr[1] = (unsigned char)(strtoul(p, NULL, 10)&0x0ff); |
c = strchr(p,'.'); |
if((!c) || ((c-p)>3)) |
return false; |
|
p = c+1; |
addr[2] = (unsigned char)(strtoul(p, NULL, 10)&0x0ff); |
c = strchr(p,'.'); |
if((!c) || ((c-p)>3)) |
return false; |
|
p = c+1; |
addr[3] = (unsigned char)(strtoul(p, NULL, 10)&0x0ff); |
|
return true; |
} |
|
unsigned calccrc(const int bytelen, const unsigned *buf) { |
const unsigned int taps = 0xedb88320u; |
#ifdef DONT_INVERT |
unsigned int crc = 0; |
#else |
unsigned int crc = 0xffffffff; // initial value |
#endif |
int bidx; |
int bp = 0; |
|
for(bidx = 0; bidx<bytelen; bidx++) { |
if (bidx == 14) |
bidx+=2; |
unsigned char byte = buf[(bidx>>2)]>>(24-((bidx&3)<<3)); |
|
// printf("CRC[%2d]: %02x ([%2d]0x%08x)\n", bidx, byte, (bidx>>2), buf[(bidx>>2)]); |
|
for(int bit=8; --bit>= 0; byte >>= 1) { |
if ((crc ^ byte) & 1) { |
crc >>= 1; |
crc ^= taps; |
} else |
crc >>= 1; |
} bp++; |
} |
#ifndef DONT_INVERT |
crc ^= 0xffffffff; |
#endif |
// Now, we need to reverse these bytes |
// ABCD |
unsigned a,b,c,d; |
a = (crc>>24); // &0x0ff; |
b = (crc>>16)&0x0ff; |
c = (crc>> 8)&0x0ff; |
d = crc; // (crc )&0x0ff; |
crc = (d<<24)|(c<<16)|(b<<8)|a; |
|
// printf("%d bytes processed\n", bp); |
return crc; |
} |
|
void ipchecksum(unsigned *packet) { |
int npkt = (packet[0]>>24)&0x0f; |
unsigned checksum = 0; |
|
packet[2] &= 0xffff0000; |
printf("PKT[2] set to %08x\n", packet[2]); |
printf("checksum = %08x\n", checksum); |
for(int i=0; i<npkt; i++) |
checksum += packet[i] & 0x0ffff; |
printf("checksum = %08x\n", checksum); |
for(int i=0; i<npkt; i++) |
checksum += (packet[i]>>16)&0x0ffff; |
printf("checksum = %08x\n", checksum); |
checksum = (checksum & 0x0ffff) + (checksum >> 16); |
checksum = (checksum & 0x0ffff) + (checksum >> 16); |
packet[2] |= (checksum & 0x0ffff)^0x0ffff; |
|
printf("PKT[2] set to 0x%08x\n", packet[2]); |
checksum = 0; |
for(int i=0; i<npkt; i++) |
checksum += packet[i] & 0x0ffff; |
for(int i=0; i<npkt; i++) |
checksum += (packet[i]>>16)&0x0ffff; |
checksum = (checksum & 0x0ffff) + (checksum >> 16); |
checksum = (checksum & 0x0ffff) + (checksum >> 16); |
checksum ^= 0x0ffff; |
|
assert(checksum == 0); |
} |
|
void clear_scope(FPGA *fpga) { |
unsigned scopev; |
|
scopev = m_fpga->readio(R_NETSCOPE); |
int delay = (scopev>>20)&0x0f; |
delay = (1<<(delay))-32; |
m_fpga->writeio(R_NETSCOPE, (delay)); |
} |
|
int main(int argc, char **argv) { |
int skp=0, port = FPGAPORT; |
bool config_hw_mac = true, config_hw_crc = true; |
FPGA::BUSW txstat; |
int argn; |
unsigned checksum; |
unsigned urand[16], nu = 0; |
|
{ |
FILE *fp; |
for(int i=0; i<16; i++) |
urand[i] = rand(); |
|
// Now, see if we can do better than the library random |
// number generator--but don't fail if we can't. |
fp = fopen("/dev/urandom", "r"); |
if (fp != NULL) { |
int nr = fread(urand, sizeof(short), 16, fp); |
fclose(fp); |
} |
} |
|
|
FPGAOPEN(m_fpga); |
|
signal(SIGSTOP, closeup); |
signal(SIGHUP, closeup); |
|
txstat = m_fpga->readio(R_NET_TXCMD); |
|
// Take the ethernet out of reset |
if ((txstat & NETRESET) != 0) |
m_fpga->writeio(R_NET_TXCMD, (txstat &=(~NETRESET))); |
|
unsigned packet[14]; |
|
unsigned char smac[6], dmac[6]; |
unsigned char sip[4], dip[4]; |
|
// I know the ethernet MAC of the computer I wish to test with |
dmac[0] = 0xc8; dmac[1] = 0x3a; dmac[2] = 0x35; |
dmac[3] = 0xd2; dmac[4] = 0x07; dmac[5] = 0xb1; |
// And just something from /dev/urandom to create our source address |
smac[0] = 0xd2; smac[1] = 0xd8; smac[2] = 0x28; |
smac[3] = 0xe8; smac[4] = 0xb0; smac[5] = 0x96; |
|
// Similarly with the destination IP of the computer I wish to test with |
dip[0] = 192; dip[1] = 168; dip[2] = 10; dip[3] = 1; |
// and let's pick a source IP just ... somewhere on that network |
sip[0] = 192; sip[1] = 168; sip[2] = 10; sip[3] = 22; |
|
clear_scope(m_fpga); |
|
argn = 1; |
|
{ |
bool bad_address = false; |
char *badp = NULL; |
if ((argn<argc)&&(strchr(argv[argn], ':'))) { |
if (!strtoenetaddr(argv[argn++], dmac)) { |
badp = argv[argn-1]; |
bad_address = true; |
} else if ((argn<argc)&&(strchr(argv[argn], ':'))) { |
if (!strtoenetaddr(argv[argn++], smac)) { |
badp = argv[argn-1]; |
bad_address = true; |
} |
} |
} if ((argn<argc)&&(!bad_address)&&(strchr(argv[argn], '.'))) { |
if (!strtoinetaddr(argv[argn++], dip)) { |
badp = argv[argn-1]; |
bad_address = true; |
} else if ((argn<argc)&&(strchr(argv[argn], '.'))) { |
if (!strtoinetaddr(argv[argn++], sip)) { |
badp = argv[argn-1]; |
bad_address = true; |
} |
} |
} |
|
if (bad_address) { |
usage(); |
fprintf(stderr, "ERR: could not comprehend address, %s\n", badp); |
exit(EXIT_FAILURE); |
} |
} |
|
printf("Building packet\n"); |
printf("From %3d.%3d.%3d.%3d [%02x:%02x:%02x:%02x:%02x:%02x]\n", |
sip[0], sip[1], sip[2], sip[3], |
smac[0], smac[1], smac[2], smac[3], smac[4], smac[5]); |
printf("To %3d.%3d.%3d.%3d [%02x:%02x:%02x:%02x:%02x:%02x]\n", |
dip[0], dip[1], dip[2], dip[3], |
dmac[0], dmac[1], dmac[2], dmac[3], dmac[4], dmac[5]); |
|
|
// Let's build ourselves a ping packet |
packet[ 0] = (dmac[0]<<24)|(dmac[1]<<16)|(dmac[2]<<8)|(dmac[3]); |
packet[ 1] = (dmac[4]<<24)|(dmac[5]<<16)|(smac[0]<<8)|(smac[1]); |
packet[ 2] = (smac[2]<<24)|(smac[3]<<16)|(smac[4]<<8)|(smac[5]); |
packet[ 3] = 0x08000800; |
packet[ 4] = 0x4500001c; // IPv4, 20byte header, type of service = 0 |
packet[ 5] = (urand[nu++]&0xffff0000); // Packet ID |
packet[ 6] = 0x80010000; // no flags, fragment offset=0, ttl=0, proto=1 |
packet[ 7] = (sip[0]<<24)|(sip[1]<<16)|(sip[2]<<8)|(sip[3]); |
packet[ 8] = (dip[0]<<24)|(dip[1]<<16)|(dip[2]<<8)|(dip[3]); |
// Ping payload: type = 0x08 (PING, the response will be zero) |
// CODE = 0 |
// Checksum will be filled in later |
packet[ 9] = 0x08000000; |
// This is the PING identifier and sequence number. For now, we'll |
// just feed it random information--doesn't really matter what |
packet[10] = urand[nu++]; |
// Now, the minimum ethernet packet is 16 words. So, let's flush |
// ourselves out to that minimum length. |
packet[11] = 0; |
packet[12] = 0; |
packet[13] = 0; |
packet[14] = 0; |
|
// Calculate the IP header checksum |
ipchecksum(&packet[4]); |
|
// Calculate the PING payload checksum |
checksum = packet[ 9] & 0x0ffff; |
checksum += (packet[ 9]>>16)&0x0ffff; |
checksum += packet[10] & 0x0ffff; |
checksum += (packet[10]>>16)&0x0ffff; |
checksum = ((checksum >> 16)&0x0ffff) + (checksum & 0x0ffff); |
checksum = ((checksum >> 16)&0x0ffff) + (checksum & 0x0ffff); |
packet[ 9] = ((packet[9] & 0xffff0000)|(checksum))^0x0ffff; |
|
// Calculate the CRC--assuming we'll use it. |
packet[15] = calccrc(15*4, packet); |
|
// Clear any/all pending receiving errors or packets |
m_fpga->writeio(R_NET_RXCMD, 0x0fffff); |
if (config_hw_mac) { |
int ln; |
|
m_fpga->writeio(R_NET_MACHI, (smac[0]<<8)|(smac[1])); |
m_fpga->writeio(R_NET_MACLO, (smac[2]<<24)|(smac[3]<<16)|(smac[4]<<8)|(smac[5])); |
|
// Now, let's rebuild our packet for the non-hw-mac option, |
// now that we know the CRC. In general, we're just going |
// to copy the packet we created earlier, but we need to |
// shift things as we do so. |
packet[ 0] = (dmac[0]<<24)|(dmac[1]<<16)|(dmac[2]<<8)|(dmac[3]); |
packet[ 1] = (dmac[4]<<24)|(dmac[5]<<16)|0x0800; |
packet[ 2] = packet[ 4]; |
packet[ 3] = packet[ 5]; |
packet[ 4] = packet[ 6]; |
packet[ 5] = packet[ 7]; |
packet[ 6] = packet[ 8]; |
packet[ 7] = packet[ 9]; |
packet[ 8] = packet[10]; |
packet[ 9] = packet[11]; |
packet[10] = packet[12]; |
packet[11] = packet[13]; |
packet[12] = packet[14]; |
packet[13] = packet[15]; |
|
ln = (config_hw_crc)?9:14; |
printf("Packet:\n"); |
for(int i=0; i<14; i++) |
printf("\t%2d: 0x%08x\n", i, packet[i]); |
|
// Load the packet into the hardware buffer |
m_fpga->writei(R_NET_TXBUF, ln, packet); |
|
// And give it the transmit command. |
m_fpga->writeio(R_NET_TXCMD, TXGO|(ln<<2)|((config_hw_crc)?0:NOHWCRC)); |
|
} else { |
int ln; |
|
ln = (config_hw_crc)?11:12; |
printf("Packet:\n"); |
for(int i=0; i<15; i++) |
printf("\t%3d: 0x%08x\n", i, packet[i]); |
printf("\tCRC: 0x%08x\n", packet[15]); |
|
// Load the packet into the hardware buffer |
m_fpga->writei(R_NET_TXBUF, ln, packet); |
|
// And give it the transmit command |
m_fpga->writeio(R_NET_TXCMD, TXGO|NOHWMAC|(ln<<2)|((config_hw_crc)?0:NOHWCRC)); |
} |
|
// First, we need to look for any ARP requests, and we'll need to |
// respond to them. If during this time we get a ping response |
// packet, we're done. |
|
printf("\nLooking for a response ...\n"); |
unsigned rxstat; |
int errcount = 0; |
do { |
rxstat = m_fpga->readio(R_NET_RXCMD); |
if (rxstat & 0x04000) { |
int rxlen; |
unsigned *buf; |
printf("RX Status = %08x\n", rxstat); |
rxlen = ((rxstat & 0x03fff)+3)>>2; |
buf = new unsigned[rxlen]; |
m_fpga->readi(R_NET_RXBUF, rxlen, buf); |
for(int i=0; i<rxlen; i++) |
printf("\tRX[%2d]: 0x%08x\n", i, buf[i]); |
delete[] buf; |
m_fpga->writeio(R_NET_RXCMD, 0xffffff); |
break; |
} |
} while(((rxstat & 0x04000)==0)&&(errcount++ < 50)); |
|
rxstat = m_fpga->readio(R_NET_RXCMD); |
printf("Final Rx Status = %08x\n", rxstat); |
|
|
delete m_fpga; |
} |
|
/trunk/sw/host/mdioscope.cpp
0,0 → 1,112
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: mdioscope.cpp |
// |
// Project: XuLA2-LX25 SoC based upon the ZipCPU |
// |
// Purpose: |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <strings.h> |
#include <ctype.h> |
#include <string.h> |
#include <signal.h> |
#include <assert.h> |
|
#include "port.h" |
#include "regdefs.h" |
#include "scopecls.h" |
|
#define WBSCOPE R_NETSCOPE |
#define WBSCOPEDATA R_NETSCOPED |
|
FPGA *m_fpga; |
void closeup(int v) { |
m_fpga->kill(); |
exit(0); |
} |
|
class MDIOSCOPE : public SCOPE { |
public: |
MDIOSCOPE(FPGA *fpga, unsigned addr, bool vecread) |
: SCOPE(fpga, addr, false, false) {}; |
~MDIOSCOPE(void) {} |
virtual void decode(DEVBUS::BUSW val) const { |
int wbstall, wbstb, wbwe, wbaddr, |
wback, rclk, zclk, zreg, wbdata, regpos, ctstate, rpend, |
mdclk, mdwe, omdio, imdio; |
|
wbstall = (val>>31)&1; |
wbstb = (val>>30)&1; |
wbwe = (val>>29)&1; |
wbaddr = (val>>24)&0x01f; |
wback = (val>>23)&1; |
wbdata = (val>>16)&0x03f; |
|
rclk = (val>>22)&1; |
zreg = (val>>10)&1; |
zclk = (val>>9)&1; |
regpos = (val>>8)&0x3f; |
rpend = (val>>7)&1; |
ctstate = (val>>4)&7; |
|
mdclk = (val&8)?1:0; |
mdwe = (val&4)?1:0; |
omdio = (val&2)?1:0; |
imdio = (val&1)?1:0; |
|
printf("WB[%s%s@%2x -> %s%s/%04x] (%d%d%d,%2d,%2x%s) MDIO[%s%s %d-%d]", |
(wbstb)?"STB":" ", (wbwe)?"WE":" ", (wbaddr), |
(wback)?"ACK":" ",(wbstall)?"STALL":" ", (wbdata), |
zclk, rclk, zreg, regpos, ctstate, |
(rpend)?"R":" ", |
(mdclk)?"CLK":" ", (mdwe)?"WE":" ",(omdio),(imdio)); |
} |
}; |
|
int main(int argc, char **argv) { |
FPGAOPEN(m_fpga); |
|
signal(SIGSTOP, closeup); |
signal(SIGHUP, closeup); |
|
MDIOSCOPE *scope = new MDIOSCOPE(m_fpga, WBSCOPE, false); |
if (!scope->ready()) { |
printf("Scope is not yet ready:\n"); |
scope->decode_control(); |
} else |
scope->read(); |
delete m_fpga; |
} |
|
/trunk/sw/host/netsetup.cpp
0,0 → 1,255
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: netsetup.cpp |
// |
// Project: OpenArty, an entirely open SoC based upon the Arty platform |
// |
// Purpose: |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <strings.h> |
#include <ctype.h> |
#include <string.h> |
#include <signal.h> |
#include <assert.h> |
|
#include "port.h" |
#include "regdefs.h" |
|
FPGA *m_fpga; |
void closeup(int v) { |
m_fpga->kill(); |
exit(0); |
} |
|
void usage(void) { |
printf("USAGE: netsetup\n"); |
} |
|
int main(int argc, char **argv) { |
int skp=0, port = FPGAPORT; |
|
FPGAOPEN(m_fpga); |
|
signal(SIGSTOP, closeup); |
signal(SIGHUP, closeup); |
|
if ((argc < 1)||(argc > 2)) { |
// usage(); |
printf("USAGE: netsetup\n"); |
exit(-1); |
} |
|
unsigned v; |
v = m_fpga->readio(R_MDIO_BMCR); |
printf(" BMCR %04x\tBasic Mode Control Register\n", v); |
if (v & 0x08000) |
printf(" \tReset in progress\n"); |
if (v & 0x04000) |
printf(" \tLoopback enabled\n"); |
if (v & 0x01000) |
printf(" \tAuto-negotiation enabled\n"); |
else if (v & 0x02000) |
printf(" \t100Mb/s -- manual selection\n"); |
else |
printf(" \t 10Mb/s -- manual selection\n"); |
if (v & 0x00800) |
printf(" \tPHY is powered down\n"); |
if (v & 0x00400) |
printf(" \tPort is isolated from MII\n"); |
if (v & 0x00200) |
printf(" \tRestart-auto-negotiation\n"); |
if ((v& 0x00100)==0) |
printf(" \tHalf-duplex mode\n"); |
if (v & 0x00080) |
printf(" \tCollision test enabled\n"); |
v = m_fpga->readio(R_MDIO_BMSR); |
printf("R/O BMSR %04x\tBasic Mode Status Register\n", v); |
if (v & 0x08000) |
printf(" \t100Base-T4 capable\n"); |
if (v & 0x04000) |
printf(" \t100Base-TX Full Duplex capable\n"); |
if (v & 0x02000) |
printf(" \t100Base-TX Half Duplex capable\n"); |
if (v & 0x01000) |
printf(" \t 10Base-TX Full Duplex capable\n"); |
if (v & 0x00800) |
printf(" \t 10Base-TX Half Duplex capable\n"); |
if (v & 0x00040) |
printf(" \tPreamble suppression capable\n"); |
if (v & 0x00020) |
printf(" \tAuto-negotiation complete\n"); |
if (v & 0x00010) |
printf(" \tRemote fault detected\n"); |
if (v & 0x00008) |
printf(" \tDevice is capable of auto-negotiation\n"); |
if (v & 0x00004) |
printf(" \tLink is up\n"); |
if (v & 0x00002) |
printf(" \tJabber condition detected (10Mb/s mode)\n"); |
if (v & 0x00001) |
printf(" \tExtended register capabilities\n"); |
v = m_fpga->readio(R_MDIO_PHYIDR1); |
printf("R/O PHYID1 %04x\tPHY Identifier Reg #1\n", v); |
//printf(" %4x\tOUI MSB\n", v); |
v = m_fpga->readio(R_MDIO_PHYIDR2); |
printf("R/O PHYID2 %04x\tPHY Identifier Reg #2\n", v); |
printf(" %4x\tOUI LSBs\n", (v>>10)&0x3f); |
printf(" %4x\tVendor model number\n", (v>>4)&0x3f); |
printf(" %4x\tModel revision number\n", v&0x0f); |
v = m_fpga->readio(R_MDIO_ANAR); |
printf(" ANAR %04x\tAuto-negotiation advertisement register\n", v); |
v = m_fpga->readio(R_MDIO_ANLPAR); |
printf(" ANLPAR %04x\tAuto-negotiation link partner ability\n", v); |
v = m_fpga->readio(R_MDIO_ANER); |
printf(" ANER %04x\tAuto-negotiation expansion register\n", v); |
v = m_fpga->readio(R_MDIO_ANNPTR); |
printf(" ANNPTR %04x\tAuto-negotiation Next page TX\n", v); |
v = m_fpga->readio(R_MDIO_PHYSTS); |
printf("R/O PHYSTS %04x\tPHY status register\n", v); |
if (v&0x4000) |
printf(" \tMDI pairs swapped\n"); |
if (v&0x2000) |
printf(" \tReceive error event since last read of RXERCNT\n"); |
if (v&0x1000) |
printf(" \tInverted polarity detected\n"); |
if (v&0x800) |
printf(" \tFalse carrier sense latch\n"); |
if (v&0x400) |
printf(" \tUnconditional signal detection from PMD\n"); |
if (v&0x200) |
printf(" \tDescrambler lock from PMD\n"); |
if (v&0x100) |
printf(" \tNew link codeword page has been received\n"); |
if (v&0x40) |
printf(" \tRemote fault condition detected\n"); |
if (v&0x20) |
printf(" \tJabber condition detected\n"); |
if (v&0x10) |
printf(" \tAuto-negotiation complete\n"); |
if (v&0x08) |
printf(" \tLoopback enabled\n"); |
if (v&0x04) |
printf(" \tFull duplex mode\n"); |
printf(" %3d\tSpeed from autonegotiation\n", (v&2)?10:100); |
if ((v&0x01)==0) |
printf(" \tNo link established\n"); |
v = m_fpga->readio(R_MDIO_FCSCR); |
printf(" FCSCR %04x\tFalse Carrier Sense Counter Register\n", v); |
v = m_fpga->readio(R_MDIO_RECR); |
printf(" RECR %04x\tReceive Error Counter Register\n", v); |
v = m_fpga->readio(R_MDIO_PCSR); |
printf(" PCSR %04x\tPCB Sub-Layer Configuration and Status Register\n", v); |
if (v&0x400) |
printf(" \tTrue Quiet (TQ) mode enabled\n"); |
if (v&0x200) |
printf(" \tSignal detecttion forced in PMA\n"); |
if (v&0x100) |
printf(" \tEnhanced signal detetion algorithm\n"); |
if (v&0x80) |
printf(" \tDescrambler timeout = 2ms (for large packets)\n"); |
if (v&0x20) |
printf(" \tForce 100Mb/s good link\n"); |
if (v&0x4) |
printf(" \tNRZI bypass enabled\n"); |
v = m_fpga->readio(R_MDIO_RBR); |
printf(" RBR %04x\tRMII and Bypass Register\n", v); |
if (v&0x20) |
printf(" \tRMII mode enabled\n"); |
v = m_fpga->readio(R_MDIO_LEDCR); |
printf(" LEDCR %04x\tLED Direct Control Register\n", v); |
if (v&0x20) |
printf(" %s\tLED_SPEED LED\n", (v&0x4)?"ON ":"OFF"); |
if (v&0x10) |
printf(" %s\tLED_LINK LED\n", (v&0x2)?"ON ":"OFF"); |
|
v = m_fpga->readio(R_MDIO_PHYCR); |
printf(" PHYCR %04x\tPHY control register\n", v); |
if (v&0x8000) |
printf(" \tAuto-neg auto-MDIX enabled\n"); |
if (v&0x4000) |
printf(" \tForce MDI pairs to cross\n"); |
if (v&0x2000) |
printf(" \tPause receive negotiation\n"); |
if (v&0x1000) |
printf(" \tPause transmit negotiation\n"); |
if (v&0x0800) |
printf(" \tForce BIST error\n"); |
if (v&0x0400) |
printf(" \tPSR15 BIST sequence selected\n"); |
if (v&0x0200) |
printf(" \tBIST test passed\n"); |
if (v&0x0100) |
printf(" \tBIST start\n"); |
if (v&0x0080) |
printf(" \tBypass LED stretching\n"); |
if ((v&0x0020)==0) |
printf(" \tDon\'t blink LED\'s on activity\n"); |
if (v&0x001f) |
printf(" %4x\tPHY Addr\n", v & 0x01f); |
v = m_fpga->readio(R_MDIO_BTSCR); |
printf(" BTSCR %04x\t10-Base T Status/Control Register\n", v); |
v = m_fpga->readio(R_MDIO_CDCTRL); |
printf(" CDCTRL %04x\tCD Test Control Register, BIST Extension Register\n", v); |
if (v&0xff00) |
printf(" %04x\tBIST error counter\n", (v>>8)&0x0ff); |
if (v&0x20) |
printf(" \tPacket BIST continuous mode\n"); |
if (v&0x10) |
printf(" \tCD pattern enable for 10Mb\n"); |
v = m_fpga->readio(R_MDIO_EDCR); |
printf(" EDCR %04x\tEnergy Detect Control Register\n", v); |
if (v&0x8000) |
printf(" \tEnergy detect mode enabled\n"); |
if (v&0x4000) |
printf(" \tEnergy detect power up\n"); |
if (v&0x2000) |
printf(" \tEnergy detect power down\n"); |
if (v&0x1000) |
printf(" \tEnergy detect manual power up/down\n"); |
if (v&0x0800) |
printf(" \tDisable bursting of energy detection bursts\n"); |
if (v&0x0400) |
printf(" \tED Power state\n"); |
if (v&0x0200) |
printf(" \tEnergy detect err threshold met\n"); |
if (v&0x0100) |
printf(" \tEnergy detect data threshold met\n"); |
printf(" %04x\tEnergy detect err threshold\n", (v>>4)&15); |
printf(" %04x\tEnergy detect data threshold\n", (v)&15); |
|
delete m_fpga; |
} |
|
/trunk/sw/host/netuart.cpp
282,13 → 282,14
cfmakeraw(&tb); // Sets no parity, 8 bits, one stop bit |
tb.c_cflag &= (~(CRTSCTS)); // Sets no parity, 8 bit |
tb.c_cflag &= (~(CSTOPB)); // One stop bit |
// #define LOW_SPEED |
#ifndef LOW_SPEED |
// Switch to 7 bit |
tb.c_cflag &= ~(CSIZE); |
tb.c_cflag |= CS7; |
// And 4 MBaud |
cfsetispeed(&tb, B4000000); |
cfsetospeed(&tb, B4000000); |
cfsetispeed(&tb, B1000000); |
cfsetospeed(&tb, B1000000); |
#else |
// Set the speed to 115200 baud |
cfsetispeed(&tb, B115200); |
/trunk/sw/host/port.h
39,7 → 39,8
#define PORT_H |
|
// #define FPGAHOST "lazarus" |
#define FPGAHOST "localhost" |
#define FPGAHOST "jericho" |
// #define FPGAHOST "localhost" |
#define FPGATTY "/dev/ttyUSB1" |
#define FPGAPORT 6510 |
|
/trunk/sw/host/program.sh
5,8 → 5,8
## |
## Project: OpenArty, an entirely open SoC based upon the Arty platform |
## |
## Purpose: To install a new program into the Arty, using the main |
## programming slot (slot 0). |
## Purpose: To install a new program into the Arty, using the alternate |
## programming slot (slot 1, starting at 0x470000). |
## |
## Creator: Dan Gisselquist, Ph.D. |
## Gisselquist Technology, LLC |
38,23 → 38,21
## |
## |
export PATH=$PATH:. |
export BINFILE=../../xilinx/openarty/openarty.runs/impl_1/fasttop.bin |
export BINFILE=../../xilinx/openarty.runs/impl_1/toplevel.bit |
|
WBREGS=wbregs |
WBPROG=wbprogram |
|
# |
$WBREGS qspiv 0x8b |
# $WBREGS qspiv 0x8b # Accomplished by the flash driver |
# |
$WBREGS clock 0x023fffff # Show the stopwatch |
$WBREGS stopwatch 2 # Clear and stop the stopwatch |
$WBREGS stopwatch 1 # Start the stopwatch |
echo $WBPROG @0x0400000 $BINFILE |
$WBPROG @0x0400000 $BINFILE |
$WBPROG @0x0470000 $BINFILE |
$WBREGS stopwatch 0 # Stop the stopwatch, we are done |
$WBREGS stopwatch # Print out the time on the stopwatch |
|
$WBREGS wbstar 0 |
$WBREGS wbstar 0x01c0000 |
$WBREGS fpgacmd 15 |
sleep 1 |
|
61,11 → 59,11
|
RED=0x00ff0000 |
GREEN=0x0000ff00 |
WHITE=0x000f0f0f |
WHITE=0x00070707 |
BLACK=0x00000000 |
DIMGREEN=0x00001f00 |
|
$WBREGS led 0x0f |
$WBREGS led 0x0ff |
$WBREGS clrled0 $RED |
$WBREGS clrled1 $RED |
$WBREGS clrled2 $RED |
92,8 → 90,8
$WBREGS led 0x80 |
sleep 1 |
$WBREGS clrled0 $WHITE |
$WBREGS clrled1 $BLACK |
$WBREGS clrled2 $BLACK |
$WBREGS clrled1 $WHITE |
$WBREGS clrled2 $WHITE |
$WBREGS clrled3 $WHITE |
$WBREGS led 0x00 |
|
/trunk/sw/host/regdefs.cpp
89,6 → 89,9
{ R_QSCOPED, "SCDATA" }, |
{ R_QSCOPED, "SCOPED" }, |
{ R_QSCOPED, "SCOPD" }, |
{ R_CPUSCOPE, "CPUSCOPE" }, |
{ R_CPUSCOPED, "CPUSCOPD" }, |
{ R_CPUSCOPED, "CPUSCOPED" }, |
{ R_GPSCOPE, "GPSSCOPE" }, // Scope one |
{ R_GPSCOPE, "GPSSCOP" }, |
{ R_GPSCOPED, "GPSSCDATA" }, |
98,6 → 101,8
{ R_CFGSCOPE, "CFGSCOP" }, |
{ R_CFGSCOPED, "CFGSCDATA" }, |
{ R_CFGSCOPED, "CFGSCD" }, |
{ R_BUSSCOPE, "BUSSCOPE" }, // Scope one |
{ R_BUSSCOPED, "BUSSCOPD" }, |
{ R_RAMSCOPE, "RAMSCOPE" }, // Scope two |
{ R_RAMSCOPE, "RAMSCOP" }, |
{ R_RAMSCOPED, "RAMSCOPD" }, |
146,7 → 151,16
{ R_GPSTB_COUNTLO, "CNTLO" }, |
{ R_GPSTB_STEPHI, "STEPHI" }, |
{ R_GPSTB_STEPLO, "STEPLO" }, |
// |
// Ethernet, packet control registers |
{ R_NET_RXCMD, "RXCMD" }, |
{ R_NET_RXCMD, "NETRX" }, |
{ R_NET_TXCMD, "TXCMD" }, |
{ R_NET_TXCMD, "NETTX" }, |
{ R_NET_MACHI, "MACHI" }, |
{ R_NET_MACLO, "MACLO" }, |
{ R_NET_RXMISS, "NETMISS" }, |
{ R_NET_RXERR, "NETERR" }, |
{ R_NET_RXCRC, "NETXCRC" }, |
// Ethernet MDIO registers |
{ R_MDIO_BMCR, "BMCR" }, |
{ R_MDIO_BMSR, "BMSR" }, |
/trunk/sw/host/regdefs.h
57,15 → 57,19
#define R_GPSRX 0x00000110 |
#define R_GPSTX 0x00000111 |
// WB Scope registers |
#define R_QSCOPE 0x00000120 // Quad SPI scope ctrl |
#define R_QSCOPE 0x00000120 // Scope #0: Quad SPI scope ctrl |
#define R_QSCOPED 0x00000121 // and data |
#define R_GPSCOPE 0x00000122 // GPS configuration scope control |
#define R_CPUSCOPE 0x00000120 // CPU scope (if so configured) |
#define R_CPUSCOPED 0x00000121 // and data |
#define R_GPSCOPE 0x00000122 // Scope #1: GPS config scope control |
#define R_GPSCOPED 0x00000123 // and data |
#define R_CFGSCOPE 0x00000122 // ICAPE2 configuration scop control |
#define R_CFGSCOPED 0x00000123 // and data |
#define R_RAMSCOPE 0x00000124 // DDR3 SDRAM Scope |
#define R_BUSSCOPE 0x00000122 // WBUBUS scope control |
#define R_BUSSCOPED 0x00000123 // and data |
#define R_RAMSCOPE 0x00000124 // Scope #2: DDR3 SDRAM Scope |
#define R_RAMSCOPED 0x00000125 // |
#define R_NETSCOPE 0x00000126 // Ethernet debug scope |
#define R_NETSCOPE 0x00000126 // Scope #3: Ethernet debug scope |
#define R_NETSCOPED 0x00000127 // |
// RTC Clock Registers |
#define R_CLOCK 0x00000128 |
82,12 → 86,20
#define R_GPS_BETA 0x00000131 |
#define R_GPS_GAMMA 0x00000132 |
#define R_GPS_STEP 0x00000133 |
// Network packet interface, 0x0134 |
// OLED |
#define R_OLED_CMD 0x00000138 |
#define R_OLED_CDATA 0x00000139 |
#define R_OLED_CDATB 0x0000013a |
#define R_OLED_DATA 0x0000013b |
#define R_OLED_CMD 0x00000134 |
#define R_OLED_CDATA 0x00000135 |
#define R_OLED_CDATB 0x00000136 |
#define R_OLED_DATA 0x00000137 |
// Network packet interface, 0x0184 |
#define R_NET_RXCMD 0x00000138 |
#define R_NET_TXCMD 0x00000139 |
#define R_NET_MACHI 0x0000013a |
#define R_NET_MACLO 0x0000013b |
#define R_NET_RXMISS 0x0000013c |
#define R_NET_RXERR 0x0000013d |
#define R_NET_RXCRC 0x0000013e |
#define R_NET_TXCOL 0x0000013f |
// Unused: 0x13c-0x13f |
// GPS Testbench: 0x140-0x147 |
#define R_GPSTB_FREQ 0x00000140 |
158,11 → 170,15
#define R_CFG_BOOTSTS 0x000001f6 |
#define R_CFG_CTL1 0x000001f8 |
#define R_CFG_BSPI 0x000001ff |
// Network buffer space |
#define R_NET_RXBUF 0x00000800 |
#define R_NET_TXBUF 0x00000c00 |
// Block RAM memory space |
#define MEMBASE 0x00008000 |
#define MEMWORDS 0x00008000 |
// Flash memory space |
#define EQSPIFLASH 0x00400000 |
#define RESET_ADDRESS 0x004e0000 |
#define FLASHWORDS (1<<22) |
// DDR3 SDRAM memory space |
#define RAMBASE 0x04000000 |
169,8 → 185,8
#define SDRAMBASE RAMBASE |
#define RAMWORDS (1<<26) |
// Zip CPU Control and Debug registers |
#define R_ZIPCTRL 0x01000000 |
#define R_ZIPDATA 0x01000001 |
#define R_ZIPCTRL 0x08000000 |
#define R_ZIPDATA 0x08000001 |
|
// Interrupt control constants |
#define GIE 0x80000000 // Enable all interrupts |
203,17 → 219,18
#define CPU_STALL 0x0200 |
#define CPU_HALT 0x0400 |
#define CPU_CLRCACHE 0x0800 |
#define CPU_sR0 (0x0000|CPU_HALT) |
#define CPU_sSP (0x000d|CPU_HALT) |
#define CPU_sCC (0x000e|CPU_HALT) |
#define CPU_sPC (0x000f|CPU_HALT) |
#define CPU_uR0 (0x0010|CPU_HALT) |
#define CPU_uSP (0x001d|CPU_HALT) |
#define CPU_uCC (0x001e|CPU_HALT) |
#define CPU_uPC (0x001f|CPU_HALT) |
#define CPU_sR0 0x0000 |
#define CPU_sSP 0x000d |
#define CPU_sCC 0x000e |
#define CPU_sPC 0x000f |
#define CPU_uR0 0x0010 |
#define CPU_uSP 0x001d |
#define CPU_uCC 0x001e |
#define CPU_uPC 0x001f |
|
#define SCOPE_NO_RESET 0x80000000 |
#define SCOPE_TRIGGER (0x08000000|SCOPE_NO_RESET) |
#define SCOPE_MANUAL SCOPE_TRIGGER |
#define SCOPE_DISABLE (0x04000000) |
|
typedef struct { |
/trunk/sw/host/sdramscope.cpp
0,0 → 1,169
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: sdramscope.cpp |
// |
// Project: XuLA2-LX25 SoC based upon the ZipCPU |
// |
// Purpose: |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <strings.h> |
#include <ctype.h> |
#include <string.h> |
#include <signal.h> |
#include <assert.h> |
|
#include "port.h" |
#include "regdefs.h" |
#include "scopecls.h" |
|
#define WBSCOPE R_RAMSCOPE |
#define WBSCOPEDATA R_RAMSCOPED |
|
FPGA *m_fpga; |
void closeup(int v) { |
m_fpga->kill(); |
exit(0); |
} |
|
class RAMSCOPE : public SCOPE { |
public: |
RAMSCOPE(FPGA *fpga, unsigned addr, bool vecread) |
: SCOPE(fpga, addr, false, false) {}; |
~RAMSCOPE(void) {} |
virtual void decode(DEVBUS::BUSW val) const { |
/* |
int ras, cas, wen, stb, we, stall, ack, dqs, dm, oe, addr, |
odat, idat, wdbg, cmd; |
static const char *cmdstr[] = { "[MRSET]", "[REFRESH]", |
"[PRECHARGE]", "[ACTIVATE]", "[WRITE]", |
"[READ]", "[ZQS]", "[NOOP]" |
}; |
|
ras = (val>>31)&1; |
cas = (val>>30)&1; |
wen = (val>>29)&1; |
stb = (val>>28)&1; |
we = (val>>27)&1; |
stall = (val>>26)&1; |
ack = (val>>25)&1; |
dqs = (val>>24)&1; |
dm = (val>>23)&1; |
oe = (val>>22)&1; |
addr = (val>>20)&3; |
odat = (val>>14)&63; |
idat = (val>>8)&63; |
wdbg = (val )&0xff; |
|
cmd = (ras<<2)|(cas<<1)|wen; |
printf("%s%s%s%s %s%s%s %x %2xO %2xI %4xW %d%d%d%s", |
(stb)?"S":" ", |
(we)?"W":"R", |
(stall)?"S":" ", |
(ack)?"AK":" ", |
// |
dqs?"D":" ",dm?"M":" ",oe?"W":"z", |
addr, odat, idat, wdbg, |
ras,cas,wen, |
cmdstr[cmd]); |
*/ |
int stb, stall, ack, err, head, tail, rid, |
arvalid, arready, awvalid, awready, wvalid, wready, |
rvalid, bvalid; |
|
stb = (val>>31)&1; |
stall = (val>>30)&1; |
ack = (val>>29)&1; |
err = (val>>28)&1; |
head = (val>>22)&0x03f; |
tail = (val>>16)&0x03f; |
rid = (val>>10)&0x03f; |
arvalid = (val>> 9)&1; |
arready = (val>> 8)&1; |
awvalid = (val>> 7)&1; |
awready = (val>> 6)&1; |
wvalid = (val>> 5)&1; |
wready = (val>> 4)&1; |
rvalid = (val>> 3)&1; |
bvalid = (val>> 2)&1; |
|
printf("%s %s %s %s ", (stb)?"STB":" ", (stall)?"STL":" ", |
(ack)?"ACK":" ", (err)?"ERR":" "); |
|
printf("%2x:%2x AR[%c%c] AW[%c%c] W[%c%c] ", head, tail, |
(arvalid)?'V':' ', (arready)?'R':' ', |
(awvalid)?'V':' ', (awready)?'R':' ', |
(wvalid)?'V':' ', (wready)?'R':' '); |
|
if (rvalid) |
printf("RV[%2x] %c", rid, bvalid?'B':' '); |
else if (bvalid) |
printf("BV[%2x]", rid); |
|
} |
}; |
|
int main(int argc, char **argv) { |
int skp=0, port = FPGAPORT; |
bool use_usb = false; |
|
skp=1; |
for(int argn=0; argn<argc-skp; argn++) { |
if (argv[argn+skp][0] == '-') { |
if (argv[argn+skp][1] == 'u') |
use_usb = true; |
else if (argv[argn+skp][1] == 'p') { |
use_usb = false; |
if (isdigit(argv[argn+skp][2])) |
port = atoi(&argv[argn+skp][2]); |
} |
skp++; argn--; |
} else |
argv[argn] = argv[argn+skp]; |
} argc -= skp; |
|
FPGAOPEN(m_fpga); |
|
signal(SIGSTOP, closeup); |
signal(SIGHUP, closeup); |
|
RAMSCOPE *scope = new RAMSCOPE(m_fpga, WBSCOPE, false); |
if (!scope->ready()) { |
printf("Scope is not yet ready:\n"); |
scope->decode_control(); |
} else |
scope->read(); |
delete m_fpga; |
} |
|
/trunk/sw/host/ttybus.cpp
52,6 → 52,8
#define DBGPRINTF filedump |
#ifndef DBGPRINTF |
#define DBGPRINTF null |
#else |
#warning "TTYBUS DEBUG IS TURNED ON" |
#endif |
|
void null(...) {} |
/trunk/sw/host/wbprogram.cpp
67,6 → 67,11
return r; |
} |
|
void usage(void) { |
printf("USAGE: wbprogram [@<Address>] file.bit\n"); |
printf("\tYou can also use a .bin file in place of the file.bit.\n"); |
} |
|
int main(int argc, char **argv) { |
FILE *fp; |
const int BUFLN = (1<<20); // 4MB Flash |
100,12 → 105,14
|
argn = 1; |
if (argc <= argn) { |
printf("BAD USAGE: program [@<Address>] file.bin\n"); |
usage(); |
exit(-1); |
} else if (argv[argn][0] == '@') { |
addr = strtoul(&argv[argn][1], NULL, 0); |
if ((addr < EQSPIFLASH)||(addr > EQSPIFLASH*2)) { |
printf("BAD ADDRESS: 0x%08x (from %s)\n", addr, argv[argn]); |
printf("The address you've selected, 0x%08x, is outside the range", addr); |
printf("from 0x%08x to 0x%08x\n", EQSPIFLASH, EQSPIFLASH*2); |
exit(-1); |
} argn++; |
} |
120,7 → 127,15
|
flash = new FLASHDRVR(m_fpga); |
|
if ((strcmp(&argv[argn][strlen(argv[argn])-4],".bit")!=0) |
&&(strcmp(&argv[argn][strlen(argv[argn])-4],".bin")!=0)) { |
printf("I'm expecting a '.bit' or \'.bin\' file extension\n"); |
exit(-1); |
} |
|
fp = fopen(argv[argn], "r"); |
if (strcmp(&argv[argn][strlen(argv[argn])-4],".bit")==0) |
fseek(fp, 0x5dl, SEEK_SET); |
sz = fread(buf, sizeof(buf[0]), BUFLN, fp); |
fclose(fp); |
|
143,8 → 158,7
exit(-1); |
} |
|
if (m_fpga->poll()) |
printf("FPGA was interrupted\n"); |
printf("ALL-DONE\n"); |
delete m_fpga; |
} |
|
/trunk/sw/startupex.sh
1,14 → 1,53
#!/bin/bash |
################################################################################ |
## |
## Filename: startupex.sh |
## |
## Project: OpenArty, an entirely open SoC based upon the Arty platform |
## |
## Purpose: A simple, but rather neat, demonstration proving that the wishbone |
## command capability works and that the FPGA is at least somewhat responsive. |
## |
## Creator: Dan Gisselquist, Ph.D. |
## Gisselquist Technology, LLC |
## |
################################################################################ |
## |
## Copyright (C) 2015-2016, Gisselquist Technology, LLC |
## |
## This program is free software (firmware): you can redistribute it and/or |
## modify it under the terms of the GNU General Public License as published |
## by the Free Software Foundation, either version 3 of the License, or (at |
## your option) any later version. |
## |
## This program is distributed in the hope that it will be useful, but WITHOUT |
## ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
## for more details. |
## |
## You should have received a copy of the GNU General Public License along |
## with this program. (It's in the $(ROOT)/doc directory, run make with no |
## target there if the PDF file isn't present.) If not, see |
## <http://www.gnu.org/licenses/> for a copy. |
## |
## License: GPL, v3, as defined and found on www.gnu.org, |
## http://www.gnu.org/licenses/gpl.html |
## |
## |
################################################################################ |
## |
## |
export PATH=$PATH:. |
export BINFILE=../../xilinx/openarty/openarty.runs/impl_1/fasttop.bin |
|
WBREGS=host/wbregs |
RED=0x00ff0000 |
GREEN=0x0000ff00 |
WHITE=0x000f0f0f |
WHITE=0x00070707 |
BLACK=0x00000000 |
DIMGREEN=0x00001f00 |
|
$WBREGS led 0x0f |
|
$WBREGS led 0x0ff |
$WBREGS clrled0 $RED |
$WBREGS clrled1 $RED |
$WBREGS clrled2 $RED |
16,19 → 55,23
|
sleep 1 |
$WBREGS clrled0 $GREEN |
$WBREGS led 0x10 |
sleep 1 |
$WBREGS clrled1 $GREEN |
$WBREGS clrled0 $DIMGREEN |
$WBREGS led 0x20 |
sleep 1 |
$WBREGS clrled2 $GREEN |
$WBREGS clrled1 $DIMGREEN |
$WBREGS led 0x40 |
sleep 1 |
$WBREGS clrled3 $GREEN |
$WBREGS clrled2 $DIMGREEN |
$WBREGS led 0x80 |
sleep 1 |
$WBREGS clrled0 $WHITE |
$WBREGS clrled1 $BLACK |
$WBREGS clrled2 $BLACK |
$WBREGS clrled1 $WHITE |
$WBREGS clrled2 $WHITE |
$WBREGS clrled3 $WHITE |
$WBREGS led 0x00 |
|