1
0
mirror of synced 2026-03-05 10:24:10 +00:00
This commit is contained in:
Romain Dolbeau
2021-07-14 05:14:19 -04:00
parent 564c5276dc
commit b2ff488740
5 changed files with 937 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
#!/bin/bash
PFX=prom_migen
rm -f ${PFX}.fc
# (export BP=~/SPARC/SBusFPGA/sbus-to-ztex/openfirmware ; toke ${PFX}.forth )
( export BP=`pwd`/openfirmware ; openfirmware/cpu/x86/Linux/forth openfirmware/cpu/x86/build/builder.dic prom_migen.bth ) 2>&1 | tee forth.log
rm -f /tmp/${PFX}.hexa
od --endian=big -w4 -x ${PFX}.fc | awk '{ print $2,$3"," }' >| /tmp/${PFX}.hexa
rm -f /tmp/${PFX}.txt_hexa
cat /tmp/${PFX}.hexa | sed -e 's/^\([a-f0-9][a-f0-9][a-f0-9][a-f0-9]\) \([a-f0-9][a-f0-9][a-f0-9][a-f0-9]\),/0x\1\2,/g' -e 's/^\([a-f0-9][a-f0-9]*\) ,/0x\10000,/' -e 's/^ ,/0x00000000,/' -e 's/\(0x[0-9a-fA-F]*\),/if (idx == 0):\n\treturn \1;/' > /tmp/${PFX}.txt_hexa
#echo "rom = ["
#cat /tmp/${PFX}.txt_hexa
#echo "]"

View File

@@ -0,0 +1,31 @@
purpose: Load file for SBusFPGA
command: &builder &this
\ in: ${BP}/dev/usb2/device/hub/build/hub.fc
\ in: ${BP}/dev/usb2/device/generic/build/generic.fc
\ in: ${BP}/dev/usb2/device/net/build/usbnet.fc
\ in: ${BP}/dev/usb2/device/serial/build/usbserial.fc
\ in: ${BP}/dev/usb2/device/storage/build/usbstorage.fc
\ in: ${BP}/dev/usb2/device/keyboard/build/usbkbd.fc
\ in: ${BP}/dev/usb2/device/mouse/build/usbmouse.fc
build-now
\ silent on
begin-tokenizing prom_migen.fc
fload prom_migen.fth
end-tokenizing
\ h# 8000 to reserved-start
\ h# f000 to reserved-end
\ " ${BP}/dev/usb2/device/hub/build/hub.fc" " usb,class9" $add-dropin
\ " ${BP}/dev/usb2/device/generic/build/generic.fc" " usbdevice" $add-deflated-dropin
\ " ${BP}/dev/usb2/device/net/build/usbnet.fc" " usbnet" $add-deflated-dropin
\ " ${BP}/dev/usb2/device/keyboard/build/usbkbd.fc" " usb,class3,1,1" $add-deflated-dropin
\ " ${BP}/dev/usb2/device/mouse/build/usbmouse.fc" " usb,class3,1,2" $add-deflated-dropin
\ " ${BP}/dev/usb2/device/serial/build/usbserial.fc" " usbserial" $add-deflated-dropin
\ " ${BP}/dev/usb2/device/storage/build/usbstorage.fc" " usbstorage" $add-deflated-dropin

View File

