how to implement clear on read register?

Guest
Hi guys,

Lets say my code has an interrupt status register, how can I implement a clear on read algorithm? Please see my example code below. I can't simply write intr_status<=0; in the second always block, because one register can't be written by two always block.

example code:

always@(posedge clk)
begin
if(user_input==1) //user press a button once a while
intr_status<=1; //intr_status register becomes high
else
intr_status<=intr_status;
end

always@(read_request)
begin
if(read_request==1) //a processor wants to read the interrupt status register
status_output<=intr_status; //status_output is an output port to the processor

//how can I reset the intr_status register?

end
 
I'm not trying to be rude, but have you ever written any Verilog (or VHDL or other HDL) before? See comments below.

On Monday, March 18, 2013 2:47:09 PM UTC-7, gordon...@gmail.com wrote:
example code:

always@(posedge clk)
begin
if(user_input==1) //user press a button once a while
intr_status<=1; //intr_status register becomes high
These 2 lines do nothing but take up space and distract from what the code is really doing. I've seen this in some engineers' code and it drives me crazy. It does nothing - other than show me the person doesn't really understand how Verilog works.
else
intr_status<=intr_status;

end

This is a latch. I don't think that's what you wanted. It's somewhat ironic that you have the extra, meaningless lines in the previous always block to assign intro_status to itself while in this block, you're missing the essential and required lines (assuming you're working with 99.9% of FPGAs or ASICs that are d-flip-flop based) to say what status_output is when read_request is not equal to '1'.

always@(read_request)
begin
if(read_request==1) //a processor wants to read the interrupt status register
status_output<=intr_status; //status_output is an output port to the processor
end
Also, don't you have a reset signal? What are intr_status and status output at time zero?

Here's one solution, but this is day-one kind of stuff, so you really need to get a Verilog book or study online code examples.

always @ (posedge clk or posedge rst) begin
if (rst) begin
intr_status <= 0;
status_output <=0;
end
else begin
if (user_input) begin
intr_status <= 1;
end
else if (read_request) begin
intr_status <= 0;
status_output <= intr_status;
end
end
end
 
On Tuesday, March 19, 2013 3:17:09 AM UTC+5:30, gordon...@gmail.com wrote:
Hi guys,



Lets say my code has an interrupt status register, how can I implement a clear on read algorithm? Please see my example code below. I can't simply write intr_status<=0; in the second always block, because one register can't be written by two always block.



example code:



always@(posedge clk)

begin

if(user_input==1) //user press a button once a while

intr_status<=1; //intr_status register becomes high

else

intr_status<=intr_status;

end



always@(read_request)

begin

if(read_request==1) //a processor wants to read the interrupt status register

status_output<=intr_status; //status_output is an output port to the processor



//how can I reset the intr_status register?



end
I've been working on my final year project which is based on hardware implementation of Image Encryption and I am finding a problem dealing with the matrix of the image. I have tried few ways, but the problem still persists.

The problem is:
I have an image (256 level -gray scale) stored in a 1-D Array (as 2-D array is not supported in I-VERILOG). I need to take some particular pixels in a particular order, for example:

@(posedge clk)
begin
M1<=Image[24*k+7:24*k];
M2<=Image[24*k+15:24*k+8];
M3<=Image[24*k+23:24*k+16];
end

where k and M1,M2,M3 are register data-type,and k is increasing at every clock pulse.(counter)

But on compiling, one of the errors is as shown :
Part select expressions must be constant.
This msb expression violates the rule: (('sd24)*(k))+('sd23)

The other error messages are similar. I even tried for loop for the same. But the same error persists.
What can be the other way to select a particular range of elements of an array and give it to a register? It will be really grateful if you can help me about the same.
 
On Saturday, March 30, 2013 11:55:10 AM UTC-4, exam1...@gmail.com wrote:
begin
M1<=Image[24*k+7:24*k];
M2<=Image[24*k+15:24*k+8];
M3<=Image[24*k+23:24*k+16];
end

But on compiling, one of the errors is as shown :
Part select expressions must be constant.
This msb expression violates the rule: (('sd24)*(k))+('sd23)
Yeah - Verilog doesn't allow the width of a slice to be variable. Even if your MSB and LSB equations are such that MSB-LSB is constant, it violates the rules. The 2001 Verilog spec added a way to deal with this. You can write xxx[LSB +: WIDTH] or xxx[MSB -: WIDTH].
So
M1<=Image[24*k+7:24*k];
becomes
M1<=Image[24*k +: 8];

I don't know what I_Verilog is but it would be pretty bad if it doesn't support this!

David
 
On 4/3/2013 11:36 AM, unfrostedpoptart wrote:
I don't know what I_Verilog is but it would be pretty bad if it doesn't support this!
I would assume I_Verilog is Icarus Verilog and if so the current
released version does support indexed part selects. The development
version has preliminary support for packed arrays and multidimensional
arrays.

Cary
 

Welcome to EDABoard.com

Sponsor

Back
Top