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

VHDL/FPGA/Verilog

开发平台:

VHDL

  1. -- **************************************************************
  2. --
  3. -- Owner: Xilinx Inc.
  4. -- File:   samsung_flash_tb.vhd
  5. --
  6. -- Purpose:  Test bench for Samsung Flash Interface and Denali 
  7. -- Samsung 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 NAND_FLASH_TB is
  15. generic (BUF_SIZE : INTEGER := 8);
  16. end NAND_FLASH_TB;
  17. architecture BEHAVIOR of NAND_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 FRAME_SIZE : INTEGER := 32;
  38. -- ******************* SIGNAL DECLARATIONS **************************
  39. type BIG_BUF is array (0 to BUF_SIZE - 1) of INTEGER; -- Define frame array
  40. signal frame_buffer : BIG_BUF;
  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. -- Samsung NAND Flash Memory Device K9F4008W0A
  61. component k9f4008w0a
  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.      rdybyn : out   STD_LOGIC
  72. );
  73. end component;
  74. -- CPLD NAND Interface => VHDL component
  75. component NAND_INTERFACE
  76. port(
  77. -- Input Signals to CPLD
  78. write_n : in  STD_LOGIC; -- System Write Enable
  79. read_n : in  STD_LOGIC; -- System Read Enable
  80. port_addr : in  STD_LOGIC_VECTOR (3 downto 0); -- Address input to select port
  81. ce_n : in  STD_LOGIC; -- Chip Enable for the interface and UltraNAND 
  82. ry_byn : in  STD_LOGIC; -- RY/BY# input from UltraNAND 
  83. reset : in  STD_LOGIC; -- RESET - high for reset and power transitions
  84. com_lat_n : in  STD_LOGIC; -- COM_LAT from test bench to negate CLE 
  85. -- during command write cycle
  86. -- Output signals from CPLD
  87. ready  : out  STD_LOGIC; -- Allows system to read RY/BY# pin state 
  88. cle : out  STD_LOGIC; -- Command Latch Enable to UltraNAND 
  89. ale : out  STD_LOGIC; -- Address Latch Enable to UltraNAND 
  90. se_n : out  STD_LOGIC; -- Spare Area Enable to UltraNAND 
  91. wp_n  : out  STD_LOGIC; -- Write Protect to UltraNAND 
  92. outce_n : out  STD_LOGIC; -- Chip Enable to UltraNAND 
  93. we_n  : out  STD_LOGIC; -- Write Enable to UltraNAND 
  94. re_n : out  STD_LOGIC -- Read Enable to UltraNAND 
  95. );
  96. end component;
  97. begin
  98. -- ******************** COMPONENT DECLARATION *********************
  99. -- DEN_MODEL: Denali Samsung Flash Model Component
  100. DEN_MODEL : k9f4008w0a
  101. port map(
  102. io      => data_bus,
  103. cle     => cle,
  104. ale     => ale,
  105. cen     => outce0,
  106. ren     => ren,
  107. wen     => wen,
  108. wpn     => wpn,
  109. sen     => sen,
  110. rdybyn  => ry_byn );
  111. -- Xilinx Timing Model Component
  112. CPLD : NAND_INTERFACE
  113. port map(
  114. -- Inputs
  115. write_n => write,
  116. read_n => read,
  117. port_addr => port_addr,
  118. ce_n => cpld_ce,
  119. ry_byn => ry_byn,
  120. reset => reset,
  121. com_lat_n => com_latn,
  122. -- Outputs
  123. ready  => ready,
  124. cle => cle,
  125. ale => ale,
  126. se_n => sen,
  127. wp_n  => wpn,
  128. outce_n => outce0,
  129. we_n  => wen,
  130. re_n => ren );
  131. -- *************************** SIGNAL DEFINITIONS **************************
  132. -- ***************************** Process: FLOW *****************************
  133. -- Main test flow for AMD UltraNAND Interface
  134. FLOW: process
  135. variable temp  : STD_LOGIC_VECTOR (31 downto 0) := (others => '0');
  136. variable byte_sel  : STD_LOGIC_VECTOR (1 downto 0) := "00";
  137. variable source_cnt : INTEGER := 0;
  138. begin
  139. fail_flag <= '0';
  140. com_latn <= '1';
  141. reset <= '0';
  142. cpld_ce <= '1';
  143. data_bus <= (others => 'Z');
  144. port_addr <= (others => 'Z'); -- Default address
  145. write <= '1';
  146. read <= '1';
  147. wait for 100 us;
  148. -- Activate NAND Interface
  149. reset <= '1';
  150. wait for 200 us;
  151. reset <= '0';
  152. wait for 200 us;
  153. ------------------- INIT ---------------------
  154. ------------------ START ---------------------
  155. -- Write 00h to (PORTADDR + 8)
  156. -- Set OUTCE0# (low) to enable Flash. Data is a don抰 care
  157. port_addr <= PORT8_ADDR;
  158. data_bus <= (others => '0');
  159. write <= '0';
  160. cpld_ce <= '0';
  161. wait for 200 us;
  162. write <= '1';
  163. cpld_ce <= '1';
  164. wait for 100 us;
  165. -- Write 00h to (PORTADDR + 3)
  166. -- Clear ALE (low) prior to issuing command. Data is a don抰 care
  167. port_addr <= PORT3_ADDR;
  168. data_bus <= (others => '0');
  169. write <= '0';
  170. cpld_ce <= '0';
  171. wait for 200 us;
  172. write <= '1';
  173. cpld_ce <= '1';
  174. wait for 100 us;
  175. -- Write 00h to (PORTADDR + 4)
  176. -- Set SE# (low) to allow Spare Area access. Data is a don抰 care
  177. port_addr <= PORT4_ADDR;
  178. data_bus <= (others => '0');
  179. write <= '0';
  180. cpld_ce <= '0';
  181. wait for 200 us;
  182. write <= '1';
  183. cpld_ce <= '1';
  184. wait for 100 us;
  185. -- Write 00h to (PORTADDR + 7)
  186. -- Clear WP# (high) to allow Flash program. Data is a don抰 care
  187. port_addr <= PORT7_ADDR;
  188. data_bus <= (others => '0');
  189. write <= '0';
  190. cpld_ce <= '0';
  191. wait for 200 us;
  192. write <= '1';
  193. cpld_ce <= '1';
  194. wait for 100 us;
  195. -- Write 80h to (PORTADDR + 1)
  196. -- Send an "Sequential Data Input" command to the Flash
  197. port_addr <= PORT1_ADDR;
  198. data_bus <= "10000000";
  199. write <= '0';
  200. cpld_ce <= '0';
  201. wait for 100 ns;
  202. com_latn <= '0';
  203. wait for 200 us;
  204. com_latn <= '1';
  205. wait for 50 us;
  206. cpld_ce <= '1';
  207. write <= '1';
  208. wait for 100 us;
  209. -- Write 00h to (PORTADDR + 2)
  210. -- Set ALE (high) prior to issuing addresses. Data is a don抰 care
  211. port_addr <= PORT2_ADDR;
  212. data_bus <= (others => '0');
  213. write <= '0';
  214. cpld_ce <= '0';
  215. wait for 200 us;
  216. write <= '1';
  217. cpld_ce <= '1';
  218. wait for 100 us;
  219. -- Write DEST[A7-A0] to (PORTADDR + 0)
  220. -- Load the first address byte into the Flash
  221. port_addr <= PORT0_ADDR;
  222. data_bus <= (others => '0');
  223. write <= '0';
  224. cpld_ce <= '0';
  225. wait for 200 us;
  226. cpld_ce <= '1';
  227. write <= '1';
  228. wait for 100 us;
  229. -- Write DEST[A16-A9] to (PORTADDR + 0)
  230. -- Load the second address byte into the Flash
  231. port_addr <= PORT0_ADDR;
  232. data_bus <= (others => '0');
  233. write <= '0';
  234. cpld_ce <= '0';
  235. wait for 200 us;
  236. cpld_ce <= '1';
  237. write <= '1';
  238. wait for 100 us;
  239. -- Write DEST[A24-A17] to (PORTADDR + 0)
  240. -- Load the third address byte into the Flash
  241. port_addr <= PORT0_ADDR;
  242. data_bus <= (others => '0');
  243. write <= '0';
  244. cpld_ce <= '0';
  245. wait for 200 us;
  246. cpld_ce <= '1';
  247. write <= '1';
  248. wait for 100 us;
  249. -- Write 00h to (PORTADDR + 3)
  250. -- Clear ALE (low) prior to writing data. Data is a don抰 care
  251. port_addr <= PORT3_ADDR;
  252. data_bus <= (others => '0');
  253. write <= '0';
  254. cpld_ce <= '0';
  255. com_latn <= '1';
  256. wait for 200 us;
  257. com_latn <= '0';
  258. wait for 50 us;
  259. cpld_ce <= '1';
  260. write <= '1';
  261. wait for 100 us;
  262. -- Clear SOURCE buffer counter
  263. source_cnt := 0;
  264. -- Does SOURCE = 7, has the last data byte been written?
  265. while (source_cnt <= (BUF_SIZE - 1) ) loop
  266. frame_buffer (source_cnt) <= source_cnt;
  267. source_cnt := source_cnt + 1;
  268. wait for 25 us;
  269. end loop;
  270. ------------------ LOOP1 ---------------------
  271. -- This is where we fill the Flash frame register
  272. -- Clear SOURCE buffer counter
  273. source_cnt := 0;
  274. -- Does SOURCE = 7, has the last data byte been written?
  275. -- FRAME_SIZE = number of bytes in frame register
  276. while (source_cnt <= (FRAME_SIZE - 1) ) loop
  277. -- Write [SOURCE] to (PORTADDR + 0)
  278. -- Write the data contents at the SOURCE location to the data port
  279. source_tmp <= int2vec (source_cnt);
  280. wait for 25 us;
  281. byte_sel := source_tmp(1 downto 0);
  282. temp := int2vec (frame_buffer ( vec2int (source_tmp (9 downto 2) ) ) );
  283. case byte_sel is
  284. when "00" =>  data_bus(7 downto 0) <= temp(7 downto 0);
  285. when "01" => data_bus(7 downto 0) <= temp(15 downto 8);
  286. when "10" => data_bus(7 downto 0) <= temp(23 downto 16);
  287. when "11" =>  data_bus(7 downto 0) <= temp(31 downto 24);
  288. when others => NULL;
  289. end case;
  290. port_addr <= PORT0_ADDR;
  291. write <= '0';
  292. cpld_ce <= '0';
  293. wait for 200 us;
  294. cpld_ce <= '1';
  295. write <= '1';
  296. wait for 100 us;
  297. -- Increment source pointer to write to next address location
  298. source_cnt := source_cnt + 1;
  299. end loop;
  300. ------------------ PROG ----------------------
  301. -- All 32 bytes are loaded from Frame Register to program the Flash
  302. -- Write 10h to (PORTADDR + 1)
  303. -- Send a "Program command" to the Flash
  304. port_addr <= PORT1_ADDR;
  305. data_bus <= "00010000";
  306. write <= '0';
  307. cpld_ce <= '0';
  308. wait for 100 ns;
  309. com_latn <= '0';
  310. wait for 200 us;
  311. com_latn <= '1';
  312. wait for 50 us;
  313. cpld_ce <= '1';
  314. write <= '1';
  315. wait for 100 us;
  316. -- Write 70h to (PORTADDR + 1)
  317. -- Send a Read Status command to the Flash
  318. port_addr <= PORT1_ADDR;
  319. data_bus <= "01110000";
  320. write <= '0';
  321. cpld_ce <= '0';
  322. wait for 100 ns;
  323. com_latn <= '0';
  324. wait for 200 us;
  325. com_latn <= '1';
  326. wait for 50 us;
  327. cpld_ce <= '1';
  328. write <= '1';
  329. wait for 100 us;
  330. ----------------- CHKSTAT --------------------
  331. -- Read from (PORTADDR + 0)
  332. -- Read the device status to see if the program is done
  333. port_addr <= PORT0_ADDR;
  334. data_bus <= (others => 'Z');
  335. read <= '0';
  336. cpld_ce <= '0';
  337. wait for 200 us;
  338. -- Check status of a ready condition
  339. -- If not continue to check the status for a ready condition
  340. read <= '1';
  341. cpld_ce <= '1';
  342. wait for 100 us;
  343. ------------------ DONE ----------------------
  344. -- Write 00h to (PORTADDR + 6)
  345. -- Set WP# (low) to re-protect the Flash. Data is a don抰 care
  346. port_addr <= PORT6_ADDR;
  347. data_bus <= "00000000";
  348. write <= '0';
  349. cpld_ce <= '0';
  350. wait for 200 us;
  351. write <= '1';
  352. cpld_ce <= '1';
  353. wait for 100 us;
  354. -- Read from (PORTADDR + 0)
  355. -- Read the device status again to see if the program passed
  356. port_addr <= PORT0_ADDR;
  357. data_bus <= (others => 'Z');
  358. read <= '0';
  359. cpld_ce <= '0';
  360. wait for 200 us;
  361. read <= '1';
  362. cpld_ce <= '1';
  363. wait for 100 us;
  364. if (data_bus(0) = '1') then
  365. ------------------- FAIL ---------------------
  366. -- A '1' in the D0 location indicates a failure condition
  367. -- Write 00h to (PORTADDR + 9)
  368. -- Clear OUTCE0# (high) to disable UltraNAND. Data is a don抰 care
  369. port_addr <= PORT9_ADDR;
  370. data_bus <= "00000000";
  371. write <= '0';
  372. cpld_ce <= '0';
  373. wait for 200 us;
  374. write <= '1';
  375. cpld_ce <= '1';
  376. wait for 100 us;
  377. -- Return (program failed)
  378. -- The program operation failed so return and report
  379. fail_flag <= '1';
  380. else
  381. -- Write 00h to (PORTADDR + 9)
  382. -- Clear OUTCE0# (high) to disable UltraNAND. Data is a don抰 care
  383. port_addr <= PORT9_ADDR;
  384. data_bus <= "00000000";
  385. write <= '0';
  386. cpld_ce <= '0';
  387. wait for 200 us;
  388. write <= '1';
  389. cpld_ce <= '1';
  390. wait for 100 us;
  391. -- Return (program successful) ;The program operation passed so return and report
  392. fail_flag <= '0';
  393. end if;
  394. wait;
  395. end process FLOW;
  396. end BEHAVIOR;