@@ -1832,6 +1832,122 @@ def fse_create_bandgap(dev, device):
1832
1832
dev .extra_func .setdefault ((10 , 18 ), {}).update (
1833
1833
{'bandgap' : {'wire' : 'C1' }})
1834
1834
1835
+ def fse_create_userflash (dev , device , dat ):
1836
+ # dat[‘UfbIns’] and dat[‘UfbOuts’].
1837
+ # The outputs are exactly 32 by the number of bits and they are always
1838
+ # present, their positions correspond to bit indices - checked by
1839
+ # selectively connecting the outputs to LEDs.
1840
+ # The inputs depend on the Flash type - different types have different
1841
+ # inputs, e.g. XY or RCP addressing is used etc. During experimental
1842
+ # generation of images with input to button connection some inputs
1843
+ # description could not be found in the table, such inputs will be
1844
+ # specified here rigidly.
1845
+ # Flash types (see UG295-1.4.3E_Gowin User Flash User Guide.pdf)
1846
+ _flash_type = {'GW1N-1' : 'FLASH96K' ,
1847
+ 'GW1NZ-1' : 'FLASH64KZ' ,
1848
+ 'GW1N-4' : 'FLASH256K' , 'GW1NS-4' : 'FLASH256K' ,
1849
+ 'GW1N-9' : 'FLASH608K' , 'GW1N-9C' : 'FLASH608K' }
1850
+ if device not in _flash_type :
1851
+ return
1852
+ flash_type = _flash_type [device ]
1853
+ ins_type = 'XY'
1854
+ if flash_type == 'FLASH96K' :
1855
+ ins_type = 'RC'
1856
+
1857
+ # userflash has neither its own cell type nor fuses, so it is logical to make it extra func.
1858
+ # use X0Y0 cell for convenience - a significant part of UserFlash pins are
1859
+ # located there, it saves from creating unnecessary nodes
1860
+ row , col = (0 , 0 )
1861
+ dev .extra_func .setdefault ((row , col ), {}).update (
1862
+ {'userflash' : {'type' : flash_type }})
1863
+ extra_func = dev .extra_func [(row , col )]['userflash' ]
1864
+
1865
+
1866
+ def make_port (r , c , wire , port , wire_type , pins ):
1867
+ if r == - 1 or c == - 1 :
1868
+ return
1869
+ bel = Bel ()
1870
+ wire = wirenames [wire ]
1871
+ bel .portmap [port ] = wire
1872
+ if r - 1 != row or c - 1 != col :
1873
+ create_port_wire (dev , row , col , r - row - 1 , c - col - 1 , bel , 'USERFLASH' , port , wire , wire_type )
1874
+ pins [port ] = bel .portmap [port ]
1875
+
1876
+ # outputs
1877
+ outs = extra_func .setdefault ('outs' , {})
1878
+ for i , desc in enumerate (dat .compat_dict ['UfbOuts' ]):
1879
+ port = f'DOUT{ i } '
1880
+ r , c , wire = desc
1881
+ make_port (r , c , wire , port , 'FLASH_OUT' , outs )
1882
+
1883
+ # inputs
1884
+ ins = extra_func .setdefault ('ins' , {})
1885
+ # DIN first - we know there they are
1886
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][58 :]):
1887
+ port = f'DIN{ i } '
1888
+ r , c , wire = desc
1889
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1890
+
1891
+ if ins_type == 'RC' :
1892
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][21 :27 ]):
1893
+ port = f'RA{ i } '
1894
+ r , c , wire = desc
1895
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1896
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][27 :33 ]):
1897
+ port = f'CA{ i } '
1898
+ r , c , wire = desc
1899
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1900
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][33 :39 ]):
1901
+ port = f'PA{ i } '
1902
+ r , c , wire = desc
1903
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1904
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][39 :43 ]):
1905
+ port = f'MODE{ i } '
1906
+ r , c , wire = desc
1907
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1908
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][43 :45 ]):
1909
+ port = f'SEQ{ i } '
1910
+ r , c , wire = desc
1911
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1912
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][45 :50 ]):
1913
+ port = ['ACLK' , 'PW' , 'RESET' , 'PE' , 'OE' ][i ]
1914
+ r , c , wire = desc
1915
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1916
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][50 :52 ]):
1917
+ port = f'RMODE{ i } '
1918
+ r , c , wire = desc
1919
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1920
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][52 :54 ]):
1921
+ port = f'WMODE{ i } '
1922
+ r , c , wire = desc
1923
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1924
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][54 :56 ]):
1925
+ port = f'RBYTESEL{ i } '
1926
+ r , c , wire = desc
1927
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1928
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][56 :58 ]):
1929
+ port = f'WBYTESEL{ i } '
1930
+ r , c , wire = desc
1931
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1932
+ else :
1933
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][:6 ]):
1934
+ port = ['XE' , 'YE' , 'SE' , 'PROG' , 'ERASE' , 'NVSTR' ][i ]
1935
+ r , c , wire = desc
1936
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1937
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][6 :15 ]):
1938
+ port = f'XADR{ i } '
1939
+ r , c , wire = desc
1940
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1941
+ for i , desc in enumerate (dat .compat_dict ['UfbIns' ][15 :21 ]):
1942
+ port = f'YADR{ i } '
1943
+ r , c , wire = desc
1944
+ make_port (r , c , wire , port , 'FLASH_IN' , ins )
1945
+
1946
+ # XXX INUSEN - is observed to be connected to the VSS when USERFLASH is used
1947
+ if flash_type != 'FLASH64KZ' :
1948
+ ins ['INUSEN' ] = 'C0'
1949
+
1950
+
1835
1951
def fse_bram (fse , aux = False ):
1836
1952
bels = {}
1837
1953
name = 'BSRAM'
@@ -1970,6 +2086,7 @@ def from_fse(device, fse, dat: Datfile):
1970
2086
fse_create_osc (dev , device , fse )
1971
2087
fse_create_gsr (dev , device )
1972
2088
fse_create_bandgap (dev , device )
2089
+ fse_create_userflash (dev , device , dat )
1973
2090
fse_create_logic2clk (dev , device , dat )
1974
2091
disable_plls (dev , device )
1975
2092
sync_extra_func (dev )
0 commit comments