I don't know if this belongs here or stackoverflow. I assume here as although verilog looks like software it's actually describing hardware connections?
I have a Spartan-3AN evaluation board and I'm trying to implement a simple rs232 port interface on it which I can't get to work. I'm an experienced software developer but new to verilog and digital design. I want to move up from flashing a single LED to the next step.
I've tried to implement it like this –
1) Generate a clock pulse "serclock" at the baud rate, so at the start of each bit.
2) Implement a state machine that once it's told to start steps through the states at the correct speed.
3) Implement a lookup to output the correct data bit depending on the state that 2) is in.
If there is a better way I'd appreciate any help. However I would expect this to work but I get nothing at all. Can anyone spot anything stupid that I've done? I'd appreciate any advice.
// 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
Best Answer
I don't speak Verilog, but I noticed that your stopbit is zero, which should be 1. Are you reading the port on a scope, or are you reading on a UART? In the latter case you may not have a character received if it doesn't see the stopbit.