Forum: FPGA, VHDL & Co. Implement serial port on FPGA (verilog)


von Ari123 L. (Firma: Kynix Semiconductor HongKong L) (yumi1)


Lesenswert?

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(http://www.kynix.com/Parts/3231833/RS232.html) 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.
Code:
1
// Serial port demo program
2
// 
3
// Assumptions: 50Mhz clock rate
4
5
module SerDemo(input clk, output ser);
6
7
8
// Start signal tells it to start sending bits
9
reg start;
10
11
//The bits of data to send
12
reg [7:0] data;
13
14
/////////////////////////////////////////////////////////////////////////////
15
// Serial port clock generator
16
// Generate a 9600 baud clock signal for the serial port by dividing the
17
// 50Mhz clock by 5208
18
19
reg [14:0] clockdiv;
20
21
// Count from 0..5207 then reset back to zero
22
always @(posedge clk) 
23
begin
24
    if (clockdiv == 5207) 
25
        clockdiv <= 0;
26
    else
27
        clockdiv <= clockdiv + 1;
28
end
29
30
// The serclock is a short pulse each time we are reset
31
wire serclock = (clockdiv == 0);
32
33
/////////////////////////////////////////////////////////////////////////////
34
// Serial port state machine
35
// Only start the state machine when "start" is set. Only advance to the
36
// next state when serclock is set.
37
38
reg [3:0] state;
39
40
always @(posedge clk)
41
begin
42
   case (state)
43
        4'b0000: if (start) state <= 4'b0001;
44
        4'b0001: if (serclock) state <= 4'b0010;    // Start bit
45
        4'b0010: if (serclock) state <= 4'b0011;    // Bit 0
46
        4'b0011: if (serclock) state <= 4'b0100;    // Bit 1
47
        4'b0100: if (serclock) state <= 4'b0101;    // Bit 2
48
        4'b0101: if (serclock) state <= 4'b0110;    // Bit 3
49
        4'b0110: if (serclock) state <= 4'b0111;    // Bit 4
50
        4'b0111: if (serclock) state <= 4'b1000;    // Bit 5
51
        4'b1000: if (serclock) state <= 4'b1001;    // Bit 6
52
         4'b1001: if (serclock) state <= 4'b1010;   // Bit 7
53
        4'b1010: if (serclock) state <= 4'b0000;    // Stop bit
54
        default: state <= 4'b0000;                  // Undefined, skip to stop
55
    endcase
56
end
57
58
59
///////////////////////////////////////////////////////////////////////////////
60
// Serial port data
61
// Ensure that the serial port has the correct data on it in each state
62
63
reg outbit;
64
65
always @(posedge clk)
66
begin
67
    case (state)
68
         4'b0000: outbit <= 1;              // idle
69
         4'b0001: outbit <= 0;              // Start bit
70
         4'b0010: outbit <= data[0];        // Bit 0
71
         4'b0011: outbit <= data[1];        // Bit 1
72
         4'b0100: outbit <= data[2];        // Bit 2
73
         4'b0101: outbit <= data[3];        // Bit 3
74
         4'b0110: outbit <= data[4];        // Bit 4
75
         4'b0111: outbit <= data[5];        // Bit 5
76
         4'b1000: outbit <= data[6];        // Bit 6
77
         4'b1001: outbit <= data[7];        // Bit 7
78
         4'b1010: outbit <= 0;          // Stop bit
79
         default: outbit <= 1;          // Bad state output idle
80
    endcase
81
end
82
83
// Output register to pin
84
assign ser = outbit;
85
86
///////////////////////////////////////////////////////////////////////////////
87
// Test by outputting a letter 'd'
88
89
always @(posedge clk)
90
begin
91
    data = 100;
92
     start = 1;
93
end
94
95
endmodule

: Bearbeitet durch Moderator
von Klakx (Gast)


Lesenswert?

How do u define nothing? Try to simulate at first and show us ur 
Testbench.

von Gustl B. (-gb-)


Lesenswert?

For the state you could use a simple counter, but why so many states? 
You are only sending Data, so you could at start initialize a 10bit 
Register(9 downto 0) with
stopbit, 8bit_data, startbit
and then shift the Register from left to right. So with every clock 
(Baudrate) you shift the Register:
Register = '1' & Register(9 downto 1)
'1' because UART idle is logical '1'. With this you don't need the 
Stopbit.

The Output is register(0)

I don't know Verilog, sorry.

von Sigi (Gast)


Lesenswert?

Serial port state machine/Serial port data:
As already mentioned, 10 bit (?) shift register and
corresponding counter, this reduce this parts of
your code to some few lines.

Serial port clock generator:
<clockdiv> is count up to 5207 (Comparator) and then
reset to Zero. <clockdiv> is also compared against Zero
to set/reset <serclock>. But this can be done in the
reset part of <clockdiv>.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.