• 0
leventofset

Using memory values in Verilog / VHDL

Question

Hello everyone,

 

I'm using Zybo and i want to create a custom ip. The ip will have two inputs (as registers) that has 32 bits: Let's call them a[31:0] and  b[31:0]. And i want to get memory value at a and add b. The calculated value is a new memory address and i want to read value at that address and write it into the third register of ip. But i haven't find a tutorial like this. If there's any, i would like to know it.

 

Thanks for your time.

Share this post


Link to post
Share on other sites

6 answers to this question

Recommended Posts

  • 0

Hi,

you can write RAM using up to two ports in plain Verilog like this:

module myMem(clkA, in_addrA, out_dataA,
		     clkB, in_weB, in_addrB, in_dataB, out_dataB);
   localparam NBITADDR = 11;
   localparam NBITDATA = 8;
   
   input clkA;
   input [NBITADDR-1:0] in_addrA;   
   output reg [NBITDATA-1:0] out_dataA;

   input 		     clkB;
   input 		     in_weB;
   input [NBITADDR-1:0]      in_addrB;
   input [NBITDATA-1:0]      in_dataB;
   output reg [NBITDATA-1:0] out_dataB;

   reg [NBITDATA-1:0] 	     mem [0:2**NBITADDR-1];   

   integer 		     ix;
   initial begin
      	mem[0000] = 8'h00;
		...
		mem[2047] = 8'h2e;
   end   
   
   always @(posedge clkA) begin
      out_dataA <= mem[in_addrA];	 
   end
   
   always @(posedge clkB) begin
      if (in_weB) begin
	 mem[in_addrB] <= in_dataB;
	 out_dataB <= in_dataB;	 
      end else begin
	 out_dataB <= mem[in_addrB];	 
      end
   end
endmodule

It will be recognized as BRAM (inference).

The functionality you asked for can be done using both ports (one operation per clock cycle) or a state machine and one port (one operation every two clock cycles).

 

Share this post


Link to post
Share on other sites
  • 0

@xc6lx45 Thank you for your reply. But i want to do is a little bit different. Assume that custom ip's registers maps to 0x43C0_0000 to 0x43C0_FFFF and our DDR is map to 0x0000_0000 to 0x1FFF_FFFF and value at 0x0000_ABCD is 0x0000_0100 and value at 0x0000_0100 is 0x0000_0005.

I want to give 0x43C0_0000 0x0000_000D and give 0x43C0_0004 0x0000_ABC0, ip will calculate 0x0000_000D + 0x0000_ABC0 and the result, 0x0000_ABCD, will be an address. ddr[0x0000_ABCD] = 0x0000_0100 and then 0x43C0_0008 will be 0x0000_0005.

Thank you for your time.

Share this post


Link to post
Share on other sites
  • 0

Just thinking aloud... I wonder whether it might actually be faster do do this on a CPU, compared to RTL, because some of those slow DRAM reads may be handled by the cache.
 

Share this post


Link to post
Share on other sites
  • 0

@leventofset,

Building an MMU?  Well, if you are interested, you can find an example block RAM based MMU within the ZipCPU project here.  I say block RAM based, since the TLB is maintained within a software defined block RAM table internal to the component.  You can even find a formal proof of the code starting with the `ifdef FORMAL towards the bottom half.

Dan

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now