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
\$\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).

\$\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\$
    – The Photon
    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
\$\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\$
    – pjc50
    Commented Apr 21, 2013 at 13:53
  • \$\begingroup\$ OP seems to want reads to have no dependence at all on the clock. \$\endgroup\$
    – The Photon
    Commented Apr 21, 2013 at 14:39

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.