amd_flash_tb.vhd
上传用户:dgrongshen
上传日期:2016-07-09
资源大小:827k
文件大小:14k
源码类别:

VHDL/FPGA/Verilog

开发平台:

VHDL

  1. -- **************************************************************
  2. --
  3. -- Owner: Xilinx Inc.
  4. -- File:   amd_flash_tb.vhd
  5. --
  6. -- Purpose:  Test bench for AMD Flash Interface and Denali 
  7. -- AMD Flash model.
  8. --
  9. -- **************************************************************
  10. library IEEE;
  11. use IEEE.std_logic_1164.all;
  12. use IEEE.numeric_std.all;
  13. use WORK.pkg_convert.all;
  14. entity AMD_FLASH_TB is
  15. generic (MEM_SIZE : INTEGER := 132);
  16. end AMD_FLASH_TB;
  17. architecture BEHAVIOR of AMD_FLASH_TB is 
  18. -- ******************** CONSTANT DECLARATIONS ***********************
  19. -- CPLD Port Addresses
  20. constant PORT0_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "0000"; -- Read Data, IO, Status
  21. -- Write Address and Data
  22. constant PORT1_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "0001"; -- Write Command
  23. constant PORT2_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "0010"; -- Set ale
  24. constant PORT3_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "0011"; -- clear ale
  25. constant PORT4_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "0100"; -- Set sen
  26. constant PORT5_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "0101"; -- Clear sen
  27. constant PORT6_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "0110"; -- Set wpn
  28. constant PORT7_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "0111"; -- Clear wpn
  29. constant PORT8_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "1000"; -- Set ce0n
  30. constant PORT9_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "1001"; -- Clear ce0n
  31. constant PORTA_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "1010"; -- Set ce1n
  32. constant PORTB_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "1011"; -- Clear ce1n
  33. constant PORTC_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "1100"; -- Set ce2n
  34. constant PORTD_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "1101"; -- Clear ce2n
  35. constant PORTE_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "1110"; -- N/A
  36. constant PORTF_ADDR : STD_LOGIC_VECTOR (3 downto 0) := "1111"; -- Read ry_byn status
  37. constant PAGE_SIZE : INTEGER := 528;
  38. -- ******************* SIGNAL DECLARATIONS **************************
  39. type BIG_MEM is array (0 to MEM_SIZE - 1) of INTEGER; -- Define memory array
  40. signal mem_buffer : BIG_MEM;
  41. signal data_bus      : STD_LOGIC_VECTOR (7 downto 0);
  42. signal cle     : STD_LOGIC;
  43. signal ale     : STD_LOGIC;
  44. signal ren     : STD_LOGIC;
  45. signal wen     : STD_LOGIC;
  46. signal wpn     : STD_LOGIC;
  47. signal sen     : STD_LOGIC;
  48. signal ry_byn  : STD_LOGIC;
  49. signal cpld_ce  : STD_LOGIC; -- CPLD chip enable (active high)
  50. signal port_addr  : STD_LOGIC_VECTOR (3 downto 0); -- Specifies CPLD port address
  51. signal outce0  : STD_LOGIC; -- Output signals 
  52. signal write, read  : STD_LOGIC; -- Port read/write signals (active low)
  53. signal reset  : STD_LOGIC; -- Reset is high when Vcc is ramping up or drops down
  54. -- Active high reset
  55. signal ready  : STD_LOGIC; -- Asserted to read status of RY/BY signal
  56. signal source_tmp : STD_LOGIC_VECTOR (31 downto 0); -- Temp signal for source_cnt
  57. signal fail_flag : STD_LOGIC; -- Asserted when programming fails
  58. signal com_latn : STD_LOGIC; -- Command latch signal
  59. -- ******************** COMPONENT DECLARATIONS **********************
  60. -- Denali AMD UltraNAND Flash Model Component: AM30LV0064D
  61. component am30lv0064d
  62. port( 
  63.     io     : inout STD_LOGIC_VECTOR(7 downto 0);
  64.      cle    : in    STD_LOGIC;
  65.      ale    : in    STD_LOGIC;
  66.      cen    : in    STD_LOGIC;
  67.      ren    : in    STD_LOGIC;
  68.      wen    : in    STD_LOGIC;
  69.      wpn    : in    STD_LOGIC;
  70.      sen    : in    STD_LOGIC;
  71.     ry_byn : out   STD_LOGIC 
  72.     );
  73.   
  74. end component;
  75. -- CPLD NAND Interface => VHDL component
  76. component NAND_INTERFACE
  77. port(
  78. -- Input Signals to CPLD
  79. write_n : in  STD_LOGIC; -- System Write Enable
  80. read_n : in  STD_LOGIC; -- System Read Enable
  81. port_addr : in  STD_LOGIC_VECTOR (3 downto 0); -- Address input to select port
  82. ce_n : in  STD_LOGIC; -- Chip Enable for the interface and UltraNAND 
  83. ry_byn : in  STD_LOGIC; -- RY/BY# input from UltraNAND 
  84. reset : in  STD_LOGIC; -- RESET - high for reset and power transitions
  85. com_lat_n : in  STD_LOGIC; -- COM_LAT from test bench to negate CLE 
  86. -- during command write cycle
  87. -- Output signals from CPLD
  88. ready  : out  STD_LOGIC; -- Allows system to read RY/BY# pin state 
  89. cle : out  STD_LOGIC; -- Command Latch Enable to UltraNAND 
  90. ale : out  STD_LOGIC; -- Address Latch Enable to UltraNAND 
  91. se_n : out  STD_LOGIC; -- Spare Area Enable to UltraNAND 
  92. wp_n  : out  STD_LOGIC; -- Write Protect to UltraNAND 
  93. outce_n : out  STD_LOGIC; -- Chip Enable to UltraNAND 
  94. we_n  : out  STD_LOGIC; -- Write Enable to UltraNAND 
  95. re_n : out  STD_LOGIC -- Read Enable to UltraNAND 
  96. );
  97. end component;
  98. begin
  99. -- ******************** COMPONENT DECLARATION *********************
  100. -- DEN_MODEL: Denali AMD Flash Model Component
  101. DEN_MODEL : am30lv0064d
  102. port map(
  103. io      => data_bus,
  104. cle     => cle,
  105. ale     => ale,
  106. cen     => outce0,
  107. ren     => ren,
  108. wen     => wen,
  109. wpn     => wpn,
  110. sen     => sen,
  111. ry_byn  => ry_byn );
  112. -- Xilinx Timing Model Component
  113. CPLD : NAND_INTERFACE
  114. port map(
  115. -- Inputs
  116. write_n => write,
  117. read_n => read,
  118. port_addr => port_addr,
  119. ce_n => cpld_ce,
  120. ry_byn => ry_byn,
  121. reset => reset,
  122. com_lat_n => com_latn,
  123. -- Outputs
  124. ready  => ready,
  125. cle => cle,
  126. ale => ale,
  127. se_n => sen,
  128. wp_n  => wpn,
  129. outce_n => outce0,
  130. we_n  => wen,
  131. re_n => ren );
  132. -- *************************** SIGNAL DEFINITIONS **************************
  133. -- ***************************** Process: FLOW *****************************
  134. -- Main test flow for AMD UltraNAND Interface
  135. FLOW: process
  136. variable temp  : STD_LOGIC_VECTOR (31 downto 0) := (others => '0');
  137. variable byte_sel  : STD_LOGIC_VECTOR (1 downto 0) := "00";
  138. variable source_cnt : INTEGER := 0;
  139. begin
  140. fail_flag <= '0';
  141. com_latn <= '1';
  142. reset <= '0';
  143. cpld_ce <= '1';
  144. data_bus <= (others => 'Z');
  145. port_addr <= (others => 'Z'); -- Default address
  146. write <= '1';
  147. read <= '1';
  148. wait for 100 us;
  149. -- Activate NAND Interface
  150. reset <= '1';
  151. wait for 200 us;
  152. reset <= '0';
  153. wait for 200 us;
  154. ------------------- INIT ---------------------
  155. ------------------ START ---------------------
  156. -- Write 00h to (PORTADDR + 8)
  157. -- Set OUTCE0# (low) to enable UltraNAND. Data is a don抰 care
  158. port_addr <= PORT8_ADDR;
  159. data_bus <= (others => '0');
  160. write <= '0';
  161. cpld_ce <= '0';
  162. wait for 200 us;
  163. write <= '1';
  164. cpld_ce <= '1';
  165. wait for 100 us;
  166. -- Write 00h to (PORTADDR + 3)
  167. -- Clear ALE (low) prior to issuing command. Data is a don抰 care
  168. port_addr <= PORT3_ADDR;
  169. data_bus <= (others => '0');
  170. write <= '0';
  171. cpld_ce <= '0';
  172. wait for 200 us;
  173. write <= '1';
  174. cpld_ce <= '1';
  175. wait for 100 us;
  176. -- Write FFh to (PORTADDR + 1)
  177. -- Send a reset command to reset the Flash (may be omitted)
  178. port_addr <= PORT1_ADDR;
  179. data_bus <= (others => '1');
  180. write <= '0';
  181. cpld_ce <= '0';
  182. com_latn <= '0';
  183. wait for 200 us;
  184. com_latn <= '1';
  185. wait for 50 us;
  186. cpld_ce <= '1';
  187. write <= '1';
  188. wait for 100 us;
  189. -- Write 00h to (PORTADDR + 1)
  190. -- Send a "Read First Half Page" command to the Flash to set
  191. -- the internal pointer to the first half page region in the Flash
  192. port_addr <= PORT1_ADDR;
  193. data_bus <= (others => '0');
  194. write <= '0';
  195. cpld_ce <= '0';
  196. com_latn <= '0';
  197. wait for 200 us;
  198. com_latn <= '1';
  199. wait for 50 us;
  200. cpld_ce <= '1';
  201. write <= '1';
  202. wait for 100 us;
  203. -- Write 00h to (PORTADDR + 4)
  204. -- Set SE# (low) to allow Spare Area access. Data is a don抰 care
  205. port_addr <= PORT4_ADDR;
  206. data_bus <= (others => '0');
  207. write <= '0';
  208. cpld_ce <= '0';
  209. wait for 200 us;
  210. write <= '1';
  211. cpld_ce <= '1';
  212. wait for 100 us;
  213. -- Write 00h to (PORTADDR + 7)
  214. -- Clear WP# (high) to allow Flash program. Data is a don抰 care
  215. port_addr <= PORT7_ADDR;
  216. data_bus <= (others => '0');
  217. write <= '0';
  218. cpld_ce <= '0';
  219. wait for 200 us;
  220. write <= '1';
  221. cpld_ce <= '1';
  222. wait for 100 us;
  223. -- Write 80h to (PORTADDR + 1)
  224. -- Send an "Input Data" command to the Flash
  225. port_addr <= PORT1_ADDR;
  226. data_bus <= "10000000";
  227. write <= '0';
  228. cpld_ce <= '0';
  229. com_latn <= '0';
  230. wait for 200 us;
  231. com_latn <= '1';
  232. wait for 50 us;
  233. cpld_ce <= '1';
  234. write <= '1';
  235. wait for 100 us;
  236. -- Write 00h to (PORTADDR + 2)
  237. -- Set ALE (high) prior to issuing addresses. Data is a don抰 care
  238. port_addr <= PORT2_ADDR;
  239. data_bus <= (others => '0');
  240. write <= '0';
  241. cpld_ce <= '0';
  242. wait for 200 us;
  243. write <= '1';
  244. cpld_ce <= '1';
  245. wait for 100 us;
  246. -- Write DEST[A7-A0] to (PORTADDR + 0)
  247. -- Load the first address byte into the Flash
  248. port_addr <= PORT0_ADDR;
  249. data_bus <= (others => '0');
  250. write <= '0';
  251. cpld_ce <= '0';
  252. wait for 200 us;
  253. cpld_ce <= '1';
  254. write <= '1';
  255. wait for 100 us;
  256. -- Write DEST[A16-A9] to (PORTADDR + 0)
  257. -- Load the second address byte into the Flash
  258. port_addr <= PORT0_ADDR;
  259. data_bus <= (others => '0');
  260. write <= '0';
  261. cpld_ce <= '0';
  262. wait for 200 us;
  263. cpld_ce <= '1';
  264. write <= '1';
  265. wait for 100 us;
  266. -- Write DEST[A24-A17] to (PORTADDR + 0)
  267. -- Load the third address byte into the Flash
  268. port_addr <= PORT0_ADDR;
  269. data_bus <= (others => '0');
  270. write <= '0';
  271. cpld_ce <= '0';
  272. wait for 200 us;
  273. cpld_ce <= '1';
  274. write <= '1';
  275. wait for 100 us;
  276. -- Write 00h to (PORTADDR + 3)
  277. -- Clear ALE (low) prior to writing data. Data is a don抰 care
  278. port_addr <= PORT3_ADDR;
  279. data_bus <= (others => '0');
  280. write <= '0';
  281. cpld_ce <= '0';
  282. com_latn <= '1';
  283. wait for 200 us;
  284. com_latn <= '0';
  285. wait for 50 us;
  286. cpld_ce <= '1';
  287. write <= '1';
  288. wait for 100 us;
  289. -- Clear SOURCE buffer counter
  290. source_cnt := 0;
  291. -- Does SOURCE = 527, has the last data byte been written?
  292. while (source_cnt <= (MEM_SIZE - 1) ) loop
  293. --source_tmp <= int2vec (source_cnt);
  294. --mem_buffer (vec2int (source_tmp (7 downto 0) ) ) <= source_cnt;
  295. mem_buffer (source_cnt) <= source_cnt;
  296. source_cnt := source_cnt + 1;
  297. wait for 25 us;
  298. end loop;
  299. ------------------ LOOP1 ---------------------
  300. -- This is where we fill the Flash buffer
  301. -- Clear SOURCE buffer counter
  302. source_cnt := 0;
  303. -- Does SOURCE = 527, has the last data byte been written?
  304. while (source_cnt <= (PAGE_SIZE - 1) ) loop
  305. -- Write [SOURCE] to (PORTADDR + 0)
  306. -- Write the data contents at the SOURCE location to the data port
  307. source_tmp <= int2vec (source_cnt);
  308. wait for 25 us;
  309. byte_sel := source_tmp(1 downto 0);
  310. temp := int2vec (mem_buffer ( vec2int (source_tmp (9 downto 2) ) ) );
  311. case byte_sel is
  312. when "00" =>  data_bus(7 downto 0) <= temp(7 downto 0);
  313. when "01" => data_bus(7 downto 0) <= temp(15 downto 8);
  314. when "10" => data_bus(7 downto 0) <= temp(23 downto 16);
  315. when "11" =>  data_bus(7 downto 0) <= temp(31 downto 24);
  316. when others => NULL;
  317. end case;
  318. port_addr <= PORT0_ADDR;
  319. write <= '0';
  320. cpld_ce <= '0';
  321. wait for 200 us;
  322. cpld_ce <= '1';
  323. write <= '1';
  324. wait for 100 us;
  325. -- Increment source pointer to write to next address location
  326. source_cnt := source_cnt + 1;
  327. --wait for 25 us;
  328. end loop;
  329. ------------------ PROG ----------------------
  330. -- All 528 bytes are loaded so program the Flash
  331. -- Write 10h to (PORTADDR + 1)
  332. -- Send a Page Program command to the Flash
  333. port_addr <= PORT1_ADDR;
  334. data_bus <= "00010000";
  335. write <= '0';
  336. cpld_ce <= '0';
  337. com_latn <= '0';
  338. wait for 200 us;
  339. com_latn <= '1';
  340. wait for 50 us;
  341. cpld_ce <= '1';
  342. write <= '1';
  343. wait for 100 us;
  344. -- Write 70h to (PORTADDR + 1)
  345. -- Send a Read Status command to the Flash
  346. port_addr <= PORT1_ADDR;
  347. data_bus <= "01110000";
  348. write <= '0';
  349. cpld_ce <= '0';
  350. com_latn <= '0';
  351. wait for 200 us;
  352. com_latn <= '1';
  353. wait for 50 us;
  354. cpld_ce <= '1';
  355. write <= '1';
  356. wait for 100 us;
  357. ----------------- CHKSTAT --------------------
  358. -- Read from (PORTADDR + 0)
  359. -- Read the device status to see if the program is done
  360. port_addr <= PORT0_ADDR;
  361. data_bus <= (others => 'Z');
  362. read <= '0';
  363. cpld_ce <= '0';
  364. wait for 200 us;
  365. -- Check status of a ready condition
  366. -- If not continue to check the status for a ready condition
  367. --wait until (data_bus(6) = '1');
  368. read <= '1';
  369. cpld_ce <= '1';
  370. wait for 100 us;
  371. ------------------ DONE ----------------------
  372. -- Write 00h to (PORTADDR + 6)
  373. -- Set WP# (low) to re-protect the Flash. Data is a don抰 care
  374. port_addr <= PORT6_ADDR;
  375. data_bus <= "00000000";
  376. write <= '0';
  377. cpld_ce <= '0';
  378. wait for 200 us;
  379. write <= '1';
  380. cpld_ce <= '1';
  381. wait for 100 us;
  382. -- Read from (PORTADDR + 0)
  383. -- Read the device status again to see if the program passed
  384. port_addr <= PORT0_ADDR;
  385. data_bus <= (others => 'Z');
  386. read <= '0';
  387. cpld_ce <= '0';
  388. wait for 200 us;
  389. read <= '1';
  390. cpld_ce <= '1';
  391. wait for 100 us;
  392. if (data_bus(0) = '1') then
  393. ------------------- FAIL ---------------------
  394. -- A '1' in the D0 location indicates a failure condition
  395. -- Write 00h to (PORTADDR + 9)
  396. -- Clear OUTCE0# (high) to disable UltraNAND. Data is a don抰 care
  397. port_addr <= PORT9_ADDR;
  398. data_bus <= "00000000";
  399. write <= '0';
  400. cpld_ce <= '0';
  401. wait for 200 us;
  402. write <= '1';
  403. cpld_ce <= '1';
  404. wait for 100 us;
  405. -- Return (program failed)
  406. -- The program operation failed so return and report
  407. fail_flag <= '1';
  408. else
  409. -- Write 00h to (PORTADDR + 9)
  410. -- Clear OUTCE0# (high) to disable UltraNAND. Data is a don抰 care
  411. port_addr <= PORT9_ADDR;
  412. data_bus <= "00000000";
  413. write <= '0';
  414. cpld_ce <= '0';
  415. wait for 200 us;
  416. write <= '1';
  417. cpld_ce <= '1';
  418. wait for 100 us;
  419. -- Return (program successful) ;The program operation passed so return and report
  420. fail_flag <= '0';
  421. end if;
  422. wait;
  423. end process FLOW;
  424. end BEHAVIOR;