📄 bram16k.cpp
字号:
/* * TU Eindhoven * Eindhoven, The Netherlands * * Name : bram16k.cpp * * Author : A.S.Slusarczyk@tue.nl * * Date : * * Function : RAM based on VirtexII 16kb BlockRAMs * * */ #include "bram16k.h"#ifdef MEM_DBG#include "dbg_mem.h"#endifvoid BRAM16K_WRAPPER::reg(){ sc_bv<2> ar = addr.read().range(1,0);#ifdef MEM_DBG sc_uint<2> _r = r.read(), _w = w.read(); extern void hack_pc(); if( (_r == 1 || _w == 1) && ar != 0 ){ cout << "WARNING: Non-aligned word access address=" << addr.read().to_uint() << " r=" << _r << " w=" << _w << endl; cout << "\t" << name() << " PCs:"; hack_pc(); } if( dbg_mem_hit( addr.read().to_uint() ) ){ cout << "MEMORY ACCESS " << " addr=0x" << hex << addr.read().to_uint() << dec << " " << (_r==2 ? "read byte " : (_r==1 ? "read word " : "") ) << (_w==2 ? "write byte " : (_w==1 ? "write word " : "") ) << "data=0x" << hex << din.read().to_uint() << dec << endl; cout << "\t" << name() << " PCs:"; hack_pc(); }#endif if( en.read()[0]!=0 ) { // register r and w inputs r_reg.write(r.read()); w_reg.write(w.read()); byte_reg.write(ar); }}void BRAM16K_WRAPPER::in(){ // read/write request sc_uint<2> iw=w.read(), ir=r.read(); sc_bv<DWORD> a = addr.read(); // discard two least significant bits of the address // they are only used in byte mode -- // for that purpose they are registered in byte_reg sc_bv<12> a_13_2 = a.range(13,2); sc_uint<12> addr12 = a_13_2; ADDR.write(addr12); sc_bv<DWORD> dwr = din.read(); // if w == 2, we're writing the LSByte of the input word to the appropriate address sc_bv<2> byteb = a.range(1,0); sc_uint<2> byteno = byteb; sc_bv<4> b0 = dwr.range(7,4), b1 = dwr.range(3,0); bool byte_to_0 = (iw==2 && byteno==0), byte_to_1 = (iw==2 && byteno==1), byte_to_2 = (iw==2 && byteno==2), byte_to_3 = (iw==2 && byteno==3); // split the input data between the two memory blocks sc_bv<4> dwr0 = dwr.range(31,28), dwr1 = dwr.range(27,24), dwr2 = dwr.range(23,20), dwr3 = dwr.range(19,16), dwr4 = dwr.range(15,12), dwr5 = dwr.range(11,8), dwr6 = dwr.range(7,4), dwr7 = dwr.range(3,0); DI00.write(byte_to_0 ? b0 : dwr0); DI01.write(byte_to_0 ? b1 : dwr1); DI02.write(byte_to_1 ? b0 : dwr2); DI03.write(byte_to_1 ? b1 : dwr3); DI04.write(byte_to_2 ? b0 : dwr4); DI05.write(byte_to_2 ? b1 : dwr5); DI06.write(byte_to_3 ? b0 : dwr6); DI07.write(byte_to_3 ? b1 : dwr7); // BlockRAM enable needs to be active for both read and write bool e = ((en.read()[0]!=0) && ((ir!=0)||(iw!=0))); EN.write(e); WE0.write(iw==1 || iw==2 && byte_to_0); WE1.write(iw==1 || iw==2 && byte_to_1); WE2.write(iw==1 || iw==2 && byte_to_2); WE3.write(iw==1 || iw==2 && byte_to_3); SSR.write(0); CLK.write(clk.read());}void BRAM16K_WRAPPER::out(){ sc_bv<24> data24; sc_bv<4> d0, d1, d2, d3, d4, d5, d6, d7; sc_bv<8> msbyte; // gather bytes of the word from memory blocks d0 = DO00.read(); d1 = DO01.read(); d2 = DO02.read(); d3 = DO03.read(); d4 = DO04.read(); d5 = DO05.read(); d6 = DO06.read(); d7 = DO07.read(); // check byte/word mode sc_uint<2> iw=w_reg.read(), ir=r_reg.read(); bool byte_mode = (iw==2 || ir==2); data24 = (d2, d3, d4, d5, d6, d7); // depending on mode (byte/word) select the most significant byte if( byte_mode ) { // in byte mode take one of the bytes, // depending on the last two bits of the address sc_uint<2> byteno = byte_reg.read(); switch( byteno ){ case 0: msbyte = (d0,d1); break; case 1: msbyte = (d2,d3); break; case 2: msbyte = (d4,d5); break; case 3: msbyte = (d6,d7); break; } } else { // word mode msbyte = (d0,d1); } dout.write( (msbyte, data24) ); memwait.write( false );}////////////////////////////////////////////////////////////////////////////////////////////////////void BRAM16K_DBGWRAPPER::in(){ bool clk = CLK.read(); dCLK.write(clk); // discard two least significant bits of the address sc_uint<12> addr = ADDR.read().range(13,2); dADDR.write(addr); // split the input data between the memory blocks sc_int<32> dwr = DI.read(); sc_int<4> dwr0 = dwr.range(31,28), dwr1 = dwr.range(28,24), dwr2 = dwr.range(23,20), dwr3 = dwr.range(19,16), dwr4 = dwr.range(15,12), dwr5 = dwr.range(11,8), dwr6 = dwr.range(7,4), dwr7 = dwr.range(3,0); dDI00.write(dwr0); dDI01.write(dwr1); dDI02.write(dwr2); dDI03.write(dwr3); dDI04.write(dwr4); dDI05.write(dwr5); dDI06.write(dwr6); dDI07.write(dwr7); bool en = EN.read(), we = WE.read(); dEN.write(en); dWE.write(we); dSSR.write(0);}void BRAM16K_DBGWRAPPER::out(){ sc_int<32> data; sc_int<4> d0, d1, d2, d3, d4, d5, d6, d7; // gather bytes of the word from memory blocks d0 = dDO00.read(); d1 = dDO01.read(); d2 = dDO02.read(); d3 = dDO03.read(); d4 = dDO04.read(); d5 = dDO05.read(); d6 = dDO06.read(); d7 = dDO07.read(); data = (d0, d1, d2, d3, d4, d5, d6, d7); DO.write( data );}#ifndef VERILOGvoid BRAM16K::mem_init(const char *filename, int size){ vector<sc_int<4>* > v; v.push_back(bram00->memory); v.push_back(bram01->memory); v.push_back(bram02->memory); v.push_back(bram03->memory); v.push_back(bram04->memory); v.push_back(bram05->memory); v.push_back(bram06->memory); v.push_back(bram07->memory); init_memory(&v,size,filename);}void BRAM16K::mem_dump(const char *filename, int size){ vector<sc_int<4>* > v; v.push_back(bram00->memory); v.push_back(bram01->memory); v.push_back(bram02->memory); v.push_back(bram03->memory); v.push_back(bram04->memory); v.push_back(bram05->memory); v.push_back(bram06->memory); v.push_back(bram07->memory); dump_memory(&v,size,filename);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -