verilog memory implementation

G

Greg Quintana

Guest
I am trying to implement a small memory in verilog. My code is as
follows:

module memory(addr_in, data_in, data_out, we, clk);

parameter data_width = 8;
parameter addr_width = 3;

input [addr_width - 1:0] addr_in;
input [data_width - 1:0] data_in;
input we;
input clk;


output reg [data_width - 1:0] data_out;


reg [data_width - 1:0] memory_block [0:addr_width - 1]; // declare
memory


always@(posedge clk)
begin
if (we)
memory_block[addr_in] = data_in;
else
data_out = memory_block [addr_in];

end

endmodule


there is no CE because the memory is always enabled. Unfortunately
this memory does not work. Can someone suggest a fix or a similar
working memory?

Thanks
GregQ
 
On Sep 30, 5:14 am, Greg Quintana <gre...@gmail.com> wrote:
I am trying to implement a small memory in verilog. My code is as
follows:

module memory(addr_in, data_in, data_out, we, clk);

parameter data_width = 8;
parameter addr_width = 3;

input [addr_width - 1:0] addr_in;
input [data_width - 1:0] data_in;
input we;
input clk;

output reg [data_width - 1:0] data_out;

reg [data_width - 1:0] memory_block [0:addr_width - 1];         // declare
memory

always@(posedge clk)
        begin
                if (we)
                        memory_block[addr_in] = data_in;
                else
                        data_out = memory_block [addr_in];

        end

endmodule

there is no CE because the memory is always enabled. Unfortunately
this memory does not work. Can someone suggest a fix or a similar
working memory?

Thanks
GregQ
You didn't say how exactly it doesn't work. One thing doesn't look
right is the size of the memory.

Cheers,
Jim
http://myfpgablog.blogspot.com/
 
On Sep 30, 6:52 am, Jim <jimw...@gmail.com> wrote:
On Sep 30, 5:14 am, Greg Quintana <gre...@gmail.com> wrote:



I am trying to implement a small memory in verilog. My code is as
follows:

module memory(addr_in, data_in, data_out, we, clk);

parameter data_width = 8;
parameter addr_width = 3;

input [addr_width - 1:0] addr_in;
input [data_width - 1:0] data_in;
input we;
input clk;

output reg [data_width - 1:0] data_out;

reg [data_width - 1:0] memory_block [0:addr_width - 1];         // declare
memory

always@(posedge clk)
        begin
                if (we)
                        memory_block[addr_in] = data_in;
                else
                        data_out = memory_block [addr_in];

        end

endmodule

there is no CE because the memory is always enabled. Unfortunately
this memory does not work. Can someone suggest a fix or a similar
working memory?

Thanks
GregQ

You didn't say how exactly it doesn't work. One thing doesn't look
right is the size of the memory.

Cheers,
Jimhttp://myfpgablog.blogspot.com/
Specifically you need to do a power function on the memory width
like 1 << memory_width - 1, which would be the same as 2 raised
to the memory width power, minus one. Memory needs storage for
every word, not the log base 2 of the number of words. There are
a number of other threads in this newsgroup where the same mistake
has been made.

Good luck,
Gabor
 
On Sep 30, 6:02 am, gabor <ga...@alacron.com> wrote:
On Sep 30, 6:52 am, Jim <jimw...@gmail.com> wrote:



On Sep 30, 5:14 am, Greg Quintana <gre...@gmail.com> wrote:

I am trying to implement a small memory in verilog. My code is as
follows:

module memory(addr_in, data_in, data_out, we, clk);

parameter data_width = 8;
parameter addr_width = 3;

input [addr_width - 1:0] addr_in;
input [data_width - 1:0] data_in;
input we;
input clk;

output reg [data_width - 1:0] data_out;

reg [data_width - 1:0] memory_block [0:addr_width - 1];         // declare
memory

always@(posedge clk)
        begin
                if (we)
                        memory_block[addr_in] = data_in;
                else
                        data_out = memory_block [addr_in];

        end

endmodule

there is no CE because the memory is always enabled. Unfortunately
this memory does not work. Can someone suggest a fix or a similar
working memory?

Thanks
GregQ

You didn't say how exactly it doesn't work. One thing doesn't look
right is the size of the memory.

Cheers,
Jimhttp://myfpgablog.blogspot.com/

Specifically you need to do a power function on the memory width
like 1 << memory_width - 1, which would be the same as 2 raised
to the memory width power, minus one.  Memory needs storage for
every word, not the log base 2 of the number of words.  There are
a number of other threads in this newsgroup where the same mistake
has been made.

Good luck,
Gabor
Don't you need to have
(1<<addr_width) - 1
Without the parenthesis, you get the wrong memory depth.

John Providenza
 
On Wed, 30 Sep 2009 02:14:39 -0700 (PDT), Greg Quintana
<gregkq@gmail.com> wrote:

I am trying to implement a small memory in verilog. My code is as
follows:

module memory(addr_in, data_in, data_out, we, clk);

parameter data_width = 8;
parameter addr_width = 3;

input [addr_width - 1:0] addr_in;
input [data_width - 1:0] data_in;
input we;
input clk;


output reg [data_width - 1:0] data_out;


reg [data_width - 1:0] memory_block [0:addr_width - 1]; // declare memory
As others have suggested it, the number of bits in the address doesn't
agree with the memory size declaration. If you want 3 bits of address,
you need 8 words of memory so you need to change the size of your
memory as follows:

reg [data_width - 1:0] memory_block [0:(1 << addr_width) - 1];

so that the memory range goes from 0 to 7 in your case.

--
Muzaffer Kal

DSPIA INC.
ASIC/FPGA Design Services

http://www.dspia.com
 
On Sep 30, 11:36 am, johnp <jprovide...@yahoo.com> wrote:
On Sep 30, 6:02 am, gabor <ga...@alacron.com> wrote:



On Sep 30, 6:52 am, Jim <jimw...@gmail.com> wrote:

On Sep 30, 5:14 am, Greg Quintana <gre...@gmail.com> wrote:

I am trying to implement a small memory in verilog. My code is as
follows:

module memory(addr_in, data_in, data_out, we, clk);

parameter data_width = 8;
parameter addr_width = 3;

input [addr_width - 1:0] addr_in;
input [data_width - 1:0] data_in;
input we;
input clk;

output reg [data_width - 1:0] data_out;

reg [data_width - 1:0] memory_block [0:addr_width - 1];         // declare
memory

always@(posedge clk)
        begin
                if (we)
                        memory_block[addr_in] = data_in;
                else
                        data_out = memory_block [addr_in];

        end

endmodule

there is no CE because the memory is always enabled. Unfortunately
this memory does not work. Can someone suggest a fix or a similar
working memory?

Thanks
GregQ

You didn't say how exactly it doesn't work. One thing doesn't look
right is the size of the memory.

Cheers,
Jimhttp://myfpgablog.blogspot.com/

Specifically you need to do a power function on the memory width
like 1 << memory_width - 1, which would be the same as 2 raised
to the memory width power, minus one.  Memory needs storage for
every word, not the log base 2 of the number of words.  There are
a number of other threads in this newsgroup where the same mistake
has been made.

Good luck,
Gabor

Don't you need to have
  (1<<addr_width) - 1
Without the parenthesis, you get the wrong memory depth.

John Providenza
That's the sort of thing I need to look up all the time,
or else just throw in parens for safety. You're right!

Cheers,
Gabor
 
On Sep 30, 10:40 am, gabor <ga...@alacron.com> wrote:
On Sep 30, 11:36 am, johnp <jprovide...@yahoo.com> wrote:



On Sep 30, 6:02 am, gabor <ga...@alacron.com> wrote:

On Sep 30, 6:52 am, Jim <jimw...@gmail.com> wrote:

On Sep 30, 5:14 am, Greg Quintana <gre...@gmail.com> wrote:

I am trying to implement a small memory in verilog. My code is as
follows:

module memory(addr_in, data_in, data_out, we, clk);

parameter data_width = 8;
parameter addr_width = 3;

input [addr_width - 1:0] addr_in;
input [data_width - 1:0] data_in;
input we;
input clk;

output reg [data_width - 1:0] data_out;

reg [data_width - 1:0] memory_block [0:addr_width - 1];         // declare
memory

always@(posedge clk)
        begin
                if (we)
                        memory_block[addr_in] = data_in;
                else
                        data_out = memory_block [addr_in];

        end

endmodule

there is no CE because the memory is always enabled. Unfortunately
this memory does not work. Can someone suggest a fix or a similar
working memory?

Thanks
GregQ

You didn't say how exactly it doesn't work. One thing doesn't look
right is the size of the memory.

Cheers,
Jimhttp://myfpgablog.blogspot.com/

Specifically you need to do a power function on the memory width
like 1 << memory_width - 1, which would be the same as 2 raised
to the memory width power, minus one.  Memory needs storage for
every word, not the log base 2 of the number of words.  There are
a number of other threads in this newsgroup where the same mistake
has been made.

Good luck,
Gabor

Don't you need to have
  (1<<addr_width) - 1
Without the parenthesis, you get the wrong memory depth.

John Providenza

That's the sort of thing I need to look up all the time,
or else just throw in parens for safety.  You're right!

Cheers,
Gabor
I have a cheat sheet by my desk with both C and Verilog operator
precedence.
I can never remember the order either. When in doubt, I add ().

John P.
 
On Sep 30, 4:28 pm, johnp <jprovide...@yahoo.com> wrote:
On Sep 30, 10:40 am, gabor <ga...@alacron.com> wrote:





On Sep 30, 11:36 am, johnp <jprovide...@yahoo.com> wrote:

On Sep 30, 6:02 am, gabor <ga...@alacron.com> wrote:

On Sep 30, 6:52 am, Jim <jimw...@gmail.com> wrote:

On Sep 30, 5:14 am, Greg Quintana <gre...@gmail.com> wrote:

I am trying to implement a small memory in verilog. My code is as
follows:

module memory(addr_in, data_in, data_out, we, clk);

parameter data_width = 8;
parameter addr_width = 3;

input [addr_width - 1:0] addr_in;
input [data_width - 1:0] data_in;
input we;
input clk;

output reg [data_width - 1:0] data_out;

reg [data_width - 1:0] memory_block [0:addr_width - 1];         // declare
memory

always@(posedge clk)
        begin
                if (we)
                        memory_block[addr_in] = data_in;
                else
                        data_out = memory_block [addr_in];

        end

endmodule

there is no CE because the memory is always enabled. Unfortunately
this memory does not work. Can someone suggest a fix or a similar
working memory?

Thanks
GregQ

You didn't say how exactly it doesn't work. One thing doesn't look
right is the size of the memory.

Cheers,
Jimhttp://myfpgablog.blogspot.com/

Specifically you need to do a power function on the memory width
like 1 << memory_width - 1, which would be the same as 2 raised
to the memory width power, minus one.  Memory needs storage for
every word, not the log base 2 of the number of words.  There are
a number of other threads in this newsgroup where the same mistake
has been made.

Good luck,
Gabor

Don't you need to have
  (1<<addr_width) - 1
Without the parenthesis, you get the wrong memory depth.

John Providenza

That's the sort of thing I need to look up all the time,
or else just throw in parens for safety.  You're right!

Cheers,
Gabor

I have a cheat sheet by my desk with both C and Verilog operator
precedence.
I can never remember the order either.  When in doubt, I add ().

John P.
I had the similar code for the memory module. The addresssize and
bitsize are really not a major issue, as you can have less memory and
large address bus..

The issue with my working was when i made the test bench for this, I
need to take care that I have to keep a small delay between the
address and data while writing, otherwise it is not able to save the
value in data..

Also, I am not sure that above code works well but it is better to
keep begin and end after if conditions
always@(posedge clk)
begin
if (we) begin
memory_block[addr_in] = data_in;
end
else begin
data_out = memory_block [addr_in];
end
end
endmodule
 
On Oct 4, 3:02 pm, Jay <jaypatel...@gmail.com> wrote:
On Sep 30, 4:28 pm, johnp <jprovide...@yahoo.com> wrote:



On Sep 30, 10:40 am, gabor <ga...@alacron.com> wrote:

On Sep 30, 11:36 am, johnp <jprovide...@yahoo.com> wrote:

On Sep 30, 6:02 am, gabor <ga...@alacron.com> wrote:

On Sep 30, 6:52 am, Jim <jimw...@gmail.com> wrote:

On Sep 30, 5:14 am, Greg Quintana <gre...@gmail.com> wrote:

I am trying to implement a small memory in verilog. My code is as
follows:

module memory(addr_in, data_in, data_out, we, clk);

parameter data_width = 8;
parameter addr_width = 3;

input [addr_width - 1:0] addr_in;
input [data_width - 1:0] data_in;
input we;
input clk;

output reg [data_width - 1:0] data_out;

reg [data_width - 1:0] memory_block [0:addr_width - 1];         // declare
memory

always@(posedge clk)
        begin
                if (we)
                        memory_block[addr_in] = data_in;
                else
                        data_out = memory_block [addr_in];

        end

endmodule

there is no CE because the memory is always enabled. Unfortunately
this memory does not work. Can someone suggest a fix or a similar
working memory?

Thanks
GregQ

You didn't say how exactly it doesn't work. One thing doesn't look
right is the size of the memory.

Cheers,
Jimhttp://myfpgablog.blogspot.com/

Specifically you need to do a power function on the memory width
like 1 << memory_width - 1, which would be the same as 2 raised
to the memory width power, minus one.  Memory needs storage for
every word, not the log base 2 of the number of words.  There are
a number of other threads in this newsgroup where the same mistake
has been made.

Good luck,
Gabor

Don't you need to have
  (1<<addr_width) - 1
Without the parenthesis, you get the wrong memory depth.

John Providenza

That's the sort of thing I need to look up all the time,
or else just throw in parens for safety.  You're right!

Cheers,
Gabor

I have a cheat sheet by my desk with both C and Verilog operator
precedence.
I can never remember the order either.  When in doubt, I add ().

John P.

I had the similar code for the memory module. The addresssize and
bitsize are really not a major issue, as you can have less memory and
large address bus..

The issue with my working was when i made the test bench for this, I
need to take care that I have to keep a small delay between the
address and data while writing, otherwise it is not able to save the
value in data..

Also, I am not sure that above code works well but it is better to
keep begin and end after if conditions
always@(posedge clk)
        begin
                if (we) begin
                        memory_block[addr_in] = data_in;
                        end
                else begin
                        data_out = memory_block [addr_in];
                        end
        end
endmodule
The reason you needed the delay is that the assignments
should be non-blocking like:

always@(posedge clk)
begin
if (we) begin
memory_block[addr_in] <= data_in;
end
else begin
data_out <= memory_block [addr_in];
end
end

This ensures that the outputs don't change during simulation
until all other non-blocking assignments on that clock edge
were also completed.

Regards,
Gabor
 

Welcome to EDABoard.com

Sponsor

Back
Top