bluespec.com Forum Index bluespec.com
Bluespec Forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Different Types Of Bram In A Vector

 
Post new topic   Reply to topic    bluespec.com Forum Index -> Designing with BSV's Rules, Interfaces, ...
View previous topic :: View next topic  
Author Message
Oyku



Joined: 27 Jul 2016
Posts: 7

PostPosted: Thu Sep 01, 2016 5:45 am    Post subject: Different Types Of Bram In A Vector Reply with quote

I created a vector of brams. However I want the brams' address sizes to differ from each other. For example I want to have

BRAM_DUAL_PORT#(Bit#(2), Bit#(64)) b <- mkBRAMCore2Load(valueof(TExp#(2)), _ , "_", _);
and
BRAM_DUAL_PORT#(Bit#(20), Bit#(64)) b1 <- mkBRAMCore2Load(valueof(TExp#(20)), _, "_", _);

inside the same vector. I need to write Vector#(2, BRAM_DUAL_PORT#(Bit#(20), Bit#(64))) brams. But since I write the vector like this it allocates 20 bits for the first bram as the address too.

What I want is to have different types of brams inside the same vector.

I tried using tagged union, using an interface but they are not helping still. I dont want to seperate the brams by deleting the vector implementation too. Because I need to add or remove lots of brams in future.

I am now checking the HList(I checked the HList.bsv too) but I couldn't find any usage of HList in general.

Is there any other thing that I can try? Also can you help me how to instantiate an HList, because I am getting errors when doing it?

Thank you.
Back to top
View user's profile Send private message
quark
Site Admin


Joined: 02 Nov 2007
Posts: 494

PostPosted: Thu Sep 01, 2016 5:28 pm    Post subject: Re: Different Types Of Bram In A Vector Reply with quote

Can you explain more about how the BRAM sizes are chosen? Are the sizes related in some way? Or are they unrelated arbitrary sizes that you have chosen?

If the sizes were related, for example, if you want to make a Vector of BRAM modules with index sizes 1, 2, 3, ..., up to a parameter N, then that would make sense as something you might want to write compactly with a for-loop or "replicateM" or "mapM". (If that's what you want to do, let me know, and I can offer suggestions.)

But if you have to manually provide the size of each BRAM, then you have to manually write something N times, so you're not saving any effort by using a Vector (or HList) to generate the instantiations. You might as well instantiate each one individually. (Particularly if you are also providing a unique Load file for each BRAM.)

However, another reason to want a Vector, is to be able to index into the elements easily -- for example, picking a BRAM based on a register value, or a rule that operates on all of the BRAMs using a for-loop that indexes into the Vector. Do you plan to index into the vector of BRAMs, is that why you want a Vector? (If so, I can offer suggestions for that.)

HList probably won't help you here, but at its core, it looks like this:
Code:
HCons#(Bool, HCons#(Bit#(4), HCons#(Bit#(8), HNil))) vals;
vals = hCons(True, hCons(7, hCons(15, hNil)));

There are convenience functions defined for sizes up to 8:
Code:
HList3#(Bool, Bit#(4), Bit#(8)) vals;
vals = hList3(True, 7, 15);

The function "hHead" and "hTail" can be used to iterate over the elements.

For an HList whose elements are of unique types, there are convenience functions "getIt" and "putIt" which implicitly know which element to get or put based on the type.
Back to top
View user's profile Send private message
Oyku



Joined: 27 Jul 2016
Posts: 7

PostPosted: Fri Sep 02, 2016 4:52 am    Post subject: Reply with quote

They are going to be chosen as valueof(TExp#(2)), valueof(TExp#(3)), valueof(TExp#(4)) and so on till a valueof(TExp#(N)) and also I am loading all of the brams from different binary files. (1.bin, 2.bin, 3.bin .... N.bin)

Yes the reason I want to use the vectors are for indexing actually. I need to use the brams inside a loop (brams[i])
Back to top
View user's profile Send private message
quark
Site Admin


Joined: 02 Nov 2007
Posts: 494

PostPosted: Fri Sep 02, 2016 4:05 pm    Post subject: Reply with quote

At the place where you index into the Vector, the result that you get back (one of the BRAMs) must have statically known type. So every element of the list must have the same type. The hardware implementations can differ, but the interface type that's stored in the list needs to be the same.

One way to do this, if some of the BRAMs have smaller indices, is to extend the smaller interfaces into the same size as the largest interface. For example:
Code:
function BRAM_DUAL_PORT#(Bit#(n), t) extend_BRAM_DUAL_PORT(BRAM_DUAL_PORT#(Bit#(m), t) ram)
  provisos (Add#(m,k,n));
  return (interface BRAM_DUAL_PORT;
            interface a = extend_BRAM_PORT(ram.a);
            interface b = extend_BRAM_PORT(ram.b);
          endinterface);
endfunction

function BRAM_PORT#(Bit#(n), t) extend_BRAM_PORT(BRAM_PORT#(Bit#(m), t) ram)
  provisos (Add#(m,k,n));
  return (interface BRAM_PORT;
            method put(write, address, datain) = ram.put(write, truncate(address), datain);
            method read() = ram.read();
          endinterface);
end function

Then, inside your module, you could write this:
Code:
Vector#(N, BRAM_DUAL_PORT#(Bit#(TExp#(N)), Bit#(64))) vec;

BRAM_DUAL_PORT#(Bit#(TExp#(1)), Bit#(64)) b1 <- mkBRAMCore2Load(valueOf(TExp#(1)), True , "1.bin", True);
vec[0] = extend_BRAM_DUAL_PORT(b1);

BRAM_DUAL_PORT#(Bit#(TExp#(2)), Bit#(64)) b2 <- mkBRAMCore2Load(valueOf(TExp#(2)), True , "2.bin", True);
vec[1] = extend_BRAM_DUAL_PORT(b2);

BRAM_DUAL_PORT#(Bit#(TExp#(3)), Bit#(64)) b3 <- mkBRAMCore2Load(valueOf(TExp#(3)), True , "3.bin", True);
vec[2] = extend_BRAM_DUAL_PORT(b3);

...

Of course, this code has to be manually written -- I haven't yet shown how to write it as a loop, that can be parameterized, but we'll get to that. What this does allow, so far, is for you to index into the vector "vec[i]" and select a BRAM to use. The interface "vec[i]" will always have an address width of N bits -- the upper address bits will be ignored for smaller BRAMs.

However, now that I think about it, there's no reason that we had to instantiate BRAMs of different types to begin with. We could just instantiate all of the BRAMs with a fixed address size -- the depth of the BRAMs will still vary:
Code:
Vector#(N, BRAM_DUAL_PORT#(Bit#(TExp#(N)), Bit#(64))) vec;

vec[0] <- mkBRAMCore2Load(valueOf(TExp#(1)), True , "1.bin", True);
vec[1] <- mkBRAMCore2Load(valueOf(TExp#(2)), True , "2.bin", True);
vec[2] <- mkBRAMCore2Load(valueOf(TExp#(3)), True , "3.bin", True);
...

And this we can easily write with a for-loop (or using the "mapM" function):
Code:
Vector#(N, BRAM_DUAL_PORT#(Bit#(TExp#(N)), Bit#(64))) vec;

  for (Integer i=1; i<=valueOf(N); i=i+1) begin
    vec[i-1] <- mkBRAMCore2Load(2**i, True, integerToString(i) + ".bin", True);
  end

Will that not work for you?
Back to top
View user's profile Send private message
Oyku



Joined: 27 Jul 2016
Posts: 7

PostPosted: Mon Sep 05, 2016 6:59 am    Post subject: Reply with quote

Actually my approach was the same as the second option that you provided.
Quote:

However, now that I think about it, there's no reason that we had to instantiate BRAMs of different types to begin with. We could just instantiate all of the BRAMs with a fixed address size -- the depth of the BRAMs will still vary:
Code:
Code:
Vector#(N, BRAM_DUAL_PORT#(Bit#(TExp#(N)), Bit#(64))) vec;

vec[0] <- mkBRAMCore2Load(valueOf(TExp#(1)), True , "1.bin", True);
vec[1] <- mkBRAMCore2Load(valueOf(TExp#(2)), True , "2.bin", True);
vec[2] <- mkBRAMCore2Load(valueOf(TExp#(3)), True , "3.bin", True);
...


However it occupies lots of space if I take the N a large number because even the TExp#(1) bram is going to take up a lot of space. And I want to use max of the space, which I can use, the brams are providing. But making them all the same, decreases the number of brams that I can put inside my design.

So I think the first option also can not be used because we are extending the bram and initiating the variables with the extended one. So I need my brams inside the vector with different sizes. That was the reason I was checking the HList as another option. Also can you tell me why are you thinking that HList wont probably help?

Thank you very much for your time and help.
Back to top
View user's profile Send private message
quark
Site Admin


Joined: 02 Nov 2007
Posts: 494

PostPosted: Mon Sep 05, 2016 4:12 pm    Post subject: Reply with quote

The BRAMs aren't the same size. The first argument to each instantiation is what gives the size, and in the example it starts small and gets large. So each BRAM is larger than the next.

All I'm suggesting is to make the width of the address the same, which should not at all affect the size of the BRAM. A BRAM of two elements with a 32-bit index will still only take up 2 elements, and only the lowest bit of the address will be used.

Am I missing something?
Back to top
View user's profile Send private message
Oyku



Joined: 27 Jul 2016
Posts: 7

PostPosted: Sun Sep 11, 2016 7:30 am    Post subject: Reply with quote

No it was a mistake of mine Smile

Thank you for your help, it is working Smile
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    bluespec.com Forum Index -> Designing with BSV's Rules, Interfaces, ... All times are GMT - 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum
bluespec.com topic RSS feed 


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP