1library ieee; 2use ieee.std_logic_1164.all; 3use ieee.numeric_std.all; 4 5-- sewuence generator 6-- note: cos,sin output on negative edge before pha, sync. 7-- pha on positive edge, sync on positive edge 8entity ram_lut is 9port( nreset,clk,wstb,rstb: in std_logic; 10cmd: in std_logic_vector(2 downto 0); -- control 11din: in std_logic_vector(7 downto 0); 12dout: out std_logic_vector(7 downto 0); 13pos_ctr: out std_logic_vector(9 downto 0); 14sin,cos,indo,pha,sync:out std_logic); 15end ram_lut; 16 17architecture rtl of ram_lut is 18 19component ram2k8 is 20port( clk,WEn,CSn: in std_logic; -- clk rising edge, WEn & CSn are active low 21ADDR: in std_logic_vector(10 downto 0); 22dw: in std_logic_vector(7 downto 0); -- write data 23dr: out std_logic_vector(7 downto 0) -- read data 24); 25end component; 26 27-- signals for memory 28signal mCLK,mWEn,mCEn: std_logic; 29signal mA11: std_logic_vector(10 downto 0); -- address for the 2k mem 30signal mA: std_logic_vector(8 downto 0); -- normal address 31signal mD: std_logic_vector(7 downto 0); 32signal mQ: std_logic_vector(7 downto 0); 33signal mQr: std_logic_vector(7 downto 0); -- register to hold data 34 35-- signals for sequence generator 36signal ctr_lim: unsigned(8 downto 0); -- final byte address 37signal dib_ctr: unsigned(1 downto 0); 38signal sini,cosi,indoi,phai,synci: std_logic; 39signal pos_ctri:unsigned(9 downto 0); 40signal lut_ctl: std_logic_vector(7 downto 0); -- see below: 41 42alias lut_run: std_logic is lut_ctl(7); 43alias lut_3ph: std_logic is lut_ctl(5); 44alias indo_def: std_logic is lut_ctl(4); 45alias dib_lim: std_logic_vector(1 downto 0) is lut_ctl(2 downto 1); 46 47signal rd,csgen,csregen:std_logic; -- mem rd, controls for generator 48signal mxo:std_logic_vector(2 downto 0);-- mux of data 49 50begin 51 52pos_ctr<=std_logic_vector(pos_ctri); 53sync<=synci; 54sin<=sini; 55cos<=cosi; 56pha<=phai; 57indo<=indoi; 58 59-- dout 60dout<= mQ when cmd="000" else 61 std_logic_vector(ctr_lim(7 downto 0)) when cmd="010" else 62 lut_ctl when cmd="011" else 63 "01111110"; -- 7e 64 65mD<=din; --always 66 67-- modified controls 68-- cmd: 000 read or write mem, autoinc 69-- 001 zero address - wstb 70-- 010 ctr_lim(7 downto 0) - wstb, rstb 71-- 011 lut_ctl - wstb,rstb 72-- 101 73-- 74-- lut_ctl: run,0,3pha,set_indo,0,dib_lim1,dib_lim0.ctr_lim(8) 75 76 mCEn<='0' when ((cmd="000") and ((wstb='1') or (rstb='1'))) else 77 '0' when rd='1' else 78 '1'; -- 1 cycle long 79 mWEn<='0' when ((cmd="000") and ((wstb='1'))) 80 else '1'; 81 mCLK<=not(clk) and not(mCEn); -- only clock when necessary 82 83process(mQ,dib_ctr) begin -- set mxo(2 downto 0) to indoi,mxo(1),mxo(0) 84 if lut_3ph='0' then 85 mxo(2)<=indo_def; -- per lut_ctl 86 case dib_ctr is 87 when "00"=> 88 mxo(0)<=mQ(0); 89 mxo(1)<=mQ(1); 90 when "01"=> 91 mxo(0)<=mQ(2); 92 mxo(1)<=mQ(3); 93 when "10"=> 94 mxo(0)<=mQ(4); 95 mxo(1)<=mQ(5); 96 when others=> 97 mxo(0)<=mQ(6); 98 mxo(1)<=mQ(7); 99 end case; 100 else -- lut_3ph='1' 101 case dib_ctr is 102 when "00"=> 103 mxo(0)<=mQ(0); 104 mxo(1)<=mQ(1); 105 mxo(2)<=mq(2); 106 when others=> 107 mxo(0)<=mQ(4); 108 mxo(1)<=mQ(5); 109 mxo(2)<=mq(6); 110 end case; 111 end if; 112end process; 113 114process (nreset,clk) -- generator 115begin 116 if nreset='0' then 117 synci<='0'; 118 cosi<='0'; 119 sini<='0'; 120 phai<='0'; 121 pos_ctri<=(others=>'0'); 122 csgen<='0'; -- 1 when running 123 csregen<='0'; -- 1 when output cos,sin to register 124 dib_ctr<=(others=>'0'); 125 mQr<=(others=>'0'); 126 rd<='0'; -- read data byte 127 elsif clk'event and clk='1' then 128 synci<='0'; -- will give a pulse at adr 0 129 rd<='0'; -- pulse 130 if mCEn='0' then -- always autoinc at end of access. 131 mQr<=mQ; 132 mA<=std_logic_vector(unsigned(mA) + 1); 133 end if; 134 if lut_run='0' then -- hold in reset 135 if ((cmd="001") and (wstb='1')) then -- handle table write from spi 136 mA<=(others=>'0'); -- separate or part of cycle 137 elsif (mCEn='0') then 138 mA<=std_logic_vector(unsigned(mA) + 1); 139 end if; 140 dib_ctr<=(others=>'0'); 141 phai<='0'; 142 pos_ctri<=(others=>'0'); 143 else -- lut_run='1' 144 if csregen='1' then -- timing: pha follows cos,sin output 145 phai<=not(phai); 146 end if; 147 if rd='1' then 148 mQr<=mQ; 149 mA<=std_logic_vector(unsigned(mA) + 1); 150 end if; 151 if csgen='0' then 152 mA<=(others=>'0'); -- separate or part of cycle 153 synci<='1'; 154 rd<='1'; 155 else -- csgen='1'; 156 dib_ctr<=dib_ctr+1; 157 if ((pos_ctri=ctr_lim) and (dib_ctr=unsigned(dib_lim))) then 158 dib_ctr<="00"; 159 pos_ctri<=(others=>'0'); 160 mA<=(others=>'0'); 161 rd<='1'; 162 synci<='1'; 163 elsif dib_ctr="11" then 164 dib_ctr<="00"; 165 rd<='1'; 166 end if; 167 end if; 168 end if; 169 elsif clk'event and clk='0' then -- to get cos,sin on negedge 170 if lut_run='0' then 171 csregen<='0'; 172 elsif csregen='0' then 173 if rd='1' then csregen<='1'; end if; -- set it once 174 else -- normal running 175 cosi<=mxo(0); 176 sini<=mxo(1); 177 indoi<=mxo(2); 178 end if; 179 end if; 180end process; 181 182process (nreset,clk) -- handle setting things per cmd 183begin 184 if nreset='0' then 185 ctr_lim<=(others=>'0'); 186 lut_ctl<=(others=>'0'); 187 elsif clk'event and clk='1' then 188 if wstb='1' then 189 case cmd is 190 when "010"=> -- load ctr_lim 191 ctr_lim<=unsigned(lut_ctl(0) & din); -- so load lut ctl first 192 when "011"=> -- load cmd 193 lut_ctl<=din; 194 dib_lim<=unsigned(din(2 downto 1)); 195 ctr_lim(8)<=din(0); 196 when others=> 197 end case; 198 end if; 199 end if; 200end process; 201 202-- this is based on 512 bytes so we do not need 2 upper bits 203mA11<=("00" & mA); 204 205-- based on ram2k8.vhp in vhdl_ip. 206-- need to move this RAM out so we just have ports. 207-- target -Dxfab 512x8 for asic 208-- -Dghdl model for simulation 209-- -Dxilinx model for fpga 210 211r1:ram2k8 port map( 212mCLK,mWEn,mCEn, 213mA11, mD, mQ); 214 215 216end rtl; 217