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.

462 lines
15 KiB

  1. `timescale 1ns/1ps
  2. `define BITS 8
  3. module sc_decoder_fsm #(parameter BITS=8, N=11'd32)(
  4. input clk, rst,
  5. input in_valid,
  6. input signed [N-1:0][BITS-1:0] y,
  7. input [N-1:0] f,
  8. output wire [N-1:0] u_cap,
  9. output wire [N-1:0] v_final,
  10. output wire out_valid
  11. );
  12. //function for fminsum calculation
  13. function void fminsum_calc;
  14. input signed [`BITS-1:0] a;
  15. input signed [`BITS-1:0] b;
  16. output signed [`BITS-1:0] c;
  17. logic [`BITS-2:0] abs_a;
  18. logic [`BITS-2:0] abs_b;
  19. logic [`BITS-2:0] abs_c;
  20. abs_a = (a[`BITS-1]) ? ~a[`BITS-2:0] + 1'b1 : a[`BITS-2:0];
  21. abs_b = (b[`BITS-1]) ? ~b[`BITS-2:0] + 1'b1 : b[`BITS-2:0];
  22. abs_c = (abs_b < abs_a) ? abs_b : abs_a;
  23. c[`BITS-1] = a[`BITS-1] ^ b[`BITS-1];
  24. c[`BITS-2:0] = (c[`BITS-1]) ? ~abs_c + 1'b1 : abs_c;
  25. endfunction
  26. //function for g-value calculation
  27. function void g_calc;
  28. input signed [`BITS-1:0] a;
  29. input signed [`BITS-1:0] b;
  30. input u;
  31. output signed [`BITS:0] c;
  32. c = (u == 0) ? (b + a) : (b + (~a+1'b1));
  33. endfunction
  34. // Parameter
  35. localparam d = $clog2(N);
  36. // Internal Signals
  37. logic [N-1:0][BITS-1:0] L_in, L_out;
  38. logic [d :0] temp_index_f,temp_index_g;
  39. logic [N-1:0] v_in, v_out;
  40. logic [11 :0] jL1,jL2,
  41. jU1,jU2,
  42. jR1,jR2,jR3;
  43. logic ena_v,enb_v,wea_v;
  44. logic ena_L,enb_L,wea_L;
  45. logic [N-1:0]u;
  46. reg signed [BITS-1:0] LRU[2];
  47. reg [N-1:0]v;
  48. // State Variables
  49. logic [4:0] c_state, n_state;
  50. //Auxiliary registers declarations
  51. logic [d:0] depth,depth_reg;
  52. logic [d:0] node,node_reg;
  53. logic [11:0] tmp_L, tmp_L_reg,
  54. tmp_R, tmp_R_reg,
  55. tmp_U, tmp_U_reg;
  56. //FSM States
  57. localparam idle = 5'd0 , root = 5'd1 , wait_L_logic = 5'd2,
  58. wait_L = 5'd3 , state_L = 5'd4 , wait_R_logic = 5'd5,
  59. wait_R = 5'd6 , state_R = 5'd7 , wait_U_logic = 5'd8,
  60. wait_U = 5'd9 , state_U = 5'd10, wait_LRU_logic = 5'd11,
  61. wait_LRU = 5'd12, state_LRU = 5'd13, wait_lnode_logic = 5'd14,
  62. wait_lnode = 5'd15, state_lnode = 5'd16, wait_lstate_logic = 5'd17,
  63. wait_lstate = 5'd18, state_last = 5'd19;
  64. //BlockRAM Instantiations
  65. bram_v #( .ADDR_WIDTH(d-1),
  66. .DATA_WIDTH(N),
  67. .DEPTH(2**(d-1)))
  68. bram_v_i (
  69. .clk(clk),.ena(ena_v),.enb(enb_v),
  70. .addra(depth_reg-1'b1),
  71. .addrb(depth_reg),
  72. .wea(wea_v),
  73. .dia(v_in),
  74. .dob(v_out));
  75. bram_L #( .ADDR_WIDTH(d-1),
  76. .DATA_WIDTH(N*BITS),
  77. .DEPTH(2**(d-1)),
  78. .N(N))
  79. bram_L_i (
  80. .clk(clk),.ena(ena_L),.enb(enb_L),
  81. .addra(depth_reg),
  82. .addrb(depth_reg-1'b1),
  83. .wea(wea_L),
  84. .dia(L_in),
  85. .dob(L_out));
  86. //output assignment
  87. for(genvar i=0; i<N; i++)
  88. assign u_cap[i] = u[i];
  89. assign v_final = v;
  90. assign out_valid = (n_state == state_lnode) ? 1'b1 : 1'b0;
  91. // Sequential Logic - FSM State and Data Registers
  92. always_ff@(posedge clk)
  93. begin
  94. if(rst)
  95. begin
  96. c_state <= idle;
  97. depth_reg <= 0;
  98. node_reg <= 0;
  99. tmp_L_reg <= 0;
  100. tmp_R_reg <= 0;
  101. tmp_U_reg <= 0;
  102. end
  103. else
  104. begin
  105. c_state <= n_state;
  106. depth_reg <= depth;
  107. node_reg <= node;
  108. tmp_L_reg <= tmp_L;
  109. tmp_R_reg <= tmp_R;
  110. tmp_U_reg <= tmp_U;
  111. end
  112. end
  113. //Combinational Logic - FSM Next State Logic
  114. always_comb
  115. begin
  116. u = 0;
  117. v = 0;
  118. // depth = 0;
  119. if(in_valid)
  120. case(c_state)
  121. idle:
  122. begin
  123. depth = 0; node = 0;
  124. tmp_L = 0; tmp_R = 0; tmp_U = 0;
  125. ena_L = 0; wea_L = 0; enb_L = 0;
  126. ena_v = 0; wea_v = 0; enb_v = 0;
  127. u = 0; v = 0;
  128. if(out_valid)
  129. n_state = idle;
  130. else
  131. n_state = root;
  132. end
  133. root:
  134. begin
  135. depth = depth_reg;
  136. node = node_reg;
  137. ena_L = 1'b1; wea_L = 1'b1;
  138. enb_L = 0; ena_v = 0;
  139. wea_v = 0; enb_v = 0;
  140. u = u;
  141. v = v;
  142. for(int k = 0; k < N; k++)
  143. L_in[k] = y[k];
  144. n_state = wait_L_logic;
  145. end
  146. wait_L_logic:
  147. begin
  148. depth = depth_reg + 1'b1; node = ((2*node_reg) + 1'b1);
  149. ena_L = 0; wea_L = 0;
  150. tmp_L = 0; enb_L = 1'b1;
  151. ena_v = 0; wea_v = 0;
  152. enb_v = 0;
  153. u = u;
  154. v = v;
  155. if(depth < d)
  156. n_state = wait_L;
  157. else
  158. n_state = wait_LRU_logic;
  159. end
  160. wait_L:
  161. begin
  162. u = u;
  163. // depth = depth_reg;
  164. n_state = state_L;
  165. end
  166. state_L:
  167. begin
  168. u = u;
  169. v = v;
  170. // depth = depth_reg;
  171. ena_L = 1'b1; wea_L = 1'b1; enb_L = 0;
  172. ena_v = 0; wea_v = 0; enb_v = 0;
  173. tmp_L = tmp_L_reg + 1'b1;
  174. temp_index_f = ((N/(2**(depth+1'b1))) * ((2*(node) + 1'b1) - ((2**(depth + 1'b1)) - 1'b1)));
  175. jL1 = (tmp_L_reg) + temp_index_f;
  176. jL2 = (tmp_L_reg) + temp_index_f + (N/(2**depth));
  177. fminsum_calc(L_out[jL1],L_out[jL2],L_in[jL1]);
  178. if(tmp_L< (N/(2**depth)))
  179. n_state = state_L;
  180. else if(depth < d)
  181. n_state = wait_L_logic;
  182. else
  183. n_state = wait_LRU_logic;
  184. end
  185. wait_R_logic:
  186. begin
  187. u = u;
  188. v = v;
  189. depth = depth_reg - 1'b1;
  190. node = node_reg + 1'b1;
  191. tmp_R = 0;
  192. n_state = wait_R;
  193. end
  194. wait_R:
  195. begin
  196. // depth = depth_reg;
  197. ena_L = 0;wea_L = 0; enb_L = 1'b1;
  198. ena_v = 0;wea_v = 0; enb_v = 1'b1;
  199. u = u;
  200. v = v;
  201. n_state = state_R;
  202. end
  203. state_R:
  204. begin
  205. // depth = depth_reg;
  206. u = u;
  207. v = v;
  208. ena_L = 1'b1; wea_L = 1'b1; enb_L = 0;
  209. ena_v = 0; wea_v = 0; enb_v = 0;
  210. tmp_R = tmp_R_reg + 1'b1;
  211. temp_index_f = ((N/(2**(depth + 1'b1))) * ((2*(node) + 1'b1) -((2**(depth + 1'b1)) - 1'b1)));
  212. temp_index_g = ((N/(2**(depth + 1'b1))) * ((2*(node - 1'b1) + 1'b1)-((2**(depth + 1'b1)) - 1'b1)));
  213. jR1 = (tmp_R_reg) + temp_index_g;
  214. jR2 = (tmp_R_reg) + temp_index_g + (N/(2**depth));
  215. jR3 = (tmp_R_reg) + temp_index_f;
  216. g_calc(L_out[jR1],L_out[jR2],v_out[jR1],L_in[jR3]);
  217. if(tmp_R < (N/(2**depth)))
  218. n_state = state_R;
  219. else if(node == ((2**d) - 2))
  220. n_state = wait_lnode_logic;
  221. else if(depth == d)
  222. n_state = wait_LRU_logic;
  223. else
  224. n_state = wait_L_logic;
  225. end
  226. wait_U_logic:
  227. begin
  228. depth = depth_reg - 1'b1;
  229. node = (node_reg - 2) >> 1;
  230. tmp_U = 0;
  231. u = u;
  232. v = v;
  233. n_state = wait_U;
  234. end
  235. wait_U:
  236. begin
  237. // depth = depth_reg;
  238. ena_L = 0; wea_L = 0; enb_L = 0;
  239. ena_v = 0; wea_v = 0; enb_v = 1'b1;
  240. n_state = state_U;
  241. end
  242. state_U:
  243. begin
  244. // depth = depth_reg;
  245. ena_L = 0; ena_v =1'b1; enb_L = 0;
  246. wea_L = 0; wea_v =1'b1; enb_v = 0;
  247. u = u;
  248. v = v;
  249. tmp_U = tmp_U_reg+1'b1;
  250. temp_index_f = ((N/(2**(depth))) * ((2*node + 1'b1) - ((2**(depth)) - 1'b1)));
  251. jU1 = (tmp_U_reg) + temp_index_f;
  252. jU2 = (tmp_U_reg) + temp_index_f + (N/(2**(depth)));
  253. v_in[jU1] = v_out[jU1] ^ v_out[jU2];
  254. v_in[jU2] = v_out[jU2];
  255. if(tmp_U < (N/(2**(depth))))
  256. n_state = state_U;
  257. else if(depth > 0 && ~node[0])
  258. n_state = wait_U_logic;
  259. else if(depth > 0 && node!=0)
  260. n_state = wait_R_logic;
  261. else
  262. n_state = wait_lstate_logic;
  263. end
  264. wait_LRU_logic:
  265. begin
  266. u = u;
  267. v = v;
  268. // depth = depth_reg;
  269. node = (node_reg - 1'b1) >> 1;
  270. n_state = wait_LRU;
  271. end
  272. wait_LRU:
  273. begin
  274. // depth = depth_reg;
  275. u = u;
  276. v = v;
  277. ena_L = 0; wea_L = 0; enb_L = 1'b1;
  278. ena_v = 0; wea_v = 0; enb_v = 0;
  279. n_state = state_LRU;
  280. end
  281. state_LRU:
  282. begin
  283. // depth = depth_reg;
  284. ena_L = 0; ena_v = 1'b1;
  285. enb_v = 0; wea_v = 1'b1;
  286. wea_L = 0; enb_L = 0;
  287. v = v;
  288. temp_index_f = ((N/(2**(depth))) * ((2*node + 1'b1) - ((2**(depth)) - 1'b1)));
  289. fminsum_calc(L_out[temp_index_f],L_out[temp_index_f + 1],LRU[0]);
  290. u[(2*node)+2-N] = (f[(2*node)+2-N]) ? 0 : ((LRU[0][BITS-1]) ? 1 : 0);
  291. g_calc(L_out[temp_index_f],L_out[temp_index_f+1],u[(2*node)+2-N],LRU[1]);
  292. u[(2*node)+3-N] = (f[(2*node)+3-N]) ? 0 : ((LRU[1][BITS-1]) ? 1 : 0);
  293. v_in[temp_index_f] = u[(2*node)+2-N] ^ u[(2*node)+3-N];
  294. v_in[temp_index_f+1] = u[(2*node)+3-N];
  295. if(node[0])
  296. n_state = wait_R_logic;
  297. else
  298. n_state = wait_U_logic;
  299. end
  300. wait_lnode_logic:
  301. begin
  302. u = u;
  303. v = v;
  304. depth = depth_reg + 1'b1; node = node_reg;
  305. n_state = wait_lnode;
  306. end
  307. wait_lnode:
  308. begin
  309. // depth = depth_reg;
  310. u = u;
  311. v = v;
  312. ena_L = 0; wea_L = 0; enb_L = 1'b1;
  313. ena_v = 0; wea_v = 0; enb_v = 0;
  314. n_state = state_lnode;
  315. end
  316. state_lnode:
  317. begin
  318. // depth = depth_reg;
  319. u = u;
  320. v = v;
  321. ena_L = 0; wea_L = 0; enb_L = 0;
  322. ena_v = 1'b1; wea_v = 1'b1; enb_v = 0;
  323. temp_index_f = ((N/(2**(depth))) * ((2*node + 1'b1) - ((2**(depth)) - 1'b1)));
  324. fminsum_calc(L_out[temp_index_f],L_out[temp_index_f+1],LRU[0]);
  325. u[(2*node)+2-N] = (f[(2*node)+2-N]) ? 0 : ((LRU[0][BITS-1]) ? 1'b1 : 0);
  326. g_calc(L_out[temp_index_f],L_out[temp_index_f+1],u[(2*node)+2-N],LRU[1]);
  327. u[(2*node)+3-N] = (f[(2*node)+3-N]) ? 0 : ((LRU[1][BITS-1]) ? 1'b1 : 0);
  328. v_in[temp_index_f] = u[(2*node)+2-N] ^ u[(2*node)+3-N];
  329. v_in[temp_index_f+1] = u[(2*node)+3-N];
  330. n_state = wait_U_logic;
  331. end
  332. wait_lstate_logic:
  333. begin
  334. u = u;
  335. v = v;
  336. // depth = depth_reg;
  337. node = node_reg;
  338. n_state = wait_lstate;
  339. end
  340. wait_lstate:
  341. begin
  342. // depth = depth_reg;
  343. u = u;
  344. v = v;
  345. ena_L = 0; wea_L = 0; enb_L = 1'b1;
  346. ena_v = 0; wea_v = 0; enb_v = 0;
  347. n_state = state_last;
  348. end
  349. state_last:
  350. begin
  351. // depth = depth_reg;
  352. u = u;
  353. ena_L = 0; wea_L = 0; enb_L = 0;
  354. ena_v = 1'b1; wea_v = 1'b1; enb_v = 0;
  355. v = v_out;
  356. n_state = idle;
  357. end
  358. default:
  359. begin
  360. u = 0;
  361. v = 0;
  362. depth = 0; node = 0;
  363. tmp_L = 0; tmp_R = 0; tmp_U = 0;
  364. ena_L = 0; wea_L = 0; enb_L = 0;
  365. ena_v = 0; wea_v = 0; enb_v = 0;
  366. n_state = idle;
  367. end
  368. endcase
  369. else
  370. begin
  371. u = 0;
  372. v = 0;
  373. depth = 0; node = 0;
  374. tmp_L = 0; tmp_R = 0; tmp_U = 0;
  375. ena_L = 0; wea_L = 0; enb_L = 0;
  376. ena_v = 0; wea_v = 0; enb_v = 0;
  377. n_state = idle;
  378. end
  379. end
  380. endmodule