⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitstreamfifo.bsv

📁 基于MATLAB的OFDM发送
💻 BSV
字号:
//----------------------------------------------------------------------//// The MIT License // // Copyright (c) 2007 Alfred Man Cheuk Ng, mcn02@mit.edu // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use,// copy, modify, merge, publish, distribute, sublicense, and/or sell// copies of the Software, and to permit persons to whom the// Software is furnished to do so, subject to the following conditions:// // The above copyright notice and this permission notice shall be// included in all copies or substantial portions of the Software.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR// OTHER DEALINGS IN THE SOFTWARE.//----------------------------------------------------------------------///////////////////////////////////////////////////////////////// Interface and Implementation of BitStreamFIFO// Description: BitStreamFIFO is a fifo that can enq and deq //              arbitrary no. bits/////////////////////////////////////////////////////////////import Vector::*;/////////////////////////////////////////////////////////////// Interface// Name: BitStreamFIFO// Description: A fifo that can enq and deq arbitrary no. elements// Parameters: buf_sz    : FIFO buffer size//             buf_bsz   : buffer index size in no. bits//             io_sz     : max no. io_sz data element can be enq/deq at one time//             io_bsz    : no. bits to specify the element to be enq/deq at one time//             io_data_sz: data element size in no. bits// Methods: enq  : enqueue the first i_b elements in i_data to //                 the end of the fifo//          first: read o_sz elements from the start of fifo//          deq  : dequeue the o_b elements from the start of fifo//          clear: clear the fifo//          usage: return no. buffer used in the fifo//          free:  return no. buffer free in the fifo          /////////////////////////////////////////////////////////////interface BitStreamFIFO#(numeric type buf_sz,                         numeric type buf_bsz,                         numeric type io_sz,                         numeric type io_bsz,                         numeric type io_data_sz);   method Action enq(Bit#(io_bsz) i_sz,                         Vector#(io_sz,Bit#(io_data_sz))  i_data);   method Vector#(io_sz,Bit#(io_data_sz)) first();               method Action deq(Bit#(io_bsz) o_sz);      method Action clear();                   method Bit#(buf_bsz) usage();               method Bit#(buf_bsz) free();            endinterface//////////////////////////////////////////////////////////////// Auxiliary Functions/////////////////////////////////////////////////////////////// dynamic left shifter using barrel shifterfunction Vector#(sz,Bit#(data_sz)) shiftLeft(Vector#(sz,Bit#(data_sz)) i_data, // input data                                             Bit#(s_sz) shift); // left shift amount      function Tuple2#(Bit#(a),Nat)       stageFunc(Tuple2#(Bit#(a),Nat) in, Bool ctrl);      let in_data      = tpl_1(in);      let in_shift     = tpl_2(in);      let new_in_data  = ctrl ? in_data << in_shift : in_data;      let new_in_shift = in_shift << 1;      return tuple2(new_in_data,new_in_shift);   endfunction   Vector#(s_sz,Bool) ctrlVec = unpack(pack(shift));   Nat seed = fromInteger(valueOf(data_sz));   let i_data_b = pack(i_data);   let resTpl = foldl(stageFunc,tuple2(i_data_b,seed),ctrlVec);   return unpack(tpl_1(resTpl));      endfunction// dynamic right shifter using barrel shifterfunction Vector#(sz,Bit#(data_sz)) shiftRight(Vector#(sz,Bit#(data_sz)) i_data, // input data                                              Bit#(s_sz) shift); // right shift amount      function Tuple2#(Bit#(a),Nat)       stageFunc(Tuple2#(Bit#(a),Nat) in, Bool ctrl);      let in_data      = tpl_1(in);      let in_shift     = tpl_2(in);      let new_in_data  = ctrl ? in_data >> in_shift : in_data;      let new_in_shift = in_shift << 1;      return tuple2(new_in_data,new_in_shift);   endfunction   Vector#(s_sz,Bool) ctrlVec = unpack(pack(shift));   Nat seed = fromInteger(valueOf(data_sz));   let i_data_b = pack(i_data);   let resTpl = foldl(stageFunc,tuple2(i_data_b,seed),ctrlVec);   return unpack(tpl_1(resTpl));      endfunction////////////////////////////////////////////////////////////////////// Module Defintion// Name: mkUGBitStreamFIFO// Description: Implementation of BitStreamFIFO interface//              with shifters, methods enq/deq are unguarded, //              user of this module needs to check usage and free //              explicitly to guarantee correctness// Schedule: enq CF {first, deq, usage, free}//           enq SB clear//           enq C  enq//           first CF {enq, first, deq, usage ,free}//           first SB clear//           deq CF {enq, first, usage, free}//           deq SB clear//           deq C  deq//           clear SB clear//           clear SA {enq, first, deq, usage, free}//           usage CF {enq, first, deq, usage, free}//           usage SB clear//           free CF {enq, first, deq, usage, free}//           free SB clear///////////////////////////////////////////////////////////////////module mkUGBitStreamFIFO(BitStreamFIFO#(buf_sz,buf_bsz,io_sz,io_bsz,io_data_sz))   provisos (Add#(buf_sz,1,buf_szp1),             Log#(buf_szp1,buf_bsz),    // Bit#(buf_bsz) ranges 0-buf_sz             Add#(io_sz,1,io_szp1),             Log#(io_szp1,io_bsz),      // Bit#(io_bsz) ranges 0-io_sz             Add#(xxA,io_bsz,buf_bsz),  // io_bsz < buf_bsz             Add#(io_sz,xxB,buf_sz));   // io_sz < buf_sz       Bit#(buf_bsz) maxIdx = fromInteger(valueOf(buf_sz));   Reg#(Vector#(buf_sz,Bit#(io_data_sz))) buffers <- mkReg(newVector);   Reg#(Bit#(buf_bsz)) freeNo <- mkReg(maxIdx);   Reg#(Bit#(buf_bsz)) useNo  <- mkReg(0);   Wire#(Bit#(io_bsz)) subFree <- mkDWire(0);   Wire#(Bit#(io_bsz)) addFree <- mkDWire(0);   Bit#(io_bsz) addUse = subFree;   Bit#(io_bsz) subUse = addFree;   Wire#(Vector#(buf_sz,Bit#(io_data_sz))) newBuffers <- mkDWire(buffers);      // adjust the freeNo/ussNo/buffers dependings on whether enq/deq has been called   rule updateState(True);      freeNo <= freeNo + zeroExtend(addFree) - zeroExtend(subFree);      useNo  <= useNo + zeroExtend(addUse) - zeroExtend(subUse);      buffers <= newBuffers;   endrule      method Action enq(Bit#(io_bsz) i_b,Vector#(io_sz,Bit#(io_data_sz)) i_data);      let extBuffers  = append(buffers,i_data);     // append i_data at the end of buffers      let shftBuffers = shiftRight(extBuffers,i_b); // shift the extended buffers by i_b elements          newBuffers <= take(shftBuffers);              // save back the data      subFree <= i_b;                               // add i_b to freeNo   endmethod      method Vector#(io_sz,Bit#(io_data_sz)) first();       // shift the data so that first element at lsbs      let shftBuffers = shiftRight(buffers,freeNo);      return take(shftBuffers);   endmethod      method Action deq(Bit#(io_bsz) o_b);      addFree <= o_b; // sub o_b to freeNo   endmethod      method Action clear();      freeNo <= maxIdx;   // reset freeNo      useNo <= 0;   endmethod      method Bit#(buf_bsz) usage();      return useNo;   endmethod      method Bit#(buf_bsz) free();      return freeNo;   endmethod   endmodule////////////////////////////////////////////////////////////////////// Module Defintion// Name: mkUGBitStreamLFIFO// Description: Implementation of BitStreamFIFO interface//              with shifters, methods enq/deq are unguarded, //              user of this module needs to check usage and free //              explicitly to guarantee correctness, free returns//              the value after deq  // Schedule: enq CF {first, deq, usage, free}//           enq SB clear//           enq C  enq//           first CF {enq, first, deq, usage ,free}//           first SB clear//           deq CF {enq, first, usage}//           deq SB {free, clear}//           deq C  deq//           clear SB clear//           clear SA {enq, first, deq, usage, free}//           usage CF {enq, first, deq, usage, free}//           usage SB clear//           free CF {enq, first, usage, free}//           free SB clear//           free SA deq              ///////////////////////////////////////////////////////////////////module mkUGBitStreamLFIFO(BitStreamFIFO#(buf_sz,buf_bsz,io_sz,io_bsz,io_data_sz))   provisos (Add#(buf_sz,1,buf_szp1),             Log#(buf_szp1,buf_bsz),   // Bit#(buf_bsz) ranges 0-buf_sz             Add#(io_sz,1,io_szp1),             Log#(io_szp1,io_bsz),     // Bit#(io_bsz) ranges 0-io_sz             Add#(xxA,io_bsz,buf_bsz), // io_bsz < buf_bsz             Add#(io_sz,xxB,buf_sz));  // io_sz < buf_sz       Bit#(buf_bsz) maxIdx = fromInteger(valueOf(buf_sz));   Reg#(Vector#(buf_sz,Bit#(io_data_sz))) buffers <- mkReg(newVector);   Reg#(Bit#(buf_bsz)) freeNo <- mkReg(maxIdx);   Reg#(Bit#(buf_bsz)) useNo  <- mkReg(0);   Wire#(Bit#(io_bsz)) subFree <- mkDWire(0);   Wire#(Bit#(io_bsz)) addFree <- mkDWire(0);   Bit#(io_bsz) addUse = subFree;   Bit#(io_bsz) subUse = addFree;   Wire#(Vector#(buf_sz,Bit#(io_data_sz))) newBuffers <- mkDWire(buffers);      // adjust the freeNo dependings on whether enq/deq has been called   rule updateFreeNo(True);      freeNo <= freeNo + zeroExtend(addFree) - zeroExtend(subFree);      useNo <= useNo + zeroExtend(addUse) - zeroExtend(subUse);      buffers <= newBuffers;   endrule      method Action enq(Bit#(io_bsz) i_b,Vector#(io_sz,Bit#(io_data_sz)) i_data);      let extBuffers  = append(buffers,i_data);     // append i_data at the end of buffers      let shftBuffers = shiftRight(extBuffers,i_b); // shift the extended buffers by i_b elements          newBuffers <= take(shftBuffers);              // save back the data      subFree <= i_b;                               // add i_b to freeNo   endmethod      method Vector#(io_sz,Bit#(io_data_sz)) first();       // shift the data so that first bit at lsb      let shftBuffers = shiftRight(buffers,freeNo);      return take(shftBuffers);   endmethod      method Action deq(Bit#(io_bsz) o_b);      addFree <= o_b; // add o_b to freeNo   endmethod      method Action clear();      freeNo <= maxIdx;   // reset freeNo   endmethod      method Bit#(buf_bsz) usage();      return useNo;   endmethod      method Bit#(buf_bsz) free();      return freeNo + zeroExtend(addFree);   endmethod   endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -