How to read the values of memory into a register in verilog?

Status
Not open for further replies.

keerthna

Member level 1
Joined
Sep 16, 2014
Messages
33
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
251
I am trying to read the values of memory after 5 cycles into an output register. How do I do that?
For example if i have a code which looks like this,


Code dot - [expand]
1
2
3
4
5
6
7
8
reg[31:0] mem[0:5];
       if(high==1)
       begin
       newcount1<=count2;
       mem[i]<=newcount1;
       i<=i+1;
       count2=0;
       end


after the 5 cycles of operation whatever mem values i get, how do i read them in another output register? and can i perform averaging operation on those 5 cycles? and get a nominal value?
 
Last edited by a moderator:

Looks like some part of the code is missing. There is no looping statement.
If finally what you want to do is averaging, I don't see a point in having a memory. You can define a big enough register and keep accumulating the sum of the individual words in that. Finally divide it by 5.
 

I will get a new count value at the end of each cycle i.e., for different values of i the count changes. So I used a memory to save all those values upto 5 clock cycles. At the end of the fifth clock cycle I want to take all those values and average and find a nominal value. How am I supposed to do it? I am a bit confused with the same. Could anyone please help me out with an example code. Thanks in advance
 

If I understand your requirement right, you don't need to bother about individual count value and only the average matters. You can have a loop which finds out the sum of the count values i.e. sum = sum + count; After 5 counts are accumulated in sum, you can find the average..
 

But if I try like that no values are getting accumulated in sum. And it is always in the unknown state.
 

But if I try like that no values are getting accumulated in sum. And it is always in the unknown state.

Use an initial block to make sure your registers are initialized to zero. Otherwise you get those U unknowns during simulation.
 

I initialized them to zero. But still the same issue. Can you please provide a sample loop conditions example on how I should be doing it? Thanks in advance
 

I initialized them to zero.

Where? Because you don't do so in the code you show. Please post your code + testbench that you are currently using.

Also, please use [syntax=verilog] tags for your code. Helps in readability. And indentation (spaces, no tabs) also helps.
 

Here is the complete verilog code.


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
module jitterclk(signalin,clk,rst,edgedet,newcount1);
input clk;
output [31:0]newcount1;
input signalin;
input rst;
integer i;
reg [31:0]count1;
reg [31:0]count2;
output edgedet;
reg edgedet;
 
 
reg signald;
wire signalin;
reg tempedge;
reg [31:0]newcount1;
reg [31:0] mem[0:9];
 
reg [64:0]sum;
reg [32:0]avg;
reg high;
 
initial
begin
count1=0;
count2=0;
i=0;
 
 
end
always@(posedge clk)
begin
if(rst==1)
begin
signald<=1'b0;
count1=0;
count2=0;
tempedge<=1'b0; 
end
else
begin
count1=count1+1;
high=0;
signald<=signalin;
tempedge<=signalin&(~signald); 
end
if(count1==20'b11110100001001000000)
begin
count1=0;
high=1;
 
end
if(tempedge==1)
begin
count2=count2+1;
edgedet<=tempedge;
end
if(high==1)
begin
 
newcount1<=count2;
mem[i]<=newcount1;
//i<=i+1;
count2=0;
 
for(i=0;i<5;i=i+1)
begin
sum=sum+newcount1[i];
end
end
endmodule

I am so sorry, I couldn't understand how to add the verilog tags to the code.
 
Last edited by a moderator:

I am so sorry, I couldn't understand how to add the verilog tags to the code.

Please review this tutorial (second post in announcements)

- - - Updated - - -

mrflibble told you to use an initial block for sum etc. But there is none in your code.
 

i added that for loop and also initialised them. can you please suggest a solution for my problem? how to read those count values and average them?
 

Question: do you work on your code like that, without indentation? Or is the indentation getting lost somewhere from your editor to this forum? Because I could spend time to make it readable, but that seems a bit counterproductive...

As for the initial block. You have an initial block, and you handle the initialization of just 2 registers. How many registers do you have in your design? Why do you think you don't need to initialize the rest of them? Anyways, you have done init for two registers so you know how to do it. Now you have to add code that handles those other reg's as well.

- - - Updated - - -

Also, please post your testbench. Right now I have no idea how you test your jitterclk module and how you come to the conclusion that it doesn't work.
 

Since I wanted to test the auto-indent of a new version of SVEditor I pasted your zero-formatting module in there. After reformatting I noticed there's an end statement missing, so I doubt the code you provided is even compiling.

And too bad SVE doesn't support automatically refactoring verilog-1995 port style to verilog-2001 style. Would have been nice.

Anyways, I highly recommend you stop mixing blocking & non-blocking assignments inside the same always block. What do I mean? I mean this:


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
always @(posedge clk)
    begin
        if (rst==1)
        begin
            signald<=1'b0; // non-blocking
            count1=0; // blocking
            count2=0; // blocking
            tempedge<=1'b0; // non-blocking
        end else begin
 
// etc



Doing that is a recipe for Things That Do Not Work. Kick out the blocking ones. Only use non-blocking there. If you don't believe me, just ask someone else.

Also, why are you even mixing those two? I personally cannot think of a good reason why you'd want that in that particular piece of code.

block/non-block, see for example: https://www.asic-world.com/tidbits/blocking.html
 

I wonder if keerthna knows they are counting 1,000,001 times...


Code Verilog - [expand]
1
2
if(count1==20'b11110100001001000000) begin
  count1=0;



You do know that it's easier to read 20'd1_000_000? (I guess you must be better at reading long binary strings better than I am.)
 

Heh. I was wondering about that loooong 20-bit literal as well. But then I was wondering about a lot of other things as well reading that code. It's a bit verbose for what it is supposed to be doing. But oh well...
 

Yes I made the necessary changes to the code and it is working fine. Thanks a lot for all your help
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…