Estoy aprendiendo a codificar un UART simple usando verilog y el código funciona solo con el propósito de RX. ¿Hay algo que no puedo entender sobre la parte de TX?

0

Estoy tratando de implementar UART TX utilizando tres estados FSM. El problema es que los datos recibidos no se transmiten en serie, siempre que "rd_en" sea alto. (No hay paridad, solo TX & RX)

module SAT_UART (clk,rst,enable,rd_en,tx,rx_data);
    input        clk,rst,rd_en,enable;
    input [7:0]  rx_data;
    output       tx;
    reg   [7:0]  count;
    reg          tx;


    parameter    idle=2'd0,start=2'd1,data=2'd2,stop=2'd3;
    reg [2:0]    state;
    reg [2:0]    next_state;



    always@(state or rd_en or enable)
        begin:FSM_COMB                 //COMBINATIONAL_LOGIC
        next_state = 3'b000;
            case(state)
                idle:if(enable==1'b1 && rd_en==1'b1)
                     next_state = start;

                start:if(enable==1'b1 && rd_en==1'b1)
                     next_state = data;

                data:if(enable==1'b1 && rd_en==1'b1)
                     next_state = stop;

                stop:if(enable==1'b1 && rd_en==1'b1)
                      begin
                      next_state = idle;
                      end
            endcase
        end


    always@(posedge clk)
          begin:FSM_SEQ                  //SEQUENTIAL_LOGIC
            if(rst == 1'b1)begin
               state <= idle;
                end
            else if(count == 4'd0)
                state <= next_state;
            else if(count == 4'd1)
                state <= next_state;                                                    
            else if(count == 4'd2)
                state <= next_state;
            else if(count == 4'd3)
                state <= next_state;
            else if(count == 4'd4)
                state <= next_state;
            else if(count == 4'd5)
                state <= next_state;
            else if(count == 4'd6)
                state <= next_state;
            else if(count == 4'd7)
                state <= next_state;
            else if(count == 4'd8)
                state <= next_state;
            else
                state <= idle;                                                                      
          end   



    always@(posedge clk)
        begin:FSM_OUT                    //OUTPUT_LOGIC
                if(rst == 1'b1)
                   tx    <= 1'b1;
                   count <= 1'b0;

            case(state)
                idle:
                     tx <= 1'b1;

                start:
                      tx <= 1'b0;       //START_BIT

                data:begin
                     count <= count+1;
                     tx    <= rx_data[count - 1];
                     end
                stop:if(count == 8)
                     tx <= 1'b1;       //STOP_BIT

                     else if(enable==1'b1 && rd_en==1'b1)
                     tx <= 1'b0;
                     default: tx <= 1'b1;
            endcase

    end          

endmodule

Este es un enfoque modificado que funciona solo para transmisión, no puedo entender por qué el bucle no está terminando. (la simulación se muestra a continuación)
 module late_1(clk,rst,rd_en,enable,tx,rx_data);

    input   [7:0]rx_data;
    input   clk,rst,rd_en,enable;
    output  tx;
    reg     tx;
    reg     [3:0]state;
    reg     [3:0]next_state;
    reg     [7:0]tx_reg;
    wire    clk,rst,rd_en,enable;

      parameter IDLE   = 4'b0000,
                START  = 4'b0001,
                DATA_0 = 4'b0010,
                DATA_1 = 4'b0011,
                DATA_2 = 4'b0100,
                DATA_3 = 4'b0101,
                DATA_4 = 4'b0110,
                DATA_5 = 4'b0111,
                DATA_6 = 4'b1000,
                DATA_7 = 4'b1001,
                STOP   = 4'b1010;           

    always@(state or rd_en or enable)
        begin:TX_REGISTER
            if(state == STOP)
                tx_reg <= 1'b1;
            else
            tx_reg <= rx_data;
        end


    always@(state or rd_en or enable)
        begin:COMB_LOGIC
        next_state = 4'b0000;
                        if(rst == 1'b1)
                            begin
                            next_state = IDLE;
                            end
                else
                case(state)

                 IDLE  : 
                        begin
                        next_state = START;
                        end
                 START :
                        begin
                        next_state = DATA_0;
                        end
                 DATA_0: 
                        begin
                        next_state = DATA_1;
                        end
                 DATA_1:
                        begin
                        next_state = DATA_2;
                        end
                 DATA_2:
                        begin
                        next_state = DATA_3;
                        end
                 DATA_3:
                        begin
                        next_state = DATA_4;
                        end
                 DATA_4: 
                        begin
                        next_state = DATA_5;
                        end
                 DATA_5: 
                        begin
                        next_state = DATA_6;
                        end
                 DATA_6:
                        begin
                        next_state = DATA_7;
                        end
                 DATA_7: 
                        begin
                        next_state = STOP;
                        end
                 STOP  : 
                        begin
                        next_state = IDLE;
                        end
                 default:begin
                        next_state = IDLE;
                        end
                endcase
        end

    always@(posedge clk)
        begin:SEQ_LOGIC
        tx <= 1'b1;
            if(rst == 1'b1)
                begin
                    tx     <= 1'b1;
                    state  <= IDLE;
                    tx_reg <= 1'd0;
                end
            else
              begin
                state <= next_state;
                case(state)

                 IDLE  : if(!rst)
                        begin
                        tx    <= 1'b1;
                        end

                 START : if(rd_en == 1'b1 && enable == 1'b1)
                        begin
                        tx    <= 1'b0;
                        end

                 DATA_0: if(tx == 1'b0)
                        begin
                        tx    <= tx_reg[0];
                        end

                 DATA_1:begin
                        tx    <= tx_reg[1];
                        end

                 DATA_2:begin
                        tx    <= tx_reg[2];
                        end

                 DATA_3:begin
                        tx    <= tx_reg[3];
                        end

                 DATA_4:begin
                        tx    <= tx_reg[4];
                        end

                 DATA_5:begin
                        tx    <= tx_reg[5];
                        end

                 DATA_6:begin
                        tx    <= tx_reg[6];
                        end

                 DATA_7:begin
                        tx    <= tx_reg[7];
                        end

                 STOP  :if(tx == tx_reg[7])
                        begin
                        state <= IDLE;
                        tx    <= 1'b1;
                        end

                 default:begin
                        state <= IDLE;
                        end
                endcase
            end
        end
endmodule

ElLalíneaamarillaesSTART_BITy"tx" es la salida

    
pregunta Srinivas

0 respuestas

Lea otras preguntas en las etiquetas