-2

I am working on rs232 for over one week. My program takes a 13bit dataframe[from testbench] and serially transmits it. Now, I am testing the TX side. I think this[as commented below -here1, here2] is where the problem is.

module rs232_tx(dtr_tx,rts_tx,clk_tx,dsr_tx,cts_tx,data_tx,dataframe_tx,r_tx);
input clk_tx;
input dsr_tx;                // data set ready
input cts_tx;                // clear to send
//input rx;                  // not using for now
input r_tx;                  // asynchronous active low reset signal, given by testbench
input [8:0]data_tx;          // send this data serially out, given by testbench
output reg dtr_tx;           // data terminal ready
output reg rts_tx;           // ready to send
output reg dataframe_tx;     // serially out data

reg [1:0]state_tx;
reg [1:0]next_tx;
reg [12:0]temp_tx;
reg done_tx;

reg [3:0]count_tx = 4'b1100; // counting the shift

parameter S_IDLE=2'b00, S_START=2'b01, S_SENDING=2'b10, S_DONE=2'b11, frame_size=4'b1100;

always@(posedge clk_tx, negedge r_tx)
begin
  if(~r_tx)
    state_tx <= S_IDLE;
  else
    state_tx <= next_tx;
end

always@(*)
begin
  case(state_tx)
    S_IDLE:
    begin
      done_tx = 1'b0;
      dtr_tx = 1'b1;
      temp_tx = 12'b0;
      next_tx = (dsr_tx) ? S_START : S_IDLE; // dsr gives receiver information
    end
    S_START:
    begin                           // form data-frame
      rts_tx = 1'b1;
      .    
      .
      .
      //assigning data to temp_tx bit by bit. And few more bits.
      .
      .
      next_tx = (cts_tx) ? S_SENDING : S_START;
    end
    S_SENDING:
    begin
      //dataframe_tx = temp_tx[frame_size - count_tx];
      dataframe_tx = temp_tx[frame_size];
      temp_tx = temp_tx<<1;
      count_tx = count_tx - 1;
      if(|count_tx)
        next_tx = S_SENDING;
      else
      begin
        next_tx = S_DONE;
        done_tx = 1'b1;
      end
    end
    S_DONE:
    begin
      done_tx = 1'b0;
    end
    default:
      next_tx = S_IDLE;
  endcase
end

endmodule

In the testbench:

module rs232_tb;
.
.
rs232_tx dut(.clk(c_Clock),.rst(c_r),.dataframe_tx(t_data),done_tx,temp_tx);
.
.
.
initial
  begin
    $dumpfile("rs232.vcd");
    $dumpvars(0,rs232_tb);
    #7 c_r = 1'b1;
    // checking Tx
    #7 t_dsr = 1'b1;          // Data Set Ready signal for rs232
    #7 t_data = 9'b101010101; // data to be transmitted on receiving CTS from RX.
    #7 t_cts = 1'b1;         // Clear To Send signal from RX
    #50 $finish;
  end
.
.
.

The problem is, I am always getting temp_tx[12] value on dataframe_tx, and then temp_tx is logically rotated left by one. Next time, this shift is not happening. I observed the reg [3:0]state it remains on S_SENDING state but there is no logical shift performed on the next clock edge. Also, as a side note, I observed that count_tx decrements only once and later just remains constant to value 11.

I am in the learning phase. I cannot find any solution on internet or anyone sharing this kind of problem. Please help me...

2 Answers2

-1

In sequential process you use next, while in combo U assign to next_tx ?

Also it looks like combo-loop, the counters you use there should be moved to sequential process - you should not use the same signal in LHS and RHS when it’s combinational process.

Search for “combinatorial loop” in google for more details.

PrzemekS
  • 127
  • 6
  • Thank you for replying @PrzemekS. I was trying to write the minimum code so I made that mistake whereas my actual code was not intended for that. Could you please suggest now? – SWETHA CHILVERI Sep 26 '21 at 15:27
-1

You are performing logical operations on temp_tx which is a primary input this is not correct. Store this input to a register and perform operations on it.

always@(posedge clk or negedge rst_n)
begin
 if(!rst_n)
  temp_tx_reg <= 'd0;
 else if (state == S_START) // Register input when initializing
  temp_tx_reg <= temp_tx;
end

Also please use a proper always block for counters.

always@(posedge clk or negedge rst_n)
begin
 if(!rst_n)
  count_tx <= 4'b0000;
 else if(state == S_START)
  count_tx <= 4'b1100;
 else if(state == S_SENDING && |count_tx)
  count_tx <= count_tx - 1'd1;
end

I would suggest you follow steps via FSM.

  1. State1 -- Initialize registers and counters.
  2. State2 -- Perform the serialization.
  3. State3 -- Set the output flags.
Pradyuman Bissa
  • 171
  • 1
  • 9
  • Thank you for replying. I have now edited my code again. Actually, while trying to write in minimal reducble format I missed out on few important parameters of the code. My bad! Could you give me you suggestions now? – SWETHA CHILVERI Sep 26 '21 at 15:26