Implementar puerto serie en fpga (verilog)

6

No sé si esto pertenece aquí o stackoverflow. Supongo que aquí, aunque verilog parece software, ¿en realidad describe conexiones de hardware?

Tengo una placa de evaluación Spartan-3AN y estoy tratando de implementar una interfaz de puerto rs232 simple en la que no puedo trabajar. Soy un desarrollador de software experimentado, pero nuevo en diseño digital y verilog. Quiero pasar de destellar un solo LED al siguiente paso.

He intentado implementarlo así: 1) Genere un pulso de reloj "bloqueo" a la velocidad en baudios, al inicio de cada bit. 2) Implemente una máquina de estados que, una vez que se le indique, comience los pasos a través de los estados a la velocidad correcta. 3) Implemente una búsqueda para generar el bit de datos correcto en función del estado en que se encuentre 2).

Si hay una mejor manera, agradecería cualquier ayuda. Sin embargo, espero que esto funcione, pero no consigo nada en absoluto. ¿Alguien puede ver algo estúpido que haya hecho? Apreciaría cualquier consejo.

 
// Serial port demo program
// 
// Assumptions: 50Mhz clock rate

module SerDemo(input clk, output ser);


// Start signal tells it to start sending bits
reg start;

//The bits of data to send
reg [7:0] data;

/////////////////////////////////////////////////////////////////////////////
// Serial port clock generator
// Generate a 9600 baud clock signal for the serial port by dividing the
// 50Mhz clock by 5208

reg [14:0] clockdiv;

// Count from 0..5207 then reset back to zero
always @(posedge clk) 
begin
    if (clockdiv == 5207) 
        clockdiv <= 0;
    else
        clockdiv <= clockdiv + 1;
end

// The serclock is a short pulse each time we are reset
wire serclock = (clockdiv == 0);

/////////////////////////////////////////////////////////////////////////////
// Serial port state machine
// Only start the state machine when "start" is set. Only advance to the
// next state when serclock is set.

reg [3:0] state;

always @(posedge clk)
begin
   case (state)
        4'b0000: if (start) state <= 4'b0001;
        4'b0001: if (serclock) state <= 4'b0010;    // Start bit
        4'b0010: if (serclock) state <= 4'b0011;    // Bit 0
        4'b0011: if (serclock) state <= 4'b0100;    // Bit 1
        4'b0100: if (serclock) state <= 4'b0101;    // Bit 2
        4'b0101: if (serclock) state <= 4'b0110;    // Bit 3
        4'b0110: if (serclock) state <= 4'b0111;    // Bit 4
        4'b0111: if (serclock) state <= 4'b1000;    // Bit 5
        4'b1000: if (serclock) state <= 4'b1001;    // Bit 6
         4'b1001: if (serclock) state <= 4'b1010;   // Bit 7
        4'b1010: if (serclock) state <= 4'b0000;    // Stop bit
        default: state <= 4'b0000;                  // Undefined, skip to stop
    endcase
end


///////////////////////////////////////////////////////////////////////////////
// Serial port data
// Ensure that the serial port has the correct data on it in each state

reg outbit;

always @(posedge clk)
begin
    case (state)
         4'b0000: outbit <= 1;              // idle
         4'b0001: outbit <= 0;              // Start bit
         4'b0010: outbit <= data[0];        // Bit 0
         4'b0011: outbit <= data[1];        // Bit 1
         4'b0100: outbit <= data[2];        // Bit 2
         4'b0101: outbit <= data[3];        // Bit 3
         4'b0110: outbit <= data[4];        // Bit 4
         4'b0111: outbit <= data[5];        // Bit 5
         4'b1000: outbit <= data[6];        // Bit 6
         4'b1001: outbit <= data[7];        // Bit 7
         4'b1010: outbit <= 0;          // Stop bit
         default: outbit <= 1;          // Bad state output idle
    endcase
end

// Output register to pin
assign ser = outbit;

///////////////////////////////////////////////////////////////////////////////
// Test by outputting a letter 'd'

always @(posedge clk)
begin
    data = 100;
     start = 1;
end

endmodule
    
pregunta John Burton

2 respuestas

13

No hablo Verilog, pero noté que tu stopbit es cero, que debería ser 1. ¿Estás leyendo el puerto en un visor, o estás leyendo en un UART? En este último caso, es posible que no se reciba un carácter si no se ve el stopbit.

    
respondido por el stevenvh
6

No has restablecido el sistema a un estado conocido.

Dicho esto, ¿asumo que estás haciendo esto para aprender Verilog? De lo contrario, hay muchos núcleos disponibles de forma gratuita que puede encontrar en Internet que lo hacen. :)

Como ejemplo:

// Count from 0..5207 then reset back to zero
always @(posedge clk) 
begin
  if (rst) begin
    clockdiv <= 0;
  end else begin
    if (clockdiv == 5207) 
        clockdiv <= 0;
    else
        clockdiv <= clockdiv + 1;
  end
end
    
respondido por el sybreon

Lea otras preguntas en las etiquetas