3
\$\begingroup\$

I am beginner in Verilog. So my question may seem easy to you, but I have difficulty in understanding structure of Verilog. I have one module which works in two modes: read and write. In write mode, it must assign value on positive edge of clock. In read mode, it must give output in any time without clock. Can I use always statement in case?

 module EncodedRAM (input EncodingMode, input [2:0] EncodingIndex, input [7:0] EncodingNumber, 
input [7:0] EncodingMask, input CLK, output [7:0] EncodingResult);
initial begin
 EncodingNumbers[0]=8'b00000000;
 EncodingNumbers[1]=8'b00000000;
 EncodingNumbers[2]=8'b00000000;
 EncodingNumbers[3]=8'b00000000;
 EncodingNumbers[4]=8'b00000000;
 EncodingNumbers[5]=8'b00000000;
 EncodingNumbers[6]=8'b00000000;
 EncodingNumbers[7]=8'b00000000;
end
case(EncodingMode)
0: 
 always @(posedge CLK)
 EncodingNumbers[EncodingIndex]=EncodingNumber ^ Masks[EncodingIndex];
1: 
 EncodingResult=EncodingNumbers[EncodingIndex];
endcase
endmodule
asked Apr 21, 2013 at 12:49
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

First you need to declare your EncodingNumbers. From the way you used it, I think you want it to be a memory:

reg [7:0] EncodingNumbers [7:0];

This makes EncodingNumbers a memory file with 8 elements, and each of those elements is 8 bits wide. Because you assign to it in an always block, you need to make it a reg.

Then, if you want writes to be clocked but reads to be asynchronous, you can do this:

// write operation
always @(posedge clk) begin
 if (EncodingMode == 0) begin
 EncodingNumbers[EncodingIndex] <= EncodingNumber ^ Masks[EncodingIndex];
 end
end 
// read operation 
assign EncodingResult = EncodingMode == 1 ? EncodingNumbers[EncodingIndex] : 8'bX;

The main take-away is, each signal that you control needs to be either a wire or a reg. You need to handle reg's in procedural code (always blocks) and wires in continuous code (assign statements).

Also notice that you didn't define what EncodingResult should be when EncodingMode is 0, so I just made it undefined --- you should put something else there, like 1 or 0.

Also, be aware, especially when using memories, if you're coding for synthesis (if going to implement the code in real hardware like an FPGA), you need to be careful to code things in a way that the hardware can actually match your code. If the memories in your hardware aren't able to do an asynchronous read (which is very common in FPGAs), for example, you will either get an error in synthesis (which is not so bad) or your hardware behavior won't match what you simulated (potentially much worse if you're not aware of it).

answered Apr 21, 2013 at 14:33
\$\endgroup\$
2
  • \$\begingroup\$ assign EncodingResult = EncodingMode == 1 ? EncodingNumbers[EncodingIndex] : 8'bX; do we need to include EncodingMode? \$\endgroup\$ Commented Apr 21, 2013 at 18:11
  • \$\begingroup\$ I just tried to reflect what you had in your question. If you only want the output to appear when EncodingMode is 1, then you need to check if EncodingMode is 1. If you are okay with having the output appear regardless of what EncodingMode is,then you can get rid of it. It also might depend what your hardware is capable of, if you are coding for synthesis. \$\endgroup\$ Commented Apr 21, 2013 at 18:38
2
\$\begingroup\$

No, but you can put a case stament inside an always block:

always @(posedge CLK) begin
 case(EncodingMode)
 0 : EncodingNumbers[EncodingIndex]=EncodingNumber ^ Masks[EncodingIndex];
 1 : EncodingResult=EncodingNumbers[EncodingIndex];
 endcase
end

always blocks are executed in parallel, control structure goes inside of it.

Think of Always blocks as sections of hardware, if, case and other control mechanisms are branches of logic within that block. If you are selectively creating always blocks you are creating and destroying hardware on the fly.

If it is for improved reusability of code where we control the hardware base on constant parameters then generate statements or pre-processing techniques can help.

In your case you seem to want to trigger the block differently, write on posedge and read on any edge. Therefore I would recommend using 2 separate blocks which check the set mode.

always @(posedge clk) begin
 if (EncodingMode == 0) begin
 EncodingNumbers[EncodingIndex]=EncodingNumber ^ Masks[EncodingIndex];
 end
end
always @(clk) begin
 if (EncodingMode == 1) begin
 EncodingResult=EncodingNumbers[EncodingIndex];
 end
end
answered Apr 21, 2013 at 13:14
\$\endgroup\$
3
  • \$\begingroup\$ is there any way to implement what I meant before? any suggestion or advice could be appreciated \$\endgroup\$ Commented Apr 21, 2013 at 13:28
  • 1
    \$\begingroup\$ This answer implements what you described in your question. \$\endgroup\$ Commented Apr 21, 2013 at 13:53
  • \$\begingroup\$ OP seems to want reads to have no dependence at all on the clock. \$\endgroup\$ Commented Apr 21, 2013 at 14:39

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.