Advertisement
punjusquad

question_9

Dec 17th, 2023
1,304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. ///////////////////////////////////////////////////////////////
  3.  
  4. timeunit 1ns;
  5. timeprecision 1ns;
  6. class Transaction ;
  7. rand bit n; // nickel
  8. rand bit d; // dime
  9. rand bit q; // quarter
  10. constraint C1 { {n,d,q} dist {3'b100:=120, 3'b010:=50, 3'b001:=20};}
  11. endclass: Transaction
  12. ////////////////////////////////////////////////////////////
  13. class Generator;
  14. Transaction trans;
  15. mailbox drv_mb;
  16. mailbox scb_mb;
  17. function new (mailbox drv_mb, scb_mb);
  18. this.drv_mb = drv_mb;
  19. this.scb_mb = scb_mb;
  20. endfunction
  21. /////////////////////
  22. task main (int count);
  23. repeat (count) begin
  24. trans = new();
  25. if (!trans.randomize)
  26. $fatal (0, "<<<<---Randomization Failure--->>>");
  27. drv_mb.put(trans);
  28. scb_mb.put(trans);
  29. end//repeat
  30. endtask
  31. ///////////////////
  32. endclass:Generator
  33. ////////////////////////////////////////////////////////////
  34. class Driver;
  35. Transaction trans;
  36. mailbox gen2drv;
  37. virtual candy_if.TEST tb_port_h;
  38. int nickels, dimes, quarters;
  39. bit done;
  40. function new (virtual candy_if.TEST tb_port_h, mailbox bb);
  41. this.tb_port_h = tb_port_h;
  42. gen2drv = bb;
  43. endfunction
  44. task reset();
  45. tb_port_h.rst <= 0;
  46. $display ("RESET started.. @%0t",$time);
  47. tb_port_h.n <= 0;
  48. tb_port_h.d <= 0;
  49. tb_port_h.q <= 0;
  50. #12ns;
  51. tb_port_h.rst <= 1; // de-assert reset...
  52. $display ("RESET ended.. @%0t",$time);
  53. endtask
  54. ///////////////////////////
  55. task drive(int count);
  56. repeat (count) begin:loop
  57. gen2drv.get(trans);
  58. @(posedge tb_port_h.clk);
  59. tb_port_h.n <= trans.n;
  60. tb_port_h.d <= trans.d;
  61. tb_port_h.q <= trans.q;
  62. @(posedge tb_port_h.clk); // one clock duration pulse
  63. tb_port_h.n <= 0;
  64. tb_port_h.d <= 0;
  65. tb_port_h.q <= 0;
  66. if(tb_port_h.dispense)
  67. repeat (20)@(posedge tb_port_h.clk);//for next set of coins..
  68. nickels += trans.n;
  69. dimes += trans.d;
  70. quarters += trans.q;
  71. end:loop
  72. done = 1'b1; //mailbox emptied
  73. //$display("DRIVER::\tNICKELS = %0d, DIMES = %0d, QUARTERS = %0d\n",nickels, dimes, quarters);
  74. endtask
  75. /////////////////////////////
  76. endclass
  77. ////////////////////////////////////////////////////////////
  78. class Scoreboard;
  79. mailbox scb_mb;
  80. Transaction trans;
  81. nickels, dimes, quarters, num_candies;
  82. int candy_cents, total_cents;
  83. int rn, rd;
  84. ///////////////////////////
  85. function new (mailbox scb_mb);
  86. this.scb_mb = scb_mb;
  87. endfunction
  88. ///////////////////////////
  89. task compute(int count);
  90. repeat (count) begin
  91. scb_mb.get(trans);
  92. nickels += trans.n;
  93. dimes += trans.d;
  94. quarters += trans.q;
  95. candy_cents += 5*trans.n + 10*trans.d + 25*trans.q;
  96. total_cents += 5*trans.n + 10*trans.d + 25*trans.q;
  97. if(candy_cents >= 25) begin
  98. num_candies++;
  99. if(candy_cents==30) rn++;
  100. else if (candy_cents ==35) rd++;
  101. else if (candy_cents ==40) begin rd++;rn++; end
  102. else if (candy_cents ==45) begin rd++;rd++; end
  103. candy_cents = 0; // prepare for the next candy dispense...
  104. end
  105. end //repeat
  106. endtask
  107. ///////////////////////////
  108. task scb_display;
  109. //$display("SCOREBOARD:: TOTAL CENTS=%0d",total_cents);
  110. //$display("SCOREBOARD:: NICKELS = %0d, DIMES = %0d, QUARTERS = %0d\n",
  111. //nickels, dimes, quarters);
  112. $display("SCOREBOARD:: CANDIES = %0d", num_candies);
  113. $display("SCOREBOARD:: DIMES Returned = %0d",rd);
  114. $display("SCOREBOARD:: NICKELS Returned = %0d\n",rn);
  115. endtask
  116. endclass
  117. ////////////////////////////////////////////////////////////
  118. class Monitor;
  119. int num_candies, rn, rd;
  120. virtual candy_if.MONITOR mon_port_h;
  121. //////////////////////
  122. function new(virtual candy_if.MONITOR aa);
  123. mon_port_h = aa;
  124. endfunction
  125. //////////////////////
  126. task collect_info;
  127. @(negedge mon_port_h.clk);
  128. if(mon_port_h.dispense) num_candies++;
  129. if(mon_port_h.rd) rd++;
  130. if(mon_port_h.rn) rn++;
  131. endtask
  132. //////////////////////
  133. task mon_display;
  134. $display ("MONITOR:: CANDIES = %0d", num_candies);
  135. $display ("MONITOR:: DIMES Returned = %0d", rd);
  136. $display ("MONITOR:: NICKELS returned = %0d\n", rn);
  137. endtask
  138. //////////////////////
  139. endclass
  140. ////////////////////////////////////////////////////////////
  141. class Environment;
  142. Generator gen;
  143. mailbox gen_mb, scb_mb;
  144. Driver drv;
  145. Scoreboard scb;
  146. Monitor mon;
  147. bit fail;
  148. // declare handles to the Interface for use by Driver and Monitor
  149. virtual candy_if.TEST tb_port_h;
  150. virtual candy_if.MONITOR mon_port_h;
  151. //////////////////////
  152. function new (virtual candy_if.TEST aa, virtual candy_if.MONITOR bb);
  153. tb_port_h = aa;
  154. mon_port_h = bb;
  155. gen_mb = new(1);
  156. scb_mb = new(1);
  157. gen = new(gen_mb, scb_mb);
  158. drv = new(tb_port_h, gen_mb);
  159. scb = new(scb_mb);
  160. mon = new(mon_port_h);
  161. endfunction
  162. /////////////////////
  163. task run(int count);
  164. pre_test();
  165. test(count);
  166. post_test();
  167. endtask
  168. ////////////////////
  169. task pre_test();
  170. drv.reset;
  171. repeat (5)
  172. @(posedge tb_port_h.clk); // some arbitrary delay...
  173. endtask
  174. ///////////////////
  175. task test(count);
  176. fork:fj1
  177. gen.main(count);
  178. drv.drive(count);
  179. scb.compute(count);
  180. while (!drv.done)
  181. mon.collect_info();
  182. join:fj1
  183. endtask
  184. //////////////////
  185. task post_test();
  186. scb.scb_display();
  187. mon.mon_display();
  188. if((scb.num_candies != mon.num_candies) || mon.num_candies ==0 )
  189. fail = 1;
  190. if((scb.rn != mon.rn) || mon.rn==0)
  191. fail = 1;
  192. if((scb.rd != mon.rd) || mon.rd==0)
  193. fail = 1;
  194. if(fail)
  195. $display ("<<<<<----TEST FAILED --->>>>>>\n");
  196. else
  197. $display ("!!! TEST PASSED !!!\n");
  198. endtask
  199. //////////////////
  200. endclass
  201. ////////////////////////////////////////////////////////////
  202. interface candy_if (input bit clk);
  203. logic rst;
  204. logic n;
  205. logic d;
  206. logic q;
  207. logic dispense;
  208. logic rn;
  209. logic rd;
  210. ///////////
  211. modport DUT (
  212. output dispense, rn ,rd,
  213. input rst, n, d, q, clk
  214. );
  215. modport TEST (
  216. input dispense, rn ,rd, clk,
  217. output rst, n, d, q
  218. );
  219. modport MONITOR (
  220. input dispense, rn, rd, clk
  221. );
  222. endinterface:candy_if
  223. ////////////////////////////////////////////////////////////
  224. program automatic tb_candy_vending (tb_port, mon_port);
  225. candy_if.TEST tb_port;
  226. candy_if.MONITOR mon_port;
  227. Environment env;
  228. int rpt_count = 401;
  229. bit fail;
  230. // declare and initialize the interface handles..
  231. virtual candy_if.TEST tb_port_h = tb_port;
  232. virtual candy_if.MONITOR mon_port_h = mon_port;
  233. // apply the inputs.....
  234. initial begin
  235. env = new (tb_port_h, mon_port_h);
  236. env.run(rpt_count);
  237. end
  238.  
  239.  initial
  240.     begin
  241.         $recordfile("candy_vending_ver3.trn");
  242.         $recordvars();
  243.     end
  244. endprogram
  245. ////////////////////////////////////////////////////////////
  246. module top_candy_vending_ver4;
  247. // generate the clock....
  248. bit clk=1;
  249. always #5 clk++;
  250. // instantiate the interface..
  251. candy_if IF1(
  252. .clk(clk)
  253. );
  254. // instantiate the design unit...
  255. candy_vending U2 (
  256. .design_port(IF1.DUT)
  257. );
  258. // instantiate the program block
  259. tb_candy_vending U1 (
  260. .tb_port(IF1.TEST),
  261. .mon_port(IF1.MONITOR)
  262. );
  263. endmodule
  264. ////////////////////////////////////////////////////////////
  265. module candy_vending ( design_port);
  266. candy_if.DUT design_port;
  267. localparam [3:0] // for holding value of money deposited....
  268. S0 = 4'b0000,
  269. S5 = 4'b0001,
  270. S10 = 4'b0010,
  271. S15 = 4'b0011,
  272. S20 = 4'b0100,
  273. S25 = 4'b0101,
  274. S30 = 4'b0110,
  275. S35 = 4'b0111,
  276. S40 = 4'b1000,
  277. S45 = 4'b1001,
  278. Sdd = 4'b1010, // dummy state...
  279. SDD = 4'b1011; // dispense dime
  280. reg [3:0] cst, nst; /// current and next states...
  281. always_comb begin
  282. nst = cst;
  283. case (cst)
  284. S0 :
  285. if(design_port.n) nst = S5;
  286. else if(design_port.d) nst = S10;
  287. else if(design_port.q) nst = S25;
  288. S5 :
  289. if(design_port.n) nst = S10;
  290. else if(design_port.d) nst = S15;
  291. else if(design_port.q) nst = S30;
  292. S10 :
  293. if(design_port.n) nst = S15;
  294. else if(design_port.d) nst = S20;
  295. else if(design_port.q) nst = S35;
  296. S15 :
  297. if(design_port.n) nst = S20;
  298. else if(design_port.d) nst = S25;
  299. else if(design_port.q) nst = S40;
  300. S20 :
  301. if(design_port.n) nst = S25;
  302. else if(design_port.d) nst = S30;
  303. else if(design_port.q) nst = S45;
  304. S25 , // in all these states candy is dispensed....
  305. S30 ,
  306. S35 ,
  307. S40 ,
  308. SDD : nst = S0;
  309. S45 : nst = Sdd; // candy dispensed in S45
  310. Sdd : nst = SDD; // Sdd is dummy state to separate out release of two dimes....
  311. default: nst = S0;
  312. endcase
  313. end // begin
  314. always_ff @(posedge design_port.clk or negedge design_port.rst) // sequential logic....
  315. if(!design_port.rst)
  316. cst <= S0;
  317. else
  318. cst <= nst;
  319. assign design_port.dispense = (cst == S25)
  320. | (cst == S30)
  321. | (cst == S35)
  322. | (cst == S40)
  323. | (cst == S45);
  324. assign design_port.rn = (cst == S30)
  325. | (cst == S40);
  326. assign design_port.rd = (cst == S35)
  327. | (cst == S40)
  328. | (cst == S45)
  329. | (cst == SDD);
  330. endmodule
  331. ///////////////////////////////////////////
  332.  
  333.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement