How to simulate baud rate generator?

I've gotten the following code for the baudrate generator from opencores

I've created a Test Bench Waveform for it from my ISE.

Using single clock, Rising edge, Clock High/Low time as 3, Input setup/ Output Valid delay/ Offset as 0

when i run it in modelsim, I dont get any errors, neither do I get any waves from baud_x_en or baud_en.

======================

-----------------------------------------------------------------------------

-- Filename: am_baud_rate_gen.vhd

--

-- Description:

-- a paramatizable baud rate generator

--

-- input a 'high speed' clock, and get out a clock enable of x times the baud rate, and the baud rate.

-- paramiters are the high speed clock frequency, the baud rate required, and the over sample needed.

--

-- works by having two counters,

-- fast counter, counts down to x time baud rate

-- slow counter, then divides this to give baud rate.

--

--

-- Copyright (c) 2007 by Andrew Mulcock

-- an OpenCores.org Project

-- free to use, but see documentation for conditions

--

-- Revision History:

-- Revision Date Author Comment

-- -------- ---------- --------- -----------

-- 1.0 26/Nov/07 A Mulcock Initial revision

--

----------------------------------------------------------------------------- library ieee ; use ieee.std_logic_1164.all ; use ieee.numeric_std.all ;

entity am_baud_rate_gen is generic( baudrate : integer := 115200; clock_freq_mhz : real := 200.0; over_sample : integer := 4 ); port( clk : in std_logic; rst : in std_logic; baud_x_en : out std_logic; baud_en : out std_logic ); end entity;

-- ==========================================================================================

architecture baud_rtl of am_baud_rate_gen is

-- calculate from the clock freq, the baud rate, and the over sample ratio

-- the size and count of the two counters.

constant div_ratio_real : real := ( clock_freq_mhz * 1000000.0) / ((real(baudrate) * real(over_sample)) ); constant div_ratio_int : integer := integer ( div_ratio_real - 0.5);

-- 0.5 gives rounding up / down constant over_sample_ratio : integer := over_sample -1; constant max_count : integer := div_ratio_int;

signal fast_counter : integer range 0 to div_ratio_int; signal slow_counter : integer range 0 to over_sample_ratio; signal slow_cnt_en : std_logic;

begin

------------------------------------------------------------

------------ baud rate counter -----------------------------

------------------------------------------------------------

-- in an fpga, don't need to reset a wrap around counter,

-- but somepeople still like to for simulation

-- so comparmise and reset syncronously, as suits the syncronous counter.

process(clk) begin if rising_edge(clk) then if ( (rst = '1') or (fast_counter = 0) ) then fast_counter

Reply to
Zhane
Loading thread data ...

Holy crap! - you mean places actually exist for downloading such trivial code? You cannot be THAT interested in FPGA design if you have to download such stuff as this - I summize that this is not your real vocation as you cannot have enough interest to work out such trivia - get a job elsewhere!

Well wooppee doooo

LOL - I would have thought no output was a fundamental major error?

snipped - loadsa copied crap

Reply to
Icky Thwacket

Use this trick, or something like it, so that you can simulate in a reasonably short time but still have the correct baud rate in synthesis.

function calc_divide_ratio is variable div_r : real := ( clock_freq_mhz * 1000000.0) / ((real(baudrate) * real(over_sample)) ); begin

-- pragma translate off; div_r := 16.0; -- or some other fast baud rate for sim

-- pragma translate on; return div_r; end function calc_divide_ratio;

constant div_ratio_real : real := calc_divide_ratio;

The function detects whether you are in simulation or synthesis, and initialises the constant to a different value in each case.

Now in simulation you only need to wait 16 clocks per bit.

- Brian

Reply to
Brian Drummond

ver_sample)) );

im

_ratio;

hmm

when I set my baudrate to 9600, clock_freq_mhz to 50 and over_sample to 4, with simulated clock at 20ns clock period,

the period for baud_x_en is 26060ns How do I know if the generated baudrate is correct?

putting ur function in, I get 354ns period for baud_x_en instead, which is around 17.25 clocks ..which isnt exactly 16.

and.. i've no idea what is over_sample for..

Reply to
Zhane

1 / 9600 = 104.166... microseconds 4x oversampling means baud_x_en should come 4 times every 104.16 microseconds. So 26.041666... microseconds would be the exact frequency and 26.06 microseconds is very close (for 8-bit asynchronous transmission you only need about 1% clock accuracy).

Without looking through the code (not my job :) I'm not sure why the closer value of 26.04 microseconds wasn't used, but as I said 26.06 is close enough (about 700 ppm).

Strange, A clocked process usually only changes on the clock edge so it would have to be a multiple of 20 nS... Where did you get 354nS? Is this measures from the simulation waveform?

Oversampling is for the UART receiver. This allows the UART to find the center of a bit time. 4x is usually a minimum number for the receiver to work reliably. Modern UARTs usually have 16x oversampling. I would suggest finding a paper on UARTs and getting an understanding of the process involved in receiving asynchronous data. It's really not complex and at some point you may actually enjoy designing your own UART.

Regards, Gabor

Reply to
Gabor

up/

ny

is.

al(over_sample)) );

or sim

vide_ratio;

ya... from the simulation waveform

hmm.. actually i only want to transmit...so 4x should be more than sufficient right?

Reply to
Zhane

hmm.. actually i only want to transmit...

so 4x should be more than sufficient right?

1x is sufficient for transmit

KJ

Reply to
KJ

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.