StreamFIFOHybrid.bsv
上传用户:aoptech
上传日期:2014-09-22
资源大小:784k
文件大小:12k
源码类别:

3G开发

开发平台:

Others

  1. //----------------------------------------------------------------------//
  2. // The MIT License 
  3. // 
  4. // Copyright (c) 2007 Alfred Man Cheuk Ng, mcn02@mit.edu 
  5. // 
  6. // Permission is hereby granted, free of charge, to any person 
  7. // obtaining a copy of this software and associated documentation 
  8. // files (the "Software"), to deal in the Software without 
  9. // restriction, including without limitation the rights to use,
  10. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the
  12. // Software is furnished to do so, subject to the following conditions:
  13. // 
  14. // The above copyright notice and this permission notice shall be
  15. // included in all copies or substantial portions of the Software.
  16. // 
  17. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  19. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  21. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  22. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  23. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  24. // OTHER DEALINGS IN THE SOFTWARE.
  25. //----------------------------------------------------------------------//
  26. import EHRReg::*;
  27. import Vector::*;
  28. /////////////////////////////////////////////////////////////
  29. // Interface
  30. // Name: StreamFIFO
  31. // Ptrs: sz, s_sz, data_t
  32. // Dscr: A fifo that can enq and deq arbitrary no. of 
  33. //       elements
  34. /////////////////////////////////////////////////////////////
  35. interface StreamFIFO#(numeric type sz,     // buffer sz
  36.       numeric type s_sz,   // shift sz
  37.       type data_t);        // basic data unit
  38.       method Action enq(Bit#(s_sz) i_s_sz, 
  39. Vector#(sz, data_t) i_msg);
  40.       method Vector#(sz, data_t) first();
  41.       method Action deq(Bit#(s_sz) o_s_sz); 
  42.       method Action clear();
  43.       method Bool notEmpty(Bit#(s_sz) o_s_sz); // canDeq?
  44.       method Bool notFull(Bit#(s_sz) i_s_sz);  // canEnq?
  45. //      method Bit#(s_sz) usage(); // no of slots used
  46. //      method Bit#(s_sz) free(); // no of slots unused
  47. endinterface
  48. //////////////////////////////////////////////////////////////
  49. // Functions
  50. /////////////////////////////////////////////////////////////
  51. // shift towards higher index
  52. function Vector#(sz,data_t) shiftLeftBy(Vector#(sz,data_t) inVec,
  53. Bit#(s_sz) shiftBy)
  54.    provisos (Add#(sz,1,szp1),
  55.      Log#(szp1,s_sz),
  56.      Bits#(data_t,data_sz));
  57.    
  58.    function Vector#(sz,data_t) stageFunc(Vector#(sz,data_t) iVec,
  59.  Tuple2#(Bit#(1),Nat) ctrl);
  60.       return (tpl_1(ctrl) == 1) ? 
  61.              unpack(pack(iVec) << tpl_2(ctrl)) : 
  62.              iVec;
  63.    endfunction
  64.    
  65.    Nat dataSz = fromInteger(valueOf(data_sz));
  66.    Vector#(s_sz,Bit#(1)) shiftVec = unpack(shiftBy);
  67.    Vector#(s_sz,Nat) natVec0 = genWith(fromInteger);
  68.    Vector#(s_sz,Nat) natVec1 = map(<< (1),natVec0);
  69.    Vector#(s_sz,Nat) natVec2 = map(* (dataSz),natVec1);
  70.    let ctrlVec = zip(shiftVec, natVec2);
  71.    return foldl(stageFunc,inVec,ctrlVec);
  72.    
  73. endfunction
  74. // shift towards lower index
  75. function Vector#(sz,data_t) shiftRightBy(Vector#(sz,data_t) inVec,
  76.  Bit#(s_sz) shiftBy)
  77.    provisos (Add#(sz,1,szp1),
  78.      Log#(szp1,s_sz),
  79.      Bits#(data_t,data_sz));
  80.    
  81.    function Vector#(sz,data_t) stageFunc(Vector#(sz,data_t) iVec,
  82.  Tuple2#(Bit#(1),Nat) ctrl);
  83.       return (tpl_1(ctrl) == 1) ? 
  84.              unpack(pack(iVec) >> tpl_2(ctrl)) : 
  85.              iVec;
  86.    endfunction
  87.    
  88.    Nat dataSz = fromInteger(valueOf(data_sz));
  89.    Vector#(s_sz,Bit#(1)) shiftVec = unpack(shiftBy);
  90.    Vector#(s_sz,Nat) natVec0 = genWith(fromInteger);
  91.    Vector#(s_sz,Nat) natVec1 = map(<< (1),natVec0);
  92.    Vector#(s_sz,Nat) natVec2 = map(* (dataSz),natVec1);
  93.    let ctrlVec = zip(shiftVec, natVec2);
  94.    return foldl(stageFunc,inVec,ctrlVec);
  95.    
  96. endfunction
  97. ////////////////////////////////////////////////////////////////////
  98. // Module
  99. // Name: mkStreamFIFO
  100. // Ptrs: 
  101. // Dscr: Create an instance of StreamFIFO which is implemented with
  102. //       shifting approach
  103. // Notes: To enq/deq, caller needs to check notFull/notEmpty 
  104. //        explicitly (unguarded) 
  105. ///////////////////////////////////////////////////////////////////
  106. module mkStreamFIFO(StreamFIFO#(sz, s_sz, data_t))
  107.    provisos (Add#(sz,1,szp1),  
  108.              Log#(szp1,s_sz), // calculate s_sz so that Bit#(s_sz) can store values 0 - sz
  109.              Add#(xxA,s_sz,TLog#(TAdd#(TAdd#(sz,sz),1))),
  110.              Bits#(data_t,data_sz));
  111.    
  112.    Bit#(s_sz) maxIdx = fromInteger(valueOf(sz));          // buffer size
  113.    Reg#(Vector#(sz,data_t)) buffers <- mkReg(newVector); // data storage
  114.    EHRReg#(2,Bit#(s_sz)) freeReg <- mkEHRReg(maxIdx);     // no. free slots
  115.    let usedNo = maxIdx - freeReg[0];                     // no. used slots
  116.    
  117.    method Action enq(Bit#(s_sz) i_s_sz, 
  118.                      Vector#(sz, data_t) i_msg);
  119.       let extBuffers = append(buffers, i_msg);           // append i_msg at the end of buffers
  120.       let shfBuffers = shiftRightBy(extBuffers, zeroExtend(i_s_sz)); // shift the extended buffers    
  121.       Vector#(sz, data_t) newBuffers = take(shfBuffers); // new buffers equals to first half of the buffer
  122.       buffers <= newBuffers;
  123.       freeReg[1] <= freeReg[1] - zeroExtend(i_s_sz);
  124.    endmethod
  125.    
  126.    method Vector#(sz, data_t) first(); 
  127.       // shift the data so that first data appeared at the beginning of the fifo
  128.       return shiftRightBy(buffers,freeReg[0]);
  129.    endmethod
  130.    
  131.    method Action deq(Bit#(s_sz) o_s_sz);
  132.       // adjust the no. free slots
  133.       freeReg[0] <= freeReg[0] + zeroExtend(o_s_sz);
  134.    endmethod
  135.    
  136.    method Action clear();
  137.       freeReg[1] <= maxIdx;
  138.    endmethod
  139.    
  140.    method Bool notEmpty(Bit#(s_sz) o_s_sz);
  141.       return usedNo >= zeroExtend(o_s_sz);
  142.    endmethod
  143.    
  144.    method Bool notFull(Bit#(s_sz) i_s_sz);
  145.       return freeReg[0] >= zeroExtend(i_s_sz);
  146.    endmethod
  147.    
  148. //   method Bit#(s_sz) usage();
  149. //      return usedNo;
  150. //   endmethod
  151.    
  152. //   method Bit#(s_sz) free();
  153. //      return freeReg[0];
  154. ///   endmethod
  155. endmodule
  156. ////////////////////////////////////////////////////////////////////
  157. // Module
  158. // Name: mkStreamLFIFO
  159. // Ptrs: 
  160. // Dscr: Create an instance of StreamFIFO which is implemented with
  161. //       shifting approach, can deq and enq parallelly when it is full
  162. // Notes: To enq/deq, caller needs to check notFull/notEmpty 
  163. //        explicitly  
  164. ///////////////////////////////////////////////////////////////////
  165. module mkStreamLFIFO(StreamFIFO#(sz, s_sz, data_t))
  166.    provisos (Add#(sz,1,szp1),  
  167.              Log#(szp1,s_sz), // calculate s_sz so that Bit#(s_sz) can store values 0 - sz
  168.              Add#(xxA,s_sz,TLog#(TAdd#(TAdd#(sz,sz),1))),
  169.              Bits#(data_t,data_sz));
  170.    
  171.    Bit#(s_sz) maxIdx = fromInteger(valueOf(sz));          // buffer size
  172.    Reg#(Vector#(sz,data_t)) buffers <- mkReg(newVector); // data storage
  173.    EHRReg#(2,Bit#(s_sz)) freeReg <- mkEHRReg(maxIdx);     // no. free slots
  174.    let usedNo = maxIdx - freeReg[0];                     // no. used slots
  175.    
  176.    method Action enq(Bit#(s_sz) i_s_sz, 
  177.                      Vector#(sz, data_t) i_msg);
  178.       let extBuffers = append(buffers, i_msg);           // append i_msg at the end of buffers
  179.       let shfBuffers = shiftRightBy(extBuffers, zeroExtend(i_s_sz)); // shift the extended buffers    
  180.       Vector#(sz, data_t) newBuffers = take(shfBuffers); // new buffers equals to first half of the buffer
  181.       buffers <= newBuffers;
  182.       freeReg[1] <= freeReg[1] - zeroExtend(i_s_sz);
  183.    endmethod
  184.    
  185.    method Vector#(sz, data_t) first(); 
  186.       return shiftRightBy(buffers,freeReg[0]);
  187.    endmethod
  188.    
  189.    method Action deq(Bit#(s_sz) o_s_sz); 
  190.       freeReg[0] <= freeReg[0] + zeroExtend(o_s_sz);
  191.    endmethod
  192.    
  193.    method Action clear();
  194.       freeReg[1] <= maxIdx;
  195.    endmethod
  196.    
  197.    method Bool notEmpty(Bit#(s_sz) o_s_sz);
  198.       return usedNo >= zeroExtend(o_s_sz);
  199.    endmethod
  200.    
  201.    method Bool notFull(Bit#(s_sz) i_s_sz);
  202.       return freeReg[0] >= zeroExtend(i_s_sz);
  203.    endmethod
  204.    
  205. //   method Bit#(s_sz) usage();
  206. //      return usedNo;
  207. //   endmethod
  208.    
  209. //   method Bit#(s_sz) free();
  210. //      return freeReg[0];
  211. //   endmethod
  212. endmodule
  213. // ////////////////////////////////////////////////////////////////////
  214. // // Module
  215. // // Name: mkStreamFIFO
  216. // // Ptrs: 
  217. // // Dscr: Create an instance of StreamFIFO which is implemented with
  218. // //       shifting approach
  219. // // Notes: To enq/deq, caller needs to check notFull/notEmpty 
  220. // //        explicitly  
  221. // ///////////////////////////////////////////////////////////////////
  222. // module mkStreamFIFO(StreamFIFO#(sz, s_sz, data_t))
  223. //    provisos (Add#(sz,1,szp1),
  224. //       Log#(szp1,s_sz),
  225. //       Bits#(data_t,data_sz));
  226.    
  227. //    Bit#(s_sz) maxTail = fromInteger(valueOf(sz));
  228. //    EHRReg#(2,Vector#(sz,data_t)) buffer <- mkEHRReg(newVector);       
  229. //    EHRReg#(2,Bit#(s_sz)) tail <- mkEHRReg(0); // equal to usage
  230.    
  231. //    function data_t selTuple(Tuple3#(Bool,data_t,data_t) tup);
  232. //       return tpl_1(tup) ? tpl_2(tup) : tpl_3(tup);
  233. //    endfunction
  234. //    method Action enq(Bit#(s_sz) i_s_sz, 
  235. //       Vector#(sz, data_t) i_msg);
  236. //       let buffer0 = buffer[1];
  237. //       let buffer1 = shiftLeftBy(i_msg, tail[1]);
  238. //       Vector#(sz, Bit#(s_sz)) idxVec = genWith(fromInteger);
  239. //       Vector#(sz, Bool) selBuffer = map(> (tail[1]), idxVec);
  240. //       let zipBuffer = zip3(selBuffer,buffer0,buffer1);
  241. //       let newBuffer = map(selTuple,zipBuffer);
  242. //       buffer[1] <= newBuffer;
  243. //       tail[1] <= tail[1] + i_s_sz;
  244. //    endmethod
  245.    
  246. //    method Vector#(sz, data_t) first(); 
  247. //       return buffer[0];
  248. //    endmethod
  249.    
  250. //    method Action deq(Bit#(s_sz) o_s_sz);
  251. //       buffer[0] <= shiftRightBy(buffer[0], o_s_sz);
  252. //       tail[0] <= tail[0] - o_s_sz;
  253. //    endmethod
  254.    
  255. //    method Action clear();
  256. //       tail[1] <= 0;
  257. //    endmethod
  258.    
  259. //    method Bool notEmpty(Bit#(s_sz) o_s_sz);
  260. //       return tail[0] >= o_s_sz;
  261. //    endmethod
  262.    
  263. //    method Bool notFull(Bit#(s_sz) i_s_sz);
  264. //       return tail[0] <= maxTail - i_s_sz;
  265. //    endmethod
  266.    
  267. //    method Bit#(s_sz) usage();
  268. //       return tail[0];
  269. //    endmethod
  270.    
  271. //    method Bit#(s_sz) free();
  272. //       return maxTail - tail[0];
  273. //    endmethod
  274. // endmodule
  275. // ////////////////////////////////////////////////////////////////////
  276. // // Module
  277. // // Name: mkStreamLFIFO
  278. // // Ptrs: 
  279. // // Dscr: Create an instance of StreamFIFO which is implemented with
  280. // //       shifting approach, can deq and enq parallelly when it is full
  281. // // Notes: To enq/deq, caller needs to check notFull/notEmpty 
  282. // //        explicitly  
  283. // ///////////////////////////////////////////////////////////////////
  284. // module mkStreamLFIFO(StreamFIFO#(sz, s_sz, data_t))
  285. //    provisos (Add#(sz,1,szp1),
  286. //       Log#(szp1,s_sz),
  287. //       Bits#(data_t,data_sz));
  288.    
  289. //    Bit#(s_sz) maxTail = fromInteger(valueOf(sz));
  290. //    EHRReg#(2,Vector#(sz,data_t)) buffer <- mkEHRReg(newVector);       
  291. //    EHRReg#(2,Bit#(s_sz)) tail <- mkEHRReg(0); // equal to usage
  292.    
  293. //    function data_t selTuple(Tuple3#(Bool,data_t,data_t) tup);
  294. //       return tpl_1(tup) ? tpl_2(tup) : tpl_3(tup);
  295. //    endfunction
  296. //    method Action enq(Bit#(s_sz) i_s_sz, 
  297. //       Vector#(sz, data_t) i_msg);
  298. //       let buffer0 = buffer[1];
  299. //       let buffer1 = shiftLeftBy(i_msg, tail[1]);
  300. //       Vector#(sz, Bit#(s_sz)) idxVec = genWith(fromInteger);
  301. //       Vector#(sz, Bool) selBuffer = map(> (tail[1]), idxVec);
  302. //       let zipBuffer = zip3(selBuffer,buffer0,buffer1);
  303. //       let newBuffer = map(selTuple,zipBuffer);
  304. //       buffer[1] <= newBuffer;
  305. //       tail[1] <= tail[1] + i_s_sz;
  306. //    endmethod
  307.    
  308. //    method Vector#(sz, data_t) first(); 
  309. //       return buffer[0];
  310. //    endmethod
  311.    
  312. //    method Action deq(Bit#(s_sz) o_s_sz);
  313. //       buffer[0] <= shiftRightBy(buffer[0], o_s_sz);
  314. //       tail[0] <= tail[0] - o_s_sz;
  315. //    endmethod
  316.    
  317. //    method Action clear();
  318. //       tail[1] <= 0;
  319. //    endmethod
  320.    
  321. //    method Bool notEmpty(Bit#(s_sz) o_s_sz);
  322. //       return tail[0] >= o_s_sz;
  323. //    endmethod
  324.    
  325. //    method Bool notFull(Bit#(s_sz) i_s_sz);
  326. //       return tail[1] <= maxTail - i_s_sz; // slower ready signal 
  327. //    endmethod
  328. //    method Bit#(s_sz) usage();
  329. //       return tail[0];
  330. //    endmethod
  331.    
  332. //    method Bit#(s_sz) free();
  333. //       return maxTail - tail[1];
  334. //    endmethod   
  335. // endmodule