Guest User

Untitled

a guest
Sep 23rd, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 31.47 KB | None | 0 0
  1. -----------------------------------------------------------------------------------
  2. --! @file reducer_test_model.vhd
  3. --! @brief TEST MODEL for REDUCER :
  4. --! @version 1.0.0
  5. --! @date 2012/4/3
  6. --! @author Ichiro Kawazome <ichiro_k@ca2.so-net.ne.jp>
  7. -----------------------------------------------------------------------------------
  8. --
  9. -- Copyright (C) 2012 Ichiro Kawazome
  10. -- All rights reserved.
  11. --
  12. -- Redistribution and use in source and binary forms, with or without
  13. -- modification, are permitted provided that the following conditions
  14. -- are met:
  15. --
  16. -- 1. Redistributions of source code must retain the above copyright
  17. -- notice, this list of conditions and the following disclaimer.
  18. --
  19. -- 2. Redistributions in binary form must reproduce the above copyright
  20. -- notice, this list of conditions and the following disclaimer in
  21. -- the documentation and/or other materials provided with the
  22. -- distribution.
  23. --
  24. -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. -- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. -- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27. -- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  28. -- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  29. -- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  30. -- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  31. -- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32. -- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33. -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  34. -- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. --
  36. -----------------------------------------------------------------------------------
  37. library ieee;
  38. use ieee.std_logic_1164.all;
  39. package RANDOM_DATA_TABLE is
  40. procedure GET(
  41. WIDTH : in integer;
  42. OFFSET : in integer;
  43. ADDR : in integer;
  44. SIZE : in integer;
  45. LEN : out integer;
  46. DATA : out std_logic_vector;
  47. ENBL : out std_logic_vector;
  48. DONE : out std_logic);
  49. constant TABLE_SIZE : integer := 4096;
  50. constant ERROR_CODE : std_logic_vector(7 downto 0) := "11001100";
  51. end RANDOM_DATA_TABLE;
  52. -----------------------------------------------------------------------------------
  53. --
  54. -----------------------------------------------------------------------------------
  55. library ieee;
  56. use ieee.std_logic_1164.all;
  57. use ieee.numeric_std.all;
  58. use ieee.math_real.uniform;
  59. use std.textio.all;
  60. package body RANDOM_DATA_TABLE is
  61.  
  62. type DATA_TABLE_TYPE is array (INTEGER range <>) of std_logic_vector(7 downto 0);
  63.  
  64. function DATA_TABLE_GEN(SIZE:integer) return DATA_TABLE_TYPE is
  65. variable table : DATA_TABLE_TYPE(0 to SIZE-1);
  66. variable seed1 : integer := 1234;
  67. variable seed2 : integer := 5678;
  68. variable rnd_num : real;
  69. variable pattern : integer range 0 to 255;
  70. begin
  71. for i in table'range loop
  72. UNIFORM(seed1,seed2,rnd_num);
  73. pattern := integer(rnd_num*255.0);
  74. while (pattern = TO_INTEGER(unsigned(ERROR_CODE))) loop
  75. UNIFORM(seed1,seed2,rnd_num);
  76. pattern := integer(rnd_num*255.0);
  77. end loop;
  78. table(i) := std_logic_vector(TO_UNSIGNED(pattern,8));
  79. end loop;
  80. return table;
  81. end function;
  82.  
  83. constant DATA_TABLE : DATA_TABLE_TYPE(0 to TABLE_SIZE-1) := DATA_TABLE_GEN(TABLE_SIZE);
  84.  
  85. procedure GET( WIDTH : in integer;
  86. OFFSET : in integer;
  87. ADDR : in integer;
  88. SIZE : in integer;
  89. LEN : out integer;
  90. DATA : out std_logic_vector;
  91. ENBL : out std_logic_vector;
  92. DONE : out std_logic) is
  93. variable o_data : std_logic_vector(8*WIDTH-1 downto 0);
  94. variable o_enbl : std_logic_vector( WIDTH-1 downto 0);
  95. variable f_enbl : std_logic_vector( WIDTH-1 downto 0);
  96. variable l_enbl : std_logic_vector( WIDTH-1 downto 0);
  97. variable length : integer;
  98. variable addr_end : integer range 0 to TABLE_SIZE-1;
  99. begin
  100. addr_end := OFFSET + SIZE - 1;
  101. for i in f_enbl'range loop
  102. if (i >= OFFSET) then
  103. f_enbl(i) := '1';
  104. else
  105. f_enbl(i) := '0';
  106. end if;
  107. end loop;
  108. for i in l_enbl'range loop
  109. if (i <= addr_end) then
  110. l_enbl(i) := '1';
  111. else
  112. l_enbl(i) := '0';
  113. end if;
  114. end loop;
  115. if (addr_end < WIDTH) then
  116. DONE := '1';
  117. else
  118. DONE := '0';
  119. end if;
  120. o_enbl := f_enbl and l_enbl;
  121. length := 0;
  122. for i in o_enbl'range loop
  123. if (o_enbl(i) = '1') then
  124. length := length + 1;
  125. o_data((i+1)*8-1 downto i*8) := DATA_TABLE(ADDR-OFFSET+i);
  126. else
  127. o_data((i+1)*8-1 downto i*8) := ERROR_CODE;
  128. end if;
  129. end loop;
  130. DATA := o_data;
  131. ENBL := o_enbl;
  132. LEN := length;
  133. end GET;
  134. end RANDOM_DATA_TABLE;
  135. -----------------------------------------------------------------------------------
  136. --
  137. -----------------------------------------------------------------------------------
  138. library ieee;
  139. use ieee.std_logic_1164.all;
  140. entity REDUCER_TEST_MODEL is
  141. generic (
  142. NAME : string;
  143. DELAY : time;
  144. WORD_BITS : integer := 32;
  145. I_WIDTH : integer := 1;
  146. O_WIDTH : integer := 4;
  147. I_JUSTIFIED : integer := 0;
  148. FLUSH_ENABLE : integer := 0;
  149. AUTO_FINISH : integer := 1
  150. );
  151. port(
  152. CLK : in std_logic;
  153. RST : out std_logic;
  154. CLR : out std_logic;
  155. START : out std_logic;
  156. OFFSET : out std_logic_vector(O_WIDTH-1 downto 0);
  157. DONE : out std_logic;
  158. FLUSH : out std_logic;
  159. I_DATA : out std_logic_vector(I_WIDTH*(WORD_BITS )-1 downto 0);
  160. I_ENBL : out std_logic_vector(I_WIDTH*(WORD_BITS/8)-1 downto 0);
  161. I_FLUSH : out std_logic;
  162. I_DONE : out std_logic;
  163. I_VAL : out std_logic;
  164. I_RDY : in std_logic := '0';
  165. O_DATA : in std_logic_vector(O_WIDTH*(WORD_BITS )-1 downto 0) := (others => '0');
  166. O_ENBL : in std_logic_vector(O_WIDTH*(WORD_BITS/8)-1 downto 0) := (others => '1');
  167. O_FLUSH : in std_logic := '0';
  168. O_DONE : in std_logic := '0';
  169. O_VAL : in std_logic := '0';
  170. O_RDY : out std_logic;
  171. BUSY : in std_logic;
  172. FINISH : out std_logic
  173. );
  174. end REDUCER_TEST_MODEL;
  175. -----------------------------------------------------------------------------------
  176. --
  177. -----------------------------------------------------------------------------------
  178. library ieee;
  179. use ieee.std_logic_1164.all;
  180. use ieee.numeric_std.all;
  181. use std.textio.all;
  182. use WORK.RANDOM_DATA_TABLE;
  183. architecture MODEL of REDUCER_TEST_MODEL is
  184. constant I_BYTES : integer := I_WIDTH*WORD_BITS/8;
  185. constant O_BYTES : integer := O_WIDTH*WORD_BITS/8;
  186. constant HEX : STRING(1 to 16) := "0123456789ABCDEF";
  187. signal SCENARIO : STRING(1 to 5);
  188. signal RECV_REQ : boolean;
  189. signal RECV_ACK : boolean;
  190. signal RECV_FLUSH : boolean;
  191. signal RECV_EOD : boolean;
  192. signal RECV_ADDR : integer;
  193. signal RECV_SIZE : integer;
  194. signal RECV_MODE : integer;
  195. signal i_valid : std_logic;
  196. signal o_ready : std_logic;
  197. -------------------------------------------------------------------------------
  198. --
  199. -------------------------------------------------------------------------------
  200. -- function INT_TO_STRING(arg:integer;len:integer;space:character) return STRING is
  201. -- variable str : STRING(1 to len);
  202. -- variable value : integer;
  203. -- begin
  204. -- value := arg;
  205. -- for i in str'right downto str'left loop
  206. -- if (value > 0) then
  207. -- case (value mod 10) is
  208. -- when 0 => str(i) := '0';
  209. -- when 1 => str(i) := '1';
  210. -- when 2 => str(i) := '2';
  211. -- when 3 => str(i) := '3';
  212. -- when 4 => str(i) := '4';
  213. -- when 5 => str(i) := '5';
  214. -- when 6 => str(i) := '6';
  215. -- when 7 => str(i) := '7';
  216. -- when 8 => str(i) := '8';
  217. -- when 9 => str(i) := '9';
  218. -- when others => str(i) := 'X';
  219. -- end case;
  220. -- else
  221. -- if (i = str'right) then
  222. -- str(i) := '0';
  223. -- else
  224. -- str(i) := space;
  225. -- end if;
  226. -- end if;
  227. -- value := value / 10;
  228. -- end loop;
  229. -- return str;
  230. -- end INT_TO_STRING;
  231. begin
  232. -------------------------------------------------------------------------------
  233. --
  234. -------------------------------------------------------------------------------
  235. process
  236. ---------------------------------------------------------------------------
  237. --
  238. ---------------------------------------------------------------------------
  239. procedure WAIT_CLK(CNT:integer) is
  240. begin
  241. if (CNT > 0) then
  242. for i in 1 to CNT loop
  243. wait until (CLK'event and CLK = '1');
  244. end loop;
  245. end if;
  246. wait for DELAY;
  247. end WAIT_CLK;
  248. ---------------------------------------------------------------------------
  249. --
  250. ---------------------------------------------------------------------------
  251. procedure RECV_START (ADDR,SIZE,MODE:integer;FLUSH,EOD:boolean) is
  252. begin
  253. RECV_REQ <= TRUE;
  254. RECV_ADDR <= ADDR;
  255. RECV_SIZE <= SIZE;
  256. RECV_MODE <= MODE;
  257. RECV_FLUSH<= FLUSH;
  258. RECV_EOD <= EOD;
  259. wait until (CLK'event and CLK = '1' and RECV_ACK = TRUE);
  260. wait for DELAY;
  261. RECV_REQ <= FALSE;
  262. end RECV_START;
  263. ---------------------------------------------------------------------------
  264. --
  265. ---------------------------------------------------------------------------
  266. procedure RECV_END is
  267. begin
  268. wait until (CLK'event and CLK = '1' and RECV_ACK = FALSE);
  269. wait for DELAY;
  270. end RECV_END;
  271. ---------------------------------------------------------------------------
  272. --
  273. ---------------------------------------------------------------------------
  274. procedure OUTPUT(ADDR,SIZE:integer;INITIALIZE,LAST,FLUSH:boolean) is
  275. variable data : std_logic_vector(I_DATA'range);
  276. variable enbl : std_logic_vector(I_ENBL'range);
  277. variable valid : std_logic;
  278. variable end_of_data : std_logic;
  279. variable pos : integer;
  280. variable bytes : integer;
  281. variable len : integer;
  282. variable lo_pos : integer;
  283. variable num : integer;
  284. begin
  285. if (INITIALIZE and O_WIDTH > 1) then
  286. for i in OFFSET'range loop
  287. if (i < ((ADDR rem O_BYTES)/(WORD_BITS/8))) then
  288. OFFSET(i) <= '1';
  289. else
  290. OFFSET(i) <= '0';
  291. end if;
  292. end loop;
  293. START <= '1';
  294. end if;
  295. pos := ADDR;
  296. bytes := SIZE;
  297. while (bytes > 0) loop
  298. lo_pos := pos rem I_BYTES;
  299. RANDOM_DATA_TABLE.GET(I_BYTES,lo_pos,pos,bytes,len,data,enbl,end_of_data);
  300. pos := pos + len;
  301. bytes := bytes - len;
  302. if (I_JUSTIFIED > 0 and enbl(0) = '0') then
  303. num := 1;
  304. for i in 1 to enbl'high loop
  305. if (enbl(i) = '1') then
  306. num := i;
  307. exit;
  308. end if;
  309. end loop;
  310. for i in enbl'low to enbl'high loop
  311. if (i+num > enbl'high) then
  312. I_DATA(8*(i+1)-1 downto 8*i) <= (others => '0');
  313. I_ENBL( i) <= '0';
  314. else
  315. I_DATA(8*(i+1)-1 downto 8*i) <= data(8*(i+1+num)-1 downto 8*(i+num));
  316. I_ENBL( i) <= enbl(i+num);
  317. end if;
  318. end loop;
  319. else
  320. I_DATA <= data;
  321. I_ENBL <= enbl;
  322. end if;
  323. if (LAST) then
  324. I_DONE <= end_of_data;
  325. else
  326. I_DONE <= '0';
  327. end if;
  328. if (FLUSH) then
  329. I_FLUSH <= end_of_data;
  330. else
  331. I_FLUSH <= '0';
  332. end if;
  333. I_VAL <= '1';
  334. i_valid <= '1';
  335. wait until (CLK'event and CLK = '1' and I_RDY = '1');
  336. wait for DELAY;
  337. START <= '0';
  338. I_VAL <= '0';
  339. i_valid <= '0';
  340. I_DONE <= '0';
  341. I_FLUSH <= '0';
  342. I_DATA <= (others => '1');
  343. I_ENBL <= (others => '1');
  344. end loop;
  345. end procedure;
  346. ---------------------------------------------------------------------------
  347. --
  348. ---------------------------------------------------------------------------
  349. procedure OUTPUT(ADDR,SIZE:integer) is
  350. begin
  351. OUTPUT(ADDR,SIZE,TRUE,TRUE,FALSE);
  352. end procedure;
  353. ---------------------------------------------------------------------------
  354. --
  355. ---------------------------------------------------------------------------
  356. variable max_addr : integer;
  357. variable max_size : integer;
  358. variable addr : integer;
  359. variable remain_size : integer;
  360. variable block_size : integer;
  361. variable initialize : boolean;
  362. ---------------------------------------------------------------------------
  363. --
  364. ---------------------------------------------------------------------------
  365. procedure DONE_REQ is
  366. begin
  367. DONE <= '1';
  368. wait until (CLK'event and CLK = '1');
  369. wait for DELAY;
  370. DONE <= '0';
  371. end procedure;
  372. ---------------------------------------------------------------------------
  373. --
  374. ---------------------------------------------------------------------------
  375. procedure FLUSH_REQ is
  376. begin
  377. FLUSH <= '1';
  378. wait until (CLK'event and CLK = '1');
  379. wait for DELAY;
  380. FLUSH <= '0';
  381. end procedure;
  382. begin
  383. ---------------------------------------------------------------------------
  384. --
  385. ---------------------------------------------------------------------------
  386. if (I_BYTES > O_BYTES) then
  387. max_addr := I_BYTES;
  388. max_size := (I_BYTES/O_BYTES)*(I_BYTES*5);
  389. else
  390. max_addr := O_BYTES;
  391. max_size := (O_BYTES/I_BYTES)*(O_BYTES*5);
  392. end if;
  393. ---------------------------------------------------------------------------
  394. -- シミュレーションの開始、まずはリセットから。
  395. ---------------------------------------------------------------------------
  396. assert(false) report "Starting Run..." severity NOTE;
  397. SCENARIO <= "START";
  398. RST <= '1';
  399. CLR <= '1';
  400. START <= '0';
  401. OFFSET <= (others => '0');
  402. DONE <= '0';
  403. FLUSH <= '0';
  404. I_DATA <= (others => '0');
  405. I_ENBL <= (others => '0');
  406. I_FLUSH <= '0';
  407. I_DONE <= '0';
  408. I_VAL <= '0';
  409. i_valid <= '0';
  410. WAIT_CLK( 4); RST <= '0';
  411. CLR <= '0';
  412. WAIT_CLK( 4);
  413. ---------------------------------------------------------------------------
  414. --
  415. ---------------------------------------------------------------------------
  416. SCENARIO <= "1.0.0";
  417. for size in 1 to max_size loop
  418. for pos in 0 to max_addr loop
  419. addr := pos*max_addr+pos;
  420. RECV_START(addr,size,0,FALSE,TRUE);
  421. OUTPUT (addr,size );
  422. RECV_END;
  423. end loop;
  424. end loop;
  425. ---------------------------------------------------------------------------
  426. --
  427. ---------------------------------------------------------------------------
  428. SCENARIO <= "2.0.0";
  429. for size in 1 to max_size loop
  430. for pos in 0 to max_addr loop
  431. addr := pos*max_addr+pos;
  432. RECV_START(addr,size,1,FALSE,TRUE);
  433. OUTPUT (addr,size );
  434. RECV_END;
  435. end loop;
  436. end loop;
  437. ---------------------------------------------------------------------------
  438. --
  439. ---------------------------------------------------------------------------
  440. SCENARIO <= "3.0.0";
  441. for size in 1 to max_size loop
  442. for pos in 0 to max_addr loop
  443. addr := pos*max_addr+pos;
  444. RECV_START(addr,size,2,FALSE,TRUE);
  445. OUTPUT (addr,size );
  446. RECV_END;
  447. end loop;
  448. end loop;
  449. ---------------------------------------------------------------------------
  450. --
  451. ---------------------------------------------------------------------------
  452. SCENARIO <= "4.0.0";
  453. if (WORD_BITS = 8 and I_WIDTH > 1) then
  454. for size in 8 to 33 loop
  455. for block_size in 1 to 11 loop
  456. addr := 0;
  457. remain_size := size;
  458. RECV_START(addr,size,0,FALSE,TRUE);
  459. initialize := TRUE;
  460. while (remain_size > 0) loop
  461. if (remain_size <= block_size) then
  462. OUTPUT(addr,remain_size,initialize, TRUE ,FALSE);
  463. addr := addr + remain_size;
  464. remain_size := 0;
  465. else
  466. OUTPUT(addr,block_size ,initialize, FALSE,FALSE);
  467. addr := addr + block_size;
  468. remain_size := remain_size - block_size;
  469. end if;
  470. initialize := FALSE;
  471. end loop;
  472. RECV_END;
  473. end loop;
  474. end loop;
  475. end if;
  476. ---------------------------------------------------------------------------
  477. --
  478. ---------------------------------------------------------------------------
  479. SCENARIO <= "5.0.0";
  480. if (WORD_BITS = 8 and I_WIDTH > 1) then
  481. for size in 8 to 15 loop
  482. for block_size in 1 to 11 loop
  483. for wait_count in 0 to 3 loop
  484. addr := 0;
  485. remain_size := size;
  486. RECV_START(addr,size,0,FALSE,FALSE);
  487. initialize := TRUE;
  488. while (remain_size > 0) loop
  489. if (remain_size <= block_size) then
  490. OUTPUT(addr,remain_size,initialize, FALSE,FALSE);
  491. addr := addr + remain_size;
  492. remain_size := 0;
  493. else
  494. OUTPUT(addr,block_size ,initialize, FALSE,FALSE);
  495. addr := addr + block_size;
  496. remain_size := remain_size - block_size;
  497. end if;
  498. initialize := FALSE;
  499. end loop;
  500. WAIT_CLK(wait_count);
  501. DONE_REQ;
  502. RECV_END;
  503. end loop;
  504. end loop;
  505. end loop;
  506. end if;
  507. ---------------------------------------------------------------------------
  508. --
  509. ---------------------------------------------------------------------------
  510. SCENARIO <= "6.0.0";wait for 0 ns;
  511. if (FLUSH_ENABLE > 0 and WORD_BITS = 8 and I_WIDTH > 1) then
  512. for size in 8 to 33 loop
  513. for block_size in 1 to 11 loop
  514. addr := 0;
  515. remain_size := size;
  516. initialize := TRUE;
  517. while (remain_size > 0) loop
  518. -- assert false report NAME & ":" & SCENARIO &
  519. -- " addr=" & INT_TO_STRING(addr,4,'0') &
  520. -- " size=" & INT_TO_STRING(size,4,'0') &
  521. -- " remain_size=" & INT_TO_STRING(remain_size,4,'0') &
  522. -- " block_size=" & INT_TO_STRING(block_size ,4,'0') severity note;
  523. if (remain_size <= block_size) then
  524. RECV_START(addr,remain_size,0,FALSE,TRUE);
  525. OUTPUT(addr,remain_size,initialize, TRUE ,FALSE);
  526. RECV_END;
  527. addr := addr + remain_size;
  528. remain_size := 0;
  529. else
  530. RECV_START(addr,block_size, 0,TRUE, TRUE);
  531. OUTPUT(addr,block_size ,initialize, FALSE,TRUE );
  532. RECV_END;
  533. addr := addr + block_size;
  534. remain_size := remain_size - block_size;
  535. end if;
  536. initialize := FALSE;
  537. end loop;
  538. end loop;
  539. end loop;
  540. end if;
  541. ---------------------------------------------------------------------------
  542. -- シミュレーション終了
  543. ---------------------------------------------------------------------------
  544. WAIT_CLK(10);
  545. SCENARIO <= "DONE.";
  546. WAIT_CLK(10);
  547. if (AUTO_FINISH = 0) then
  548. assert(false) report NAME & " Run complete..." severity NOTE;
  549. FINISH <= 'Z';
  550. else
  551. FINISH <= 'Z';
  552. assert(false) report NAME & " Run complete..." severity FAILURE;
  553. end if;
  554. wait;
  555. end process;
  556. -------------------------------------------------------------------------------
  557. --
  558. -------------------------------------------------------------------------------
  559. RECV:process
  560. variable addr : integer;
  561. variable size : integer;
  562. variable len : integer;
  563. variable lo_pos : integer;
  564. variable data : std_logic_vector(O_DATA'range);
  565. variable enbl : std_logic_vector(O_ENBL'range);
  566. variable end_of_data : std_logic;
  567. variable data_ok : boolean;
  568. begin
  569. RECV_ACK <= FALSE;
  570. O_RDY <= '0';
  571. o_ready <= '0';
  572. RECV_LOOP: loop
  573. wait until (CLK'event and CLK = '1' and RECV_REQ = TRUE);
  574. wait for DELAY;
  575. RECV_ACK <= TRUE;
  576. if (RECV_MODE = 0) then
  577. O_RDY <= '1';
  578. o_ready <= '1';
  579. else
  580. O_RDY <= '0';
  581. o_ready <= '0';
  582. end if;
  583. addr := RECV_ADDR;
  584. size := RECV_SIZE;
  585. CHK_LOOP: loop
  586. wait until (CLK'event and CLK = '1' and O_VAL = '1');
  587. if (RECV_MODE > 0) then
  588. if (RECV_MODE > 1) then
  589. for i in 2 to RECV_MODE loop
  590. wait until (CLK'event and CLK = '1');
  591. end loop;
  592. end if;
  593. wait for DELAY;
  594. O_RDY <= '1';
  595. o_ready <= '1';
  596. wait until (CLK'event and CLK = '1' and O_VAL = '1');
  597. end if;
  598. lo_pos := addr rem O_BYTES;
  599. RANDOM_DATA_TABLE.GET(O_BYTES,lo_pos,addr,size,len,data,enbl,end_of_data);
  600. addr := addr + len;
  601. size := size - len;
  602. assert (O_ENBL = enbl) report NAME & " Mismatch O_ENBL" severity FAILURE;
  603. data_ok := TRUE;
  604. for i in O_ENBL'range loop
  605. if (O_ENBL(i) = '1') then
  606. if (O_DATA((i+1)*8-1 downto i*8) /= data((i+1)*8-1 downto i*8)) then
  607. data_ok := FALSE;
  608. end if;
  609. end if;
  610. end loop;
  611. assert (data_ok) report NAME & " Mismatch O_DATA" severity FAILURE;
  612. if (RECV_EOD = TRUE) then
  613. if (FLUSH_ENABLE > 0 and RECV_FLUSH) then
  614. assert (O_FLUSH = end_of_data)
  615. report NAME & " Mismatch O_FLUSH" severity FAILURE;
  616. else
  617. assert (O_DONE = end_of_data)
  618. report NAME & " Mismatch O_DONE" severity FAILURE;
  619. end if;
  620. end if;
  621. exit CHK_LOOP when (end_of_data = '1');
  622. wait for DELAY;
  623. if (RECV_MODE > 0) then
  624. O_RDY <= '0';
  625. o_ready <= '0';
  626. end if;
  627. end loop;
  628. if (RECV_EOD = FALSE) then
  629. if (FLUSH_ENABLE > 0 and RECV_FLUSH) then
  630. if (O_FLUSH = '0') then
  631. wait until (CLK'event and CLK = '1' and O_FLUSH = '1');
  632. end if;
  633. else
  634. if (O_DONE = '0') then
  635. wait until (CLK'event and CLK = '1' and O_DONE = '1');
  636. end if;
  637. end if;
  638. end if;
  639. wait for DELAY;
  640. RECV_ACK <= FALSE;
  641. O_RDY <= '0';
  642. o_ready <= '0';
  643. end loop;
  644. end process;
  645. -------------------------------------------------------------------------------
  646. --
  647. -------------------------------------------------------------------------------
  648. CHECK_BUSY: process begin
  649. RECV_LOOP: loop
  650. wait until (CLK'event and CLK = '1' and RECV_ACK = TRUE);
  651. CHK_LOOP_0: loop
  652. wait until (CLK'event and CLK = '1');
  653. assert (BUSY = '0')
  654. report NAME & " Mismatch BUSY /= '0'" severity FAILURE;
  655. exit CHK_LOOP_0 when (i_valid = '1' and I_RDY = '1');
  656. end loop;
  657. CHK_LOOP_1: loop
  658. wait until (CLK'event and CLK = '1');
  659. assert (BUSY = '1')
  660. report NAME & " Mismatch BUSY /= '1'" severity FAILURE;
  661. exit CHK_LOOP_1 when (O_VAL = '1' and o_ready = '1' and O_DONE = '1') or
  662. (O_VAL = '1' and o_ready = '1' and O_FLUSH = '1');
  663. end loop;
  664. CHK_LOOP_2: loop
  665. wait until (CLK'event and CLK = '1');
  666. assert (BUSY = '0')
  667. report NAME & " Mismatch BUSY /= '0'" severity FAILURE;
  668. exit CHK_LOOP_2 when (RECV_ACK = FALSE);
  669. end loop;
  670. end loop;
  671. end process;
  672. end MODEL;
  673. -----------------------------------------------------------------------------------
  674. --
  675. -----------------------------------------------------------------------------------
  676. library ieee;
  677. use ieee.std_logic_1164.all;
  678. package COMPONENTS is
  679. component REDUCER is
  680. generic (
  681. WORD_BITS : integer;
  682. ENBL_BITS : integer;
  683. I_WIDTH : integer;
  684. O_WIDTH : integer;
  685. QUEUE_SIZE : integer;
  686. VALID_MIN : integer;
  687. VALID_MAX : integer;
  688. I_JUSTIFIED : integer;
  689. FLUSH_ENABLE: integer
  690. );
  691. port (
  692. CLK : in std_logic;
  693. RST : in std_logic;
  694. CLR : in std_logic;
  695. START : in std_logic;
  696. OFFSET : in std_logic_vector(O_WIDTH-1 downto 0);
  697. DONE : in std_logic;
  698. FLUSH : in std_logic;
  699. BUSY : out std_logic;
  700. VALID : out std_logic_vector(VALID_MAX downto VALID_MIN);
  701. I_DATA : in std_logic_vector(I_WIDTH*WORD_BITS-1 downto 0);
  702. I_ENBL : in std_logic_vector(I_WIDTH*ENBL_BITS-1 downto 0);
  703. I_DONE : in std_logic;
  704. I_FLUSH : in std_logic;
  705. I_VAL : in std_logic;
  706. I_RDY : out std_logic;
  707. O_DATA : out std_logic_vector(O_WIDTH*WORD_BITS-1 downto 0);
  708. O_ENBL : out std_logic_vector(O_WIDTH*ENBL_BITS-1 downto 0);
  709. O_DONE : out std_logic;
  710. O_FLUSH : out std_logic;
  711. O_VAL : out std_logic;
  712. O_RDY : in std_logic
  713. );
  714. end component;
  715. component REDUCER_TEST_MODEL is
  716. generic (
  717. NAME : string;
  718. DELAY : time;
  719. WORD_BITS : integer;
  720. I_WIDTH : integer;
  721. O_WIDTH : integer;
  722. I_JUSTIFIED : integer;
  723. FLUSH_ENABLE: integer;
  724. AUTO_FINISH : integer
  725. );
  726. port(
  727. CLK : in std_logic;
  728. RST : out std_logic;
  729. CLR : out std_logic;
  730. START : out std_logic;
  731. OFFSET : out std_logic_vector(O_WIDTH-1 downto 0);
  732. DONE : out std_logic;
  733. FLUSH : out std_logic;
  734. I_DATA : out std_logic_vector(I_WIDTH*(WORD_BITS )-1 downto 0);
  735. I_ENBL : out std_logic_vector(I_WIDTH*(WORD_BITS/8)-1 downto 0);
  736. I_FLUSH : out std_logic;
  737. I_DONE : out std_logic;
  738. I_VAL : out std_logic;
  739. I_RDY : in std_logic := '0';
  740. O_DATA : in std_logic_vector(O_WIDTH*(WORD_BITS )-1 downto 0) := (others => '0');
  741. O_ENBL : in std_logic_vector(O_WIDTH*(WORD_BITS/8)-1 downto 0) := (others => '1');
  742. O_FLUSH : in std_logic := '0';
  743. O_DONE : in std_logic := '0';
  744. O_VAL : in std_logic := '0';
  745. O_RDY : out std_logic;
  746. BUSY : in std_logic;
  747. FINISH : out std_logic
  748. );
  749. end component;
  750. end COMPONENTS;
Add Comment
Please, Sign In to add comment