Projektdaten für das ESY1B Praktikum im Sommersemester 2022
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SPI_FRAM_tb.sv 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. //This testbench verifies all implemented functions of the Module "SPI-FRAM-Module". That contains Read/Write to memory, Status register read and Hibernation.
  2. `timescale 1us/1ns
  3. module SPI_FRAM_tb;
  4. reg SI, SO; //init all registers that are connected to the identical named ports of the FRAM-Module.
  5. reg SCK, nCS;
  6. reg [7:0] opcode;
  7. reg [7:0] mem_data [1023:0] ;
  8. reg [23:0] addr; //3 Byte Memory Address for test only the lower 13 are used (2^13 = 8192)
  9. reg [7:0] stat_reg;
  10. reg hibernate;
  11. SPI_FRAM_Module dut(.nCS(nCS), .SCK(SCK), .SI(SI), .SO(SO), .opcode(opcode), .addr(addr), .mem_data(mem_data),. stat_reg(stat_reg), .hibernate(hibernate));
  12. initial begin //values are set to startup values of FRAM
  13. nCS = 1'b1;
  14. SCK = 1'b0;
  15. end
  16. //generate 40MHz clock
  17. always @(nCS) begin
  18. while (nCS == 0) #12.5 SCK = ~SCK;
  19. if (nCS == 1) SCK = 0;
  20. end
  21. initial begin
  22. $dumpfile("dump.vcd");
  23. $dumpvars;
  24. SI = 0;
  25. nCS = 0;
  26. //TEST READ MEMORY
  27. // Sends 8'b00000011 as Read Opcode
  28. SI = 0;
  29. #25 SI = 0;
  30. #25 SI = 0;
  31. #25 SI = 0;
  32. #25 SI = 0;
  33. #25 SI = 0;
  34. #25 SI = 1;
  35. #25 SI = 1;
  36. #25; assert (opcode == 8'h03);
  37. //first byte (only the highest 4 bits are used) of 20-Bit address
  38. SI = 0;
  39. #25 SI = 0;
  40. #25 SI = 0;
  41. #25 SI = 0;
  42. #25 SI = 0;
  43. #25 SI = 0;
  44. #25 SI = 0;
  45. #25 SI = 0;
  46. //second Byte of 20-Bit address
  47. #25 SI = 0;
  48. #25 SI = 0;
  49. #25 SI = 0;
  50. #25 SI = 0;
  51. #25 SI = 0;
  52. #25 SI = 0;
  53. #25 SI = 0;
  54. #25 SI = 0;
  55. //third byte of address
  56. #25 SI = 0;
  57. #25 SI = 0;
  58. #25 SI = 0;
  59. #25 SI = 0;
  60. #25 SI = 0;
  61. #25 SI = 0;
  62. #25 SI = 1;
  63. #25 SI = 1;
  64. //read one Byte (200clocks/25 clocks per bit = 8 bit)
  65. #25 assert (addr == 24'h000003); //check address
  66. //check for correct writing to SPI out of memory
  67. #25 assert (SO == 0);
  68. #25 assert (SO == 0);
  69. #25 assert (SO == 1);
  70. #25 assert (SO == 1);
  71. #25 assert (SO == 0);
  72. #25 assert (SO == 0);
  73. #25 assert (SO == 1);
  74. #25 assert (SO == 1);
  75. //Message is finished, so nCS is not active
  76. nCS = 1;
  77. #50 nCS = 0; //enable nCS after 50 clock cycles for next test
  78. //TEST WRITE MEMORY
  79. //send WREN opcode to set WEL bit
  80. SI = 0;
  81. #25 SI = 0;
  82. #25 SI = 0;
  83. #25 SI = 0;
  84. #25 SI = 0;
  85. #25 SI = 1;
  86. #25 SI = 1;
  87. #25 SI = 0;
  88. //to set WEL-bit, nCS needs to be high (inactive)
  89. #25 nCS = 1;
  90. #25 assert (opcode == 8'h06); //check if the WREN-opcode was recognized
  91. #25 nCS = 0;
  92. assert (stat_reg[1] == 1'b1); //check if WEL-Bit is set
  93. //after stat_reg is set, the next opcode WRITE can be received
  94. SI = 0;
  95. #25 SI = 0;
  96. #25 SI = 0;
  97. #25 SI = 0;
  98. #25 SI = 0;
  99. #25 SI = 0;
  100. #25 SI = 1;
  101. #25 SI = 0;
  102. #25 assert (opcode == 8'h02);
  103. //the next 3 following Bytes are the address. the upper 4 Bits are cut off.
  104. //Highest Byte 1
  105. SI = 0;
  106. #25 SI = 0;
  107. #25 SI = 0;
  108. #25 SI = 0;
  109. #25 SI = 0;
  110. #25 SI = 0;
  111. #25 SI = 0;
  112. #25 SI = 0;
  113. //second address Byte
  114. #25 SI = 0;
  115. #25 SI = 0;
  116. #25 SI = 0;
  117. #25 SI = 0;
  118. #25 SI = 0;
  119. #25 SI = 0;
  120. #25 SI = 0;
  121. #25 SI = 0;
  122. //third address Byte
  123. #25 SI = 0;
  124. #25 SI = 0;
  125. #25 SI = 0;
  126. #25 SI = 0;
  127. #25 SI = 0;
  128. #25 SI = 0;
  129. #25 SI = 1;
  130. #25 SI = 0;
  131. #25 assert (addr == 24'h000002);
  132. //the following SI is written to the memory at the address "addr"
  133. //one Byte is written
  134. assert (mem_data[24'h000002] == 8'hFF); //check data at addr before to see difference after writing to it
  135. SI = 0;
  136. #25 SI = 1;
  137. #25 SI = 1;
  138. #25 SI = 1;
  139. #25 SI = 0;
  140. #25 SI = 0;
  141. #25 SI = 1;
  142. #25 SI = 0;
  143. //Message is finished, so nCS is not active
  144. #12.5 nCS = 1;
  145. #50 nCS = 0; //enable nCS after 50 clock cycles for next test
  146. assert (mem_data[24'h000002] == 8'h72); //check if the operation wrote the correct data to the correct address; 8'h72 is used because it is not symmetrical and the first and last bit are 0. Since the memory (see memory.txt) has 8'hFF written to all other bytes it is easily recognized if a 0 was accidentally written elsewhere.
  147. assert (mem_data[24'h000001] == 8'hFF);
  148. //test to see if write accidentally wrote in the next memory byte
  149. assert (mem_data[24'h000003] == 8'h33);
  150. //test opcode read status register
  151. SI = 0;
  152. #25 SI = 0;
  153. #25 SI = 0;
  154. #25 SI = 0;
  155. #25 SI = 0;
  156. #25 SI = 1;
  157. #25 SI = 0;
  158. #25 SI = 1;
  159. #25 assert (opcode == 8'h05);
  160. //Test correct writing to SPI of status register (stat_reg = 8'h20)
  161. #25 assert (SO == 0);
  162. #25 assert (SO == 0);
  163. #25 assert (SO == 1);
  164. #25 assert (SO == 0);
  165. #25 assert (SO == 0);
  166. #25 assert (SO == 0);
  167. #25 assert (SO == 0);
  168. #25 assert (SO == 0);
  169. assert (stat_reg == 8'h20);
  170. //Message is finished, so nCS is not active
  171. #50 nCS = 1;
  172. #25 nCS = 0; //enable nCS and SCK after 50 clock cycles for next test
  173. //TEST HIBERNATE MODE
  174. //send opcode
  175. SI = 1;
  176. #25 SI = 0;
  177. #25 SI = 1;
  178. #25 SI = 1;
  179. #25 SI = 1;
  180. #25 SI = 0;
  181. #25 SI = 0;
  182. #25 SI = 1;
  183. #25 assert (opcode == 8'hb9);
  184. //Message is finished, so nCS is not active
  185. //hibernate is set on the rising edge of nCS and reset at the falling edge of nCS
  186. nCS = 1;
  187. #25 assert (hibernate == 1);
  188. #500 nCS = 0; //enable nCS and SCK after 50 clock cycles for next test
  189. #25 assert (hibernate == 0);
  190. end
  191. endmodule