HDLC transmitter coded in VHDL and its simulation in Modelsim software. Keywords- HDLC, VHDL, FCS, FPGA, Verilog HDL, Xilinx. INTRODUCTION High level data link control (HDLC) protocol is developed by the ISO for data link layer of OSI reference model. It specifies a packetization standard for serial links. It is mostly used as it.
I have coded my own implementation of a serial receiver. It will work for incoming data at a baud rate of 115200. Here's my code: module myserialreceiver( input clk, input resetn, input Rx, output reg 7:0 receivedbyte, output reg byteready ); parameter IDLE = 4'd0, BIT0 = 4'd1, BIT1 = 4'd2, BIT2 = 4'd3, BIT3 = 4'd4, BIT4 = 4'd5, BIT5 = 4'd6, BIT6 = 4'd7, BIT7 = 4'd8, BYTEREADY = 4'd9; reg 3:0 state = 0; reg 7:0 baudrateclock = 0; always @(posedge clk) begin if (baudrateclock 8'd216) begin baudrateclock. FPGA code works in behavioral simulation but not in hardware This happens sometimes. So maybe something is wrong with the hardware, and maybe the simulation doesn't accurately model what happens in reality. Have to check both.
I assume you're a student, since there is free ready-made code that already implements serial UARTs, so my answer is about how to approach debugging this kind of problem. Did synthesis really succeed? When you build the project, are there any diagnostic or warning messages?
Does the synthesized code make sense? Examine the post-translation/post-synthesis code that is generated by the various synthesis tools. As written, the code you posted is behavioral ( always @posedge), not structural (instances and wires).
That makes it very straightforward to simulate, but the synthesis tool has to try to recognize what you're asking for by matching against templates. If your always statement doesn't match one of the templates, then the synthesis tool won't know how to implement it. That should generate a diagnostic message somewhere.
The first translation phase generates RTL code (Register Transfer Logic) which is generic combinational logic plus flip-flops. In this example, you should expect to see some flip-flops for the baud rate counter and the state machine, and some combinational logic to determine next state. Later synthesis phases figure out how to configure the FPGA to implement that RTL code. These mapping and place-and-route phases choose which slice (Xilinx) or configurable logic block (Altera) will be which flip-flop, which pin to use for which toplevel input/output ports, and how to connect it all together. After translation/mapping/place-and-route, you can go back and run post-mapping or post-place-and-route simulation.
This simulates the RTL code that the synthesis tool generated, not the behavioral code you started with. This simulation knows where each flip-flop is located and how many picoseconds of delay each route has, so you can see a more realistic simulation of the timing edges.
(Since your clock is only 25MHz I expect there should be plenty of timing margin.) Simulation and synthesis are very different. An always block that works fine in simulation may unexpectedly be omitted after synthesis. (I once lost half of a fairly complex system because of an 'incomplete initialization ignored' warning in a low-level module, which caused Xilinx ISE 14.7 to replace one entire module with a constant 0. And all of the higher-level modules that depended on that signal, got optimized away to nothing too, since their outputs became constant.
Since there was no longer any internal logic to drive my SPI output, the output pin didn't get routed. Now I've developed the habit of checking the RTL after synthesis to make sure there's no missing pieces.) I come from a C programming background, so I constantly have to challenge myself when writing Verilog: what hardware do I want it to synthesise, then make sure I'm describing it in a way that the synthesis tool can understand. What is the hardware actually doing? Since the FPGA is doing nothing that you can directly observe, it's hard to diagnose whether the FPGA is powered up, configured with your code, and running your state machine. Modify your toplevel to bring out some diagnositc outputs:.
Bring state3:0 to four of the LEDs. Bring baudtick signal to an LED. Add a 'heartbeat' LED blinker to your toplevel (just toggle a D flip-flop at half the clk rate), to help confirm that the FPGA firmware is configured. This diagnositc is worth giving up one of the LEDs, at least for now. Bring receivedbyte0 (the first and least significant bit) to an LED.
Bring receivedbyte7 (the last and most significant bit) to an LED This does mean using the eight LEDs on your board for these diagnostic signals, instead of the receivedbyte7:0 parallel data out. But these lower-level signals give you more useful information to see what's going in inside your module. You can change it back after you get the bugs fixed. I assume your FPGA board has some debounced slide switches. Now's the time to put them to work:. Use a debounced slide switch to drive reset.
Use a debounced slide switch to drive Rx. Use a debounced slide switch to drive clk Temporarily change your baud rate parameter so you get baudtick every 7 clock cycles, so that you can manually clk-toggle through all the states without losing track of time.
Step through the state machine slowly, on real hardware. Check that the heartbeat LED is blinking (alternating 1/2 clk frequency). Check that baudtick gives one pulse at the expected rate ( HINT: I think this is where you'll find the problem. What if initial baudrateclock value is random?).
Check that the state machine goes to the correct state out of reset. Check that your state machine stays in the idle state when Rx is idle. Check that your state machine detects the start bit. Check that your state machine cycles through the states correctly and returns to idle state. Check that the receivedbyte0 and receivedbyte7 values are what you expect. An oscilloscope is a real lifeline if you have one available, this would let you see the hardware running at full speed without needing to toggle through with debounced switches.
For a more complicated design this would be an essential tool. Why doesn't the simulation match reality?
Fully testing a design is a really tough problem. Especially when it's your own code. In this example, your code has inputs clk, reset, and Rx. You're already driving clk.
What happens if Rx is in the 'wrong' state when exiting reset? Will the state machine recover?. What if the transmitter is using a different baud rate (+5%, -5%, +10%, -10%, x2, x0.5).
What if the state machine starts up in an random state, will it recover or will it get stuck?. What if the Rx frame has the wrong stop bit value?. What if the Rx is mark when you're expecting space?. What if the Rx is inverted?
(This is a very common error in RS232 UART systems, because the logic level to RS232 level translator typically inverts.) You get the idea. Coming up with all the test conditions is as hard as any other kind of design work. There will always be coverage gaps, so plan on going back and adding more tests based on what you find in checking the hardware. One of the hardest things in both programming and in HDL design, is testing your own designs. When I write a test bench for my own code, I always worry that I haven't covered enough possible test cases. And any test case that I can think of, I've probably dealt with it in my code - it's the tests that I didn't think of that cause gaps in test coverage. For example, what if the input signal is not synchronized with the device under test?
That's very common in real hardware, but can be tricky to set up in a behavioral simulation. Hope this is enough to get you on your way. @MarkU Thank you so much for such a detailed write up. I will definitely be reffering to this post a lot during my FPGA work. I attempted you debugging technique with the LEDs and it showed that only baudtick and the clk LED were lit. Apparently nothing else is happening. After giving it some thought, I have realized that I designed my UART in a synchronous fashion which is quite opposite whole point of a Universal Asynchronous receiver/transmitter.
I will try to redesign it in an asynchronous manner and see what happens. – Jun 5 '14 at 20:44. Your code is not synthesizable because of a there needs to be an else before case. You would have caught it in simulation by testing the resetn pin. Required changes are in bold.
Recommend enhancements are bold-italic always @(posedge baudtick or negedge resetn) begin if (resetn) begin state.