-3

I am working on RTL coding of rs232 protocol in verilog I wrote the Tx/Rx codes in two different files.

I wanted to know whether these lines[as shown below] are legal in verilog. By legal I mean do they produce synthesizable output? I have initialized count_tx to 12. Basically, I want serial output through dataframe_tx. I know we can do this through the logical shift left, but I used this method.

In the waveform analyzer, I could see dataframe_tx always zero. That is where I started doubting these lines.

.
.
.
S_SENDING:begin
          dataframe_tx = temp_tx[12-count_tx];
          count_tx = count_tx - 1;

          if(count_tx)
          next_tx = S_SENDING;
          else begin
          next_tx = S_DONE;
          done_tx = 1'b1;
          end

          end
.
.
.
.

1 Answers1

0

To answer your question: The code fragment you posted consists of legal SystemVerilog constructs.

If one adds proper declarations of the objects you are referencing, adds the obvious missing case statement and wraps the whole in an always_ff block it will compile and thus generate synthesizable code. You asked about syntax and not semantics. Will it work? Hard to tell from the fragment. But the intent of your if statement seems to be checking if the vector is non-zero. Consider if( |count_tx ) instead. I added few lines to your code to make if syntactically OK. I also tool the liberty to change the assignments to non-blocking as these would be otherwise inferred by the tool. Still remains as a fragment but I hope it may help.

module Sandbox(
    input logic clk
    // inputs and outputs ...
);
    logic           dataframe_tx;
    logic   [12:0]  temp_tx;
    logic               done_tx;
    logic   [3:0]       count_tx;

    enum    {S_SENDING, S_DONE} next_tx;

    always_ff @(posedge clk)        // as an example
    begin
        case (next_tx)
            // something ...
            S_SENDING: begin
                dataframe_tx    <= temp_tx[12-count_tx];
                count_tx        <= count_tx - 1;

                if( |count_tx )
                    next_tx <= S_SENDING;
                else begin
                    next_tx <= S_DONE;
                    done_tx <= 1'b1;
                end
            end
            // something ....
            S_DONE: /* your code */;
        endcase
    end
endmodule

Good luck!

Martin Vana
  • 151
  • 1
  • 8
  • Thank you for your reply...could you please clarify what does ' |count_tx ' means? – SWETHA CHILVERI Sep 12 '21 at 07:47
  • The count_tx is a vector and in this example it is 4-bits wide. The `| count_tx[3:0]` is an 'unary' `or` operator. Unary means that it only takes a right hand argument. It takes the entire width of the vector (unless a slice is specified) and performs **or** of all of the individual bits. The result is 0 if all of the bits are zero. These operators are covered in Section 11.4.9 of SystemVerilog IEEE1800-2012. – Martin Vana Sep 12 '21 at 18:44
  • Thank you for explaining, but in your example, you have not initialized count_tx anywhere. – SWETHA CHILVERI Sep 13 '21 at 07:32
  • @SWETHACHILVERI You are correct: I added to your fragment only as much as to make it syntactically complete. It isn't even close to a *functional* code. No initialization is done (next_tx is another example), no reset net, inputs or outputs. The state machine is missing handling of the start and stop bit intervals of the UART to begin with. UART RTL design is a well charted territory. Google search will give you more complete code samples than you may want. You may read a few of them and be ready to write it the way you want. – Martin Vana Sep 13 '21 at 15:35