@@ -0,0 +1,124 @@
fcode-version2
\ loads constants
fload prom_csr.fth
\ fload v2compat.fth
\ Absolute minimal stuff; name & registers def.
" RDOL,led" device-name
my-address sbusfpga_csraddr_leds + my-space h# 4 reg
\ we don't support ET or HWORD
h# 7d xdrint " slave-burst-sizes" attribute
h# 7d xdrint " burst-sizes" attribute
headers
-1 instance value led-virt
my-address constant my-sbus-address
my-space constant my-sbus-space
: map-in ( adr space size -- virt ) " map-in" $call-parent ;
: map-out ( virt size -- ) " map-out" $call-parent ;
: map-in-led ( -- ) my-sbus-address sbusfpga_csraddr_leds + my-sbus-space h# 4 map-in is led-virt ;
: map-out-led ( -- ) led-virt h# 4 map-out ;
\ external
: setled! ( pattern -- )
map-in-led
led-virt l! ( pattern virt -- )
map-out-led
;
\ h# a5 setled!
\ OpenBIOS tokenizer won't accept finish-device without new-device
\ Cheat by using the tokenizer so we can do OpenBoot 2.x siblings
\ tokenizer[ 01 emit-byte h# 27 emit-byte h# 01 emit-byte h# 1f emit-byte ]tokenizer
\ The OpenFirmware tokenizer does accept the 'clean' syntax
finish-device
new-device
\ Absolute minimal stuff; name & registers def.
" generic-ohci" device-name
my-address h# 80000 + my-space h# 1000 reg
\ we don't support ET or anything non-32bits
h# 7c xdrint " slave-burst-sizes" attribute
h# 7c xdrint " burst-sizes" attribute
1 xdrint " interrupts" attribute
headers
-1 instance value regs-virt
my-address constant my-sbus-address
my-space constant my-sbus-space
: map-in ( adr space size -- virt ) " map-in" $call-parent ;
: map-out ( virt size -- ) " map-out" $call-parent ;
: map-in-regs ( -- ) my-sbus-address h# 80000 + my-sbus-space h# 1000 map-in is regs-virt ;
: map-out-regs ( -- ) regs-virt h# 1000 map-out ;
: my-reset! ( -- )
map-in-regs
00000001 regs-virt h# 4 + l! ( -- ) ( reset the HC )
00000000 regs-virt h# 18 + l! ( -- ) ( reset HCCA & friends )
00000000 regs-virt h# 1c + l! ( -- )
00000000 regs-virt h# 20 + l! ( -- )
00000000 regs-virt h# 24 + l! ( -- )
00000000 regs-virt h# 28 + l! ( -- )
00000000 regs-virt h# 2c + l! ( -- )
00000000 regs-virt h# 30 + l! ( -- )
map-out-regs
;
my-reset!
\ " ohci" encode-string " device_type" property
\ fload openfirmware/dev/usb2/hcd/ohci/loadpkg-sbus.fth
\ open
\ OpenBIOS tokenizer won't accept finish-device without new-device
\ Cheat by using the tokenizer so we can do OpenBoot 2.x siblings
\ tokenizer[ 01 emit-byte h# 27 emit-byte h# 01 emit-byte h# 1f emit-byte ]tokenizer
\ The OpenFirmware tokenizer does accept the 'clean' syntax
finish-device
new-device
\ Absolute minimal stuff; name & registers def.
" RDOL,sdram" device-name
\ two pages of registers:
my-address sbusfpga_csraddr_ddrphy + my-space xdrphys \ Offset#1
h# 1000 xdrint xdr+ \ Merge size#1
my-address sbusfpga_csraddr_sdram + my-space xdrphys xdr+ \ Merge offset#2
h# 1000 xdrint xdr+ \ Merge size#2
" reg" attribute
\ we don't support ET or anything non-32bits
h# 7c xdrint " slave-burst-sizes" attribute
h# 7c xdrint " burst-sizes" attribute
headers
-1 instance value mregs-ddrphy-virt
-1 instance value mregs-sdramdfii-virt
my-address constant my-sbus-address
my-space constant my-sbus-space
: map-in ( adr space size -- virt ) " map-in" $call-parent ;
: map-out ( virt size -- ) " map-out" $call-parent ;
: map-in-mregs ( -- )
my-sbus-address sbusfpga_csraddr_ddrphy + my-sbus-space h# 1000 map-in is mregs-ddrphy-virt
my-sbus-address sbusfpga_csraddr_sdram + my-sbus-space h# 1000 map-in is mregs-sdramdfii-virt
;
: map-out-mregs ( -- )
mregs-ddrphy-virt h# 1000 map-out
mregs-sdramdfii-virt h# 1000 map-out
;
\ fload sdram_init.fth
\ init!
end0

View File

@@ -0,0 +1,228 @@
: dphy_rst_rd ( -- csr_value )
mregs-virt h# 1000 + l@
;
: dphy_half_sys8x_taps_rd ( -- csr_value )
mregs-virt h# 1004 + l@
;
: dphy_wlevel_en_rd ( -- csr_value )
mregs-virt h# 1008 + l@
;
: dphy_wlevel_strobe_rd ( -- csr_value )
mregs-virt h# 100c + l@
;
: dphy_dly_sel_rd ( -- csr_value )
mregs-virt h# 1010 + l@
;
: dphy_rdly_dq_rst_rd ( -- csr_value )
mregs-virt h# 1014 + l@
;
: dphy_rdly_dq_inc_rd ( -- csr_value )
mregs-virt h# 1018 + l@
;
: dphy_rdly_dq_bitslip_rst_rd ( -- csr_value )
mregs-virt h# 101c + l@
;
: dphy_rdly_dq_bitslip_rd ( -- csr_value )
mregs-virt h# 1020 + l@
;
: dphy_wdly_dq_bitslip_rst_rd ( -- csr_value )
mregs-virt h# 1024 + l@
;
: dphy_wdly_dq_bitslip_rd ( -- csr_value )
mregs-virt h# 1028 + l@
;
: dphy_rdphase_rd ( -- csr_value )
mregs-virt h# 102c + l@
;
: dphy_wrphase_rd ( -- csr_value )
mregs-virt h# 1030 + l@
;
: sdr_dfii_control_rd ( -- csr_value )
mregs-virt h# 2000 + l@
;
: sdr_dfii_pi0_command_rd ( -- csr_value )
mregs-virt h# 2004 + l@
;
: sdr_dfii_pi0_command_issue_rd ( -- csr_value )
mregs-virt h# 2008 + l@
;
: sdr_dfii_pi0_address_rd ( -- csr_value )
mregs-virt h# 200c + l@
;
: sdr_dfii_pi0_baddress_rd ( -- csr_value )
mregs-virt h# 2010 + l@
;
: sdr_dfii_pi0_wrdata_rd ( -- csr_value )
mregs-virt h# 2014 + l@
;
: sdr_dfii_pi0_rddata_rd ( -- csr_value )
mregs-virt h# 2018 + l@
;
: sdr_dfii_pi1_command_rd ( -- csr_value )
mregs-virt h# 201c + l@
;
: sdr_dfii_pi1_command_issue_rd ( -- csr_value )
mregs-virt h# 2020 + l@
;
: sdr_dfii_pi1_address_rd ( -- csr_value )
mregs-virt h# 2024 + l@
;
: sdr_dfii_pi1_baddress_rd ( -- csr_value )
mregs-virt h# 2028 + l@
;
: sdr_dfii_pi1_wrdata_rd ( -- csr_value )
mregs-virt h# 202c + l@
;
: sdr_dfii_pi1_rddata_rd ( -- csr_value )
mregs-virt h# 2030 + l@
;
: sdr_dfii_pi2_command_rd ( -- csr_value )
mregs-virt h# 2034 + l@
;
: sdr_dfii_pi2_command_issue_rd ( -- csr_value )
mregs-virt h# 2038 + l@
;
: sdr_dfii_pi2_address_rd ( -- csr_value )
mregs-virt h# 203c + l@
;
: sdr_dfii_pi2_baddress_rd ( -- csr_value )
mregs-virt h# 2040 + l@
;
: sdr_dfii_pi2_wrdata_rd ( -- csr_value )
mregs-virt h# 2044 + l@
;
: sdr_dfii_pi2_rddata_rd ( -- csr_value )
mregs-virt h# 2048 + l@
;
: sdr_dfii_pi3_command_rd ( -- csr_value )
mregs-virt h# 204c + l@
;
: sdr_dfii_pi3_command_issue_rd ( -- csr_value )
mregs-virt h# 2050 + l@
;
: sdr_dfii_pi3_address_rd ( -- csr_value )
mregs-virt h# 2054 + l@
;
: sdr_dfii_pi3_baddress_rd ( -- csr_value )
mregs-virt h# 2058 + l@
;
: sdr_dfii_pi3_wrdata_rd ( -- csr_value )
mregs-virt h# 205c + l@
;
: sdr_dfii_pi3_rddata_rd ( -- csr_value )
mregs-virt h# 2060 + l@
;
: dphy_rst_wr ( value -- )
mregs-virt h# 1000 + l!
;
: dphy_half_sys8x_taps_wr ( value -- )
mregs-virt h# 1004 + l!
;
: dphy_wlevel_en_wr ( value -- )
mregs-virt h# 1008 + l!
;
: dphy_wlevel_strobe_wr ( value -- )
mregs-virt h# 100c + l!
;
: dphy_dly_sel_wr ( value -- )
mregs-virt h# 1010 + l!
;
: dphy_rdly_dq_rst_wr ( value -- )
mregs-virt h# 1014 + l!
;
: dphy_rdly_dq_inc_wr ( value -- )
mregs-virt h# 1018 + l!
;
: dphy_rdly_dq_bitslip_rst_wr ( value -- )
mregs-virt h# 101c + l!
;
: dphy_rdly_dq_bitslip_wr ( value -- )
mregs-virt h# 1020 + l!
;
: dphy_wdly_dq_bitslip_rst_wr ( value -- )
mregs-virt h# 1024 + l!
;
: dphy_wdly_dq_bitslip_wr ( value -- )
mregs-virt h# 1028 + l!
;
: dphy_rdphase_wr ( value -- )
mregs-virt h# 102c + l!
;
: dphy_wrphase_wr ( value -- )
mregs-virt h# 1030 + l!
;
: sdr_dfii_control_wr ( value -- )
mregs-virt h# 2000 + l!
;
: sdr_dfii_pi0_command_wr ( value -- )
mregs-virt h# 2004 + l!
;
: sdr_dfii_pi0_command_issue_wr ( value -- )
mregs-virt h# 2008 + l!
;
: sdr_dfii_pi0_address_wr ( value -- )
mregs-virt h# 200c + l!
;
: sdr_dfii_pi0_baddress_wr ( value -- )
mregs-virt h# 2010 + l!
;
: sdr_dfii_pi0_wrdata_wr ( value -- )
mregs-virt h# 2014 + l!
;
: sdr_dfii_pi0_rddata_wr ( value -- )
mregs-virt h# 2018 + l!
;
: sdr_dfii_pi1_command_wr ( value -- )
mregs-virt h# 201c + l!
;
: sdr_dfii_pi1_command_issue_wr ( value -- )
mregs-virt h# 2020 + l!
;
: sdr_dfii_pi1_address_wr ( value -- )
mregs-virt h# 2024 + l!
;
: sdr_dfii_pi1_baddress_wr ( value -- )
mregs-virt h# 2028 + l!
;
: sdr_dfii_pi1_wrdata_wr ( value -- )
mregs-virt h# 202c + l!
;
: sdr_dfii_pi1_rddata_wr ( value -- )
mregs-virt h# 2030 + l!
;
: sdr_dfii_pi2_command_wr ( value -- )
mregs-virt h# 2034 + l!
;
: sdr_dfii_pi2_command_issue_wr ( value -- )
mregs-virt h# 2038 + l!
;
: sdr_dfii_pi2_address_wr ( value -- )
mregs-virt h# 203c + l!
;
: sdr_dfii_pi2_baddress_wr ( value -- )
mregs-virt h# 2040 + l!
;
: sdr_dfii_pi2_wrdata_wr ( value -- )
mregs-virt h# 2044 + l!
;
: sdr_dfii_pi2_rddata_wr ( value -- )
mregs-virt h# 2048 + l!
;
: sdr_dfii_pi3_command_wr ( value -- )
mregs-virt h# 204c + l!
;
: sdr_dfii_pi3_command_issue_wr ( value -- )
mregs-virt h# 2050 + l!
;
: sdr_dfii_pi3_address_wr ( value -- )
mregs-virt h# 2054 + l!
;
: sdr_dfii_pi3_baddress_wr ( value -- )
mregs-virt h# 2058 + l!
;
: sdr_dfii_pi3_wrdata_wr ( value -- )
mregs-virt h# 205c + l!
;
: sdr_dfii_pi3_rddata_wr ( value -- )
mregs-virt h# 2060 + l!
;

View File

@@ -0,0 +1,533 @@
headers
fload sdram_csr.fth
external
: popcnt ( n -- u)
0 swap
BEGIN dup WHILE tuck 1 AND + swap 1 rshift REPEAT
DROP
;
: cdelay ( count -- )
\ Forth loop always have a least one iteration
dup 0<> if
0 do noop loop
else drop then
;
headers
: sdram_software_control_on ( -- )
sdr_dfii_control_rd
h# e <> if h# e sdr_dfii_control_wr then
;
: sdram_software_control_off ( -- )
sdr_dfii_control_rd
h# 1 <> if h# 1 sdr_dfii_control_wr then
;
: command_p0 ( cmd -- )
sdr_dfii_pi0_command_wr
1 sdr_dfii_pi0_command_issue_wr
;
: command_p1 ( cmd -- )
sdr_dfii_pi1_command_wr
1 sdr_dfii_pi1_command_issue_wr
;
: command_p2 ( cmd -- )
sdr_dfii_pi2_command_wr
1 sdr_dfii_pi2_command_issue_wr
;
: command_p3 ( cmd -- )
sdr_dfii_pi3_command_wr
1 sdr_dfii_pi3_command_issue_wr
;
: init_sequence ( -- )
.( init_sequence ) cr
h# 0 sdr_dfii_pi0_address_wr
h# 0 sdr_dfii_pi0_baddress_wr
h# c sdr_dfii_control_wr
50 ms
h# 0 sdr_dfii_pi0_address_wr
h# 0 sdr_dfii_pi0_baddress_wr
h# e sdr_dfii_control_wr
10 ms
h# 200 sdr_dfii_pi0_address_wr
h# 2 sdr_dfii_pi0_baddress_wr
h# f command_p0
h# 0 sdr_dfii_pi0_address_wr
h# 3 sdr_dfii_pi0_baddress_wr
h# f command_p0
h# 6 sdr_dfii_pi0_address_wr
h# 1 sdr_dfii_pi0_baddress_wr
h# f command_p0
h# 920 sdr_dfii_pi0_address_wr
h# 0 sdr_dfii_pi0_baddress_wr
h# f command_p0
200 cdelay
h# 400 sdr_dfii_pi0_address_wr
0 sdr_dfii_pi0_baddress_wr
h# 3 command_p0
200 cdelay
;
: sdram_read_leveling_rst_delay ( modulenum -- )
h# 1 swap << dphy_dly_sel_wr
h# 1 dphy_rdly_dq_rst_wr
h# 0 dphy_dly_sel_wr
;
: sdram_read_leveling_inc_delay ( modulenum -- )
h# 1 swap << dphy_dly_sel_wr
h# 1 dphy_rdly_dq_inc_wr
h# 0 dphy_dly_sel_wr
;
: sdram_read_leveling_rst_bitslip ( modulenum -- )
h# 1 swap << dphy_dly_sel_wr
h# 1 dphy_rdly_dq_bitslip_rst_wr
h# 0 dphy_dly_sel_wr
;
: sdram_read_leveling_inc_bitslip ( modulenum -- )
h# 1 swap << dphy_dly_sel_wr
h# 1 dphy_rdly_dq_bitslip_wr
h# 0 dphy_dly_sel_wr
;
: lfsr ( bits prev -- res )
dup 1 and not ( bits prev -- bits prev ~{prev&1} )
swap 1 >> ( bits prev ~{prev&1} -- bits ~{prev&1} {prev>>1} )
swap ( bits prev ~{prev&1} -- bits {prev>>1} ~{prev&1} )
rot ( bits {prev>>1} ~{prev&1} -- {prev>>1} ~{prev&1} bits )
\ assume bits is 32, 'cause it is
drop h# 80200003 ( {prev>>1} ~{prev&1} bits -- {prev>>1} ~{prev&1} lfsr_taps[bits] )
and
xor
;
: sdram_activate_test_row ( -- )
h# 0 sdr_dfii_pi0_address_wr
h# 0 sdr_dfii_pi0_baddress_wr
h# 9 command_p0
15 cdelay
;
: sdram_precharge_test_row ( -- )
h# 0 sdr_dfii_pi0_address_wr
h# 0 sdr_dfii_pi0_baddress_wr
h# b command_p0
15 cdelay
;
: command_px ( phase value -- )
over 3 = if dup command_p3 then
over 2 = if dup command_p2 then
over 1 = if dup command_p1 then
over 0 = if dup command_p0 then
2drop
;
: command_prd ( value -- )
dphy_rdphase_rd
swap command_px
;
: command_pwr ( value -- )
dphy_wrphase_rd
swap command_px
;
: sdr_dfii_pix_address_wr ( phase value -- )
over 3 = if dup sdr_dfii_pi3_address_wr then
over 2 = if dup sdr_dfii_pi2_address_wr then
over 1 = if dup sdr_dfii_pi1_address_wr then
over 0 = if dup sdr_dfii_pi0_address_wr then
2drop
;
: sdr_dfii_pird_address_wr ( value -- )
dphy_rdphase_rd
swap sdr_dfii_pix_address_wr
;
: sdr_dfii_piwr_address_wr ( value -- )
dphy_wrphase_rd
swap sdr_dfii_pix_address_wr
;
: sdr_dfii_pix_baddress_wr ( phase value -- )
over 3 = if dup sdr_dfii_pi3_baddress_wr then
over 2 = if dup sdr_dfii_pi2_baddress_wr then
over 1 = if dup sdr_dfii_pi1_baddress_wr then
over 0 = if dup sdr_dfii_pi0_baddress_wr then
2drop
;
: sdr_dfii_pird_baddress_wr ( value -- )
dphy_rdphase_rd
swap sdr_dfii_pix_baddress_wr
;
: sdr_dfii_piwr_baddress_wr ( value -- )
dphy_wrphase_rd
swap sdr_dfii_pix_baddress_wr
;
: sdr_wr_rd_chk_tst_pat_get ( seed -- A B C D )
\ .( sdr_wr_rd_chk_tst_pat_get ) cr
dup 42 = if h# 00000080 swap then
dup 42 = if h# 00000000 swap then
dup 42 = if h# 00000000 swap then
dup 42 = if h# 15090700 swap then
dup 84 = if h# 00000000 swap then
dup 84 = if h# 00000000 swap then
dup 84 = if h# 00000000 swap then
dup 84 = if h# 2a150907 swap then
drop
;
: sdr_wr_rd_check_test_pattern ( modulenum seed -- errors )
\ .( sdr_wr_rd_check_test_pattern ) cr
sdram_activate_test_row
dup sdr_wr_rd_chk_tst_pat_get
\ should have the 4 patterns on top of the stack: modulenum seed p0 p1 p2 p3
sdr_dfii_pi0_wrdata_wr
sdr_dfii_pi1_wrdata_wr
sdr_dfii_pi2_wrdata_wr
sdr_dfii_pi3_wrdata_wr
\ should be back at modulenum seed
h# 0 sdr_dfii_piwr_address_wr
h# 0 sdr_dfii_piwr_baddress_wr
h# 17 command_pwr
15 cdelay
h# 0 sdr_dfii_pird_address_wr
h# 0 sdr_dfii_pird_baddress_wr
h# 25 command_prd
15 cdelay
sdram_precharge_test_row
sdr_wr_rd_chk_tst_pat_get
\ should have the 4 patterns on top of the stack: modulenum p0 p1 p2 p3
sdr_dfii_pi0_rddata_rd xor popcnt
\ should be at modulenum p0 p1 p2 errors
swap sdr_dfii_pi0_rddata_rd xor popcnt +
\ should be at modulenum p0 p1 errors
swap sdr_dfii_pi0_rddata_rd xor popcnt +
\ should be at modulenum p0 errors
swap sdr_dfii_pi0_rddata_rd xor popcnt +
\ should be at modulenum errors
\ drop modulenum
nip
;
: sdram_read_leveling_scan_module ( modulenum bitslip -- score )
\ .( sdram_read_leveling_scan_module ) cr
over sdram_read_leveling_rst_delay
\ push score
0
\ we should be at 'modulenum bitslip score'
32 0 do
\ .( starting rd_lvl_scan loop with stack: ) .s cr
2 pick 42 sdr_wr_rd_check_test_pattern
\ now we have an error count at the top
3 pick 84 sdr_wr_rd_check_test_pattern
\ merge both error count
+
\ we should be at 'modulenum bitslip score errorcount'
dup 0=
\ we should be at 'modulenum bitslip score errorcount working?'
if 16384 else 0 then
\ we should be at 'modulenum bitslip score errorcount (0|16384)'
swap 512 swap -
\ we should be at 'modulenum bitslip score (0|16384) (512-errorcount)'
+
+
\ we should be at 'modulenum bitslip score'
2 pick sdram_read_leveling_inc_delay
loop
nip
nip
;
: sdr_wr_lat_cal_bitslip_loop ( modulenum bestbitslip bestscore bitslip -- modulenum bestbitslip bestscore )
\ .( sdr_wr_lat_cal_bitslip_loop for module: ) 3 pick . .( bitslip: ) dup . cr
\ .( sdr_wr_lat_cal_bitslip_loop, stack: ) .s cr
1 4 pick << dphy_dly_sel_wr ( '4 pick' will extract modulenum, needed as we're stacking the '1' )
1 dphy_wdly_dq_bitslip_rst_wr
\ Forth loop always have a least one iteration
dup 0<> if
dup 0 do
1 dphy_wdly_dq_bitslip_wr
loop
then
0 dphy_dly_sel_wr
\ .( sdr_wr_lat_cal_bitslip_loop after bitslip init loop, stack: ) .s cr
\ push current score
0 ( we should be at 'modulenum bestbitslip bestscore bitslip score' )
4 pick sdram_read_leveling_rst_bitslip
8 0 do
4 pick over sdram_read_leveling_scan_module
\ we should be at 'modulenum bestbitslip bestscore bitslip score score', max will merge scores
max
\ we should be at 'modulenum bestbitslip bestscore bitslip score' again
4 pick sdram_read_leveling_inc_bitslip
loop
.( sdr_wr_lat_cal_bitslip_loop after bitslip check loop, stack: ) .s cr
dup 3 pick >
if
\ .( lat_cal best bitslip was: ) 3 pick . .( with score: ) 2 pick . cr
2swap
.( lat_cal best bitslip now: ) 3 pick . .( with score: ) 2 pick . cr
then
2drop
\ .( sdr_wr_lat_cal_bitslip_loop end, stack: ) .s cr
;
: sdr_wr_lat_cal_module_loop ( modulenum -- )
.( sdr_wr_lat_cal_module_loop for module: ) dup . cr
\ push best_bitslip
-1
\ push best_score
0
\ we should have 'modulenum 1 0'
8 0 do
i sdr_wr_lat_cal_bitslip_loop
2 +loop
\ we should be at 'modulenum bestbitslip bestscore'
\ we don't need score anymore
drop
\ we should be at 'modulenum bestbitslip'
1 2 pick << dphy_dly_sel_wr
1 dphy_wdly_dq_bitslip_rst_wr
.( sdr_wr_lat_cal_module_loop: best bitslip: ) dup . cr
\ loop that consumes bestbitslip as the upper bound
\ Forth loop always have a least one iteration
dup 0<> if
0 do
1 dphy_wdly_dq_bitslip_wr
loop
else drop then
0 dphy_dly_sel_wr
\ drop the modulenum
drop
;
: sdram_write_latency_calibration ( -- )
.( sdram_write_latency_calibration ) cr
2 0 do
i sdr_wr_lat_cal_module_loop
loop
;
: sdram_leveling_center_module ( modulenum -- )
.( sdram_leveling_center_module ) cr
dup sdram_read_leveling_rst_delay
\ push delay_min
-1
\ push delay
0
\ we should be at 'modulenum delay_min delay'
begin
\ .( starting lvl_center loop with stack: ) .s cr
2 pick 42 sdr_wr_rd_check_test_pattern
.( we should be at 'modulenum delay_min delay error' stack: ) .s cr
3 pick 84 sdr_wr_rd_check_test_pattern
.( we should be at 'modulenum delay_min delay error error' stack: ) .s cr
+
\ we should be at 'modulenum delay_min delay error'
\ .( we should be at 'modulenum delay_min delay error' stack: ) .s cr
0=
\ we should be at 'modulenum delay_min delay working'
\ .( we should be at 'modulenum delay_min delay working' stack: ) .s cr
2 pick 0< and
\ we should be at 'modulenum delay_min delay {working&delay_min<0}'
\ .( we should be at 'modulenum delay_min delay {working&delay_min<0}' stack: ) .s cr
dup if rot drop 2dup rot drop then
not
\ we should be at 'modulenum new_delay_min delay !{working&delay_min<0}'
\ .( we should be at 'modulenum new_delay_min delay !{working&delay_min<0}' stack: ) .s cr
\ test delay before incrementing, if already 31 no point in continuing/incrementing
over 31 <
\ .( we should be at 'modulenum new_delay_min delay !{working&delay_min<0} <31' stack: ) .s cr
dup if rot 1+ -rot then
dup if 4 pick sdram_read_leveling_inc_delay then
\ and the conditions to signal end-of-loop
and
\ .( we should be at 'modulenum new_delay_min delay !{working&delay_min<0}&<31' stack: ) .s cr
\ .( finishing lvl_center loop with stack: ) .s cr
not until
\ we should be at 'modulenum new_delay_min delay', the while has consumed the condition
.( we should be at 'modulenum new_delay_min delay' stack: ) .s cr
1+
2 pick sdram_read_leveling_inc_delay
\ build a clean stack, startin with a copy of modulenum
2 pick
\ push delay_max
-1
\ we're at 'modulenum new_delay_min delay modulenum delay_max'
\ push delay
2 pick
\ we're at 'modulenum new_delay_min delay modulenum delay_max delay'
.( we should be at 'modulenum new_delay_min delay modulenum delay_max delay ' stack: ) .s cr
\ this is almost the same loop, except with !working instead of working and delay_max instead of delay_min
begin
2 pick 42 sdr_wr_rd_check_test_pattern
3 pick 84 sdr_wr_rd_check_test_pattern
+
\ we should be at 'modulenum delay_max delay error'
0<>
\ we should be at 'modulenum delay_max delay !working'
2 pick 0< and
\ we should be at 'modulenum delay_max delay {!working&delay_max<0}'
dup if rot drop 2dup rot drop then
not
\ we should be at 'modulenum new_delay_max delay !{!working&delay_max<0}'
\ test delay before incrementing, if already 31 no point in continuing/incrementing
over 31 <
dup not if rot 1+ -rot then
dup not if 4 pick sdram_read_leveling_inc_delay then
\ and the conditions to signal end-of-loop
and
not until
\ we should be at 'modulenum new_delay_min delay modulenum new_delay_max delay', the while has consumed the condition
.( we should be at 'modulenum new_delay_min delay modulenum new_delay_max delay ' stack: ) .s cr
\ keep delay if new_delay_max<0, new_delay_max otherwise
over 0< if nip else drop then
\ we should be at 'modulenum new_delay_min delay modulenum new_delay_max'
nip
nip
\ we should be at 'modulenum new_delay_min new_delay_max'
.( we should be at 'modulenum new_delay_min new_delay_max' stack: ) .s cr
\ compute delay_mid
2dup + 2/ 32 mod
\ we should be at 'modulenum new_delay_min new_delay_max {{new_delay_min+new_delay_max}/2%32}'
\ compute delay_range
3dup drop swap - 2/
\ we should be at 'modulenum new_delay_min new_delay_max {{new_delay_min+new_delay_max}/2%32} {{new_delay_max-new_delay_min}/2}'
.( we should be at 'modulenum new_delay_min new_delay_max delay_mid delay_range ' stack: ) .s cr
4 pick sdram_read_leveling_rst_delay
100 cdelay
\ Forth loop always have a least one iteration
over 0<> if
over 0 do
4 pick sdram_read_leveling_inc_delay
100 cdelay
loop
then
drop
drop
drop
drop
drop
;
: sdr_rd_lvl_bitslip_loop ( modulenum bestbitslip bestscore bitslip -- modulenum bestbitslip bestscore )
\ .( sdr_rd_lvl_bitslip_loop, stack: ) .s cr
3 pick over sdram_read_leveling_scan_module
\ we should be at 'modulenum bestbitslip bestscore bitslip score'
4 pick sdram_leveling_center_module
\ preserve a bitslip for the later test
over
\ (we should be at 'modulenum bestbitslip bestscore bitslip score bitslip') move it out of the way
.( we should be at 'modulenum bestbitslip bestscore bitslip score bitslip' stack: ) .s cr
5 roll ( 'modulenum bestscore bitslip score bitslip bestbitslip' )
5 roll ( 'modulenum bitslip score bitslip bestbitslip bestscore' )
5 roll ( 'modulenum score bitslip bestbitslip bestscore bitslip' )
5 roll ( 'modulenum bitslip bestbitslip bestscore bitslip score' )
.( we should be at 'modulenum bitslip bestbitslip bestscore bitslip score' stack: ) .s cr
\ compare the score and bestcore
dup 3 pick >
if
2swap
.( rd_lvl best bitslip now: ) 3 pick . .( with score: ) 2 pick . cr
then
2drop
\ we should be at 'modulenum bitslip bestbitslip bestscore'
rot
\ we should be at 'modulenum bestbitslip bestscore bitslip'
.( we should be at 'modulenum bestbitslip bestscore bitslip' stack: ) .s cr
7 <> if 2 pick sdram_read_leveling_inc_bitslip then
;
: sdr_rd_lvl_module_loop ( modulenum -- )
.( sdr_rd_lvl_module_loop ) cr
1 over << sdram_read_leveling_rst_bitslip
\ push best_bitslip
0
\ push best_score
0
\ we should have 'modulenum 0 0'
8 0 do
i sdr_rd_lvl_bitslip_loop
loop
\ don't need the score anymore
drop
2 pick sdram_read_leveling_rst_bitslip
.( sdr_rd_lvl_module_loop, best bitslip: ) dup . cr
\ Forth loop always have a least one iteration
dup 0<> if
\ consume best_bitslip as loop upper bound
0 do
dup sdram_leveling_center_module
loop
else drop then
drop
;
: sdram_read_leveling ( -- )
.( sdram_read_leveling ) cr
2 0 do
i sdr_rd_lvl_module_loop
loop
;
: sdram_leveling ( -- )
.( sdram_leveling ) cr
sdram_software_control_on
2 0 do
i sdram_read_leveling_rst_delay
i sdram_read_leveling_rst_bitslip
loop
sdram_write_latency_calibration
sdram_read_leveling
sdram_software_control_off
;
external
: init_sdram ( -- )
.( init_sdram ) cr
2 dphy_rdphase_wr
3 dphy_wrphase_wr
sdram_software_control_on
1 dphy_rst_wr
1 ms
0 dphy_rst_wr
1 ms
.( going to init_sequence ) cr
init_sequence
.( going to sdram_leveling ) cr
sdram_leveling
\ redundant
sdram_software_control_off
;
: init! ( -- )
.( init ) cr
map-in-mregs
init_sdram
map-out-mregs
;