uart testbench help

Guest
Hello guys,

I am trying to write a testbench for my 9600 baud UART, can someone
suggest how I can write the code for this in verilog. I'd like to
send this data to my reciever module for verification ..

Thanks,
 
On Sun, 5 Apr 2009 03:11:18 -0700 (PDT), uraniumore238@gmail.com
wrote:

Hello guys,

I am trying to write a testbench for my 9600 baud UART, can someone
suggest how I can write the code for this in verilog. I'd like to
send this data to my reciever module for verification ..

Think BEHAVIOURAL...

`timescale 1ns/1ns
module behavioural_UART_tx
#(parameter bit_time = 104000) // nanoseconds
(output reg line);

initial
line = 1'b1; // line idles true

task send(input [7:0] data);
reg [9:0] uart_frame;
begin
// construct the whole frame with start and stop bit
// STOP data START
uart_frame = {1'b1, data, 1'b0};
repeat (10) // number of bit-symbols to send
begin
line = uart_frame[0]; // drive line to correct level
uart_frame = uart_frame >> 1; // prepare next bit
#(bit_time); // hold output for one bit time
end
end
endtask

endmodule

That's it! Now, instantiate your DUT receiver and this Tx
model:

`timescale 1ns/1ns
module TB;

wire line;
// And any other signals you need for your DUT
// such as clock, reset, data-bus...

// And any clock generators, etc...

// Here's the UART signal generator...
behavioural_UART_Tx tx_model(.line(line));

// and here's your device-under-test...
your_UART_Rx_design DUT(.rx_line(line), ......);

// and here's the test stimulus generator:
initial begin: StimGen
// Hang around for a while...
#100000;
// Use the Tx model to send a few characters to the DUT:
tx_model.send("H");
tx_model.send("e");
tx_model.send("l");
tx_model.send("l");
tx_model.send("o");
// Idle awhile:
#200000;
// Send a newline character (LF = 10)
tx_model.send(10);
end

endmodule


NOTE VERY CAREFULLY the use of a task in the transmitter
model, and how you call that task from the testbench
to get the transmitter model to do work for you.

Enjoy.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Hi Jonathan,

Yes, behavioral is good for transmit, but make sure you don't simulate
only the ideal case.


In order to be sure, that your uart receiver is working in a real
environment you should do following.

Add periodic spikes and noise to your line. (wrong detection of start
bits???)

Vary the variable bittime.
You should try
- too fast transmission (back to back transmission of multiple
characters). What is important is whether your UART will properly
recognize the start bit of the next character and whether it will not
accumulate delays and fail perhaps to detect the start bit of the fourth
/ fifth character.

- too slow transmission

- jittery transmission



If you implement a behavioral receiver module you do not have to model
spikes, as your transmitter will not generate them in simulation.
However in order to verify, that your baud rate algorithms are not
broken you should simulate at least with all potentially necessary baud
rates and use the mathematically correct bit clock.
Start bit detection can probably just b done by a negedge detection.
determining whether a bit is a 1 or a zero I'd just do oversampling and
make a majority vote.
Make also sure, that your behavioral receiver handles well if
consecutive bytes are received with a slightly too fast clock.

bye


N



Jonathan Bromley wrote:
On Sun, 5 Apr 2009 03:11:18 -0700 (PDT), uraniumore238@gmail.com
wrote:

Hello guys,

I am trying to write a testbench for my 9600 baud UART, can someone
suggest how I can write the code for this in verilog. I'd like to
send this data to my reciever module for verification ..


Think BEHAVIOURAL...

`timescale 1ns/1ns
module behavioural_UART_tx
#(parameter bit_time = 104000) // nanoseconds
(output reg line);

initial
line = 1'b1; // line idles true

task send(input [7:0] data);
reg [9:0] uart_frame;
begin
// construct the whole frame with start and stop bit only
// STOP data START
uart_frame = {1'b1, data, 1'b0};
repeat (10) // number of bit-symbols to send
begin
line = uart_frame[0]; // drive line to correct level
uart_frame = uart_frame >> 1; // prepare next bit
#(bit_time); // hold output for one bit time
end
end
endtask

endmodule

That's it! Now, instantiate your DUT receiver and this Tx
model:

`timescale 1ns/1ns
module TB;

wire line;
// And any other signals you need for your DUT
// such as clock, reset, data-bus...

// And any clock generators, etc...

// Here's the UART signal generator...
behavioural_UART_Tx tx_model(.line(line));

// and here's your device-under-test...
your_UART_Rx_design DUT(.rx_line(line), ......);

// and here's the test stimulus generator:
initial begin: StimGen
// Hang around for a while...
#100000;
// Use the Tx model to send a few characters to the DUT:
tx_model.send("H");
tx_model.send("e");
tx_model.send("l");
tx_model.send("l");
tx_model.send("o");
// Idle awhile:
#200000;
// Send a newline character (LF = 10)
tx_model.send(10);
end

endmodule


NOTE VERY CAREFULLY the use of a task in the transmitter
model, and how you call that task from the testbench
to get the transmitter model to do work for you.

Enjoy.
 
On Sun, 05 Apr 2009 15:09:09 +0200, News123 <news123@free.fr> wrote:

Yes, behavioral is good for transmit, but make sure you don't simulate
only the ideal case.
For you and me, yes.

However, there is a CLUE here...

I am trying to write a testbench for my 9600 baud UART, can someone
suggest how I can write the code for this in verilog.
....strongly suggesting that the OP is - how shall we say it
politely - taking his first tentative steps. So I posted
what I sincerely hope will be his first confident leap.
Procedural entry points to a module are IMO the most
important single benefit of Verilog over VHDL for
verification, and are not as widely understood as
they should be. Once understood, the possibilities
for modelling error conditions (as you suggest)
should be fairly evident.

Speaking of Verilog vs. VHDL, see the nearby thread
"question about the verilog standard." for lots of
reasons why Verilog is actually a PITA if used carelessly.

--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Speaking of Verilog vs. VHDL, see the nearby thread
"question about the verilog standard." for lots of
reasons why Verilog is actually a PITA if used carelessly.
How true !

If only vhdl did not oblige you to write millions of lines to
accomplish what in vlog you do in two !

BTW: vhdl can be quite painful itself.
I saw somebody trying to put together multiple modules.
Some had the clk defined as bit, some as std_logic, some as std_ulogic

Well, when simulating that you were suffering from clock skew at rtl
because of all the conversion routines !!!

Ciao, Marco.
 
On Tue, 7 Apr 2009 02:32:04 -0700 (PDT), uraniumore wrote:

What does this mean ?

ERROR:HDLCompiler:329 - "TestTopRX.v" Line 68. Concurrent assignment
to a non-net reset is not permitted
ERROR:Simulator:778 - Static elaboration of top level Verilog design
unit(s) in library work failed

I am having trouble pin-pointing my error. Here is my

module TB;

wire line;
// And any other signals you need for your DUT
// such as clock, reset, data-bus...
reg clk;
reg reset;
wire serial_out;
wire buffer_full;
wire startC;
wire resetC;
wire preset;
reg read_buffer_rx;

// And any clock generators, etc...
// declared inside RX and TX module
always #10 clk = ~clk; //50 Mhz input

// Here's the UART signal generator...
behavioural_UART_Tx tx_model(.line(line));

// and here's your device-under-test...
Top_RXandTX DUT(clk, reset, serial_out, buffer_full, line, startC,
resetC, preset, read_buffer_rx); //<<ERROR HERE!!!
Looks like your port list is messed-up. Verilog seems
to think that the second port of Top_RXandTX is an output,
which means it needs a wire connected to it; but you've
connected a reg to it. Double-check the DUT module's
port list to ensure that reset is indeed the second
port, and that it is indeed an input.

In future, I strongly recommend you use named mapping
(the .port(signal) style) for the ports of any module
instance with more than about three ports. It's always
safer and less pain in the long run.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Apr 6, 5:37 pm, hairyotter <marco.br...@gmail.com> wrote:
Speaking of Verilog vs. VHDL, see the nearby thread
"question about the verilog standard." for lots of
reasons why Verilog is actually a PITA if used carelessly.

How true !

If only vhdl did not oblige you to write millions of lines to
accomplish what in vlog you do in two !

BTW: vhdl can be quite painful itself.
I saw somebody trying to put together multiple modules.
Some had the clk defined as bit, some as std_logic, some as std_ulogic

Well, when simulating that you were suffering from clock skew at rtl
because of all the conversion routines !!!

Ciao, Marco.
Hey Guys,

What does this mean ?

ERROR:HDLCompiler:329 - "TestTopRX.v" Line 68. Concurrent assignment
to a non-net reset is not permitted
ERROR:Simulator:778 - Static elaboration of top level Verilog design
unit(s) in library work failed

I am having trouble pin-pointing my error. Here is my

`timescale 1ns/1ns
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 01:32:53 04/01/2009
// Design Name:
// Module Name: TestTopRX
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module behavioural_UART_Tx

#(parameter bit_time = 104000) // nanoseconds
(output reg line);

initial
line = 1'b1; // line idles true

task send(input [7:0] data);
reg [9:0] uart_frame;
begin
// construct the whole frame with start and stop bit
// STOP data START
uart_frame = {1'b1, data, 1'b0};
repeat (10) // number of bit-symbols to send
begin
line = uart_frame[0]; // drive line to correct level
uart_frame = uart_frame >> 1; // prepare next bit
#(bit_time); // hold output for one bit time
end
end
endtask
endmodule


module TB;

wire line;
// And any other signals you need for your DUT
// such as clock, reset, data-bus...
reg clk;
reg reset;
wire serial_out;
wire buffer_full;
wire startC;
wire resetC;
wire preset;
reg read_buffer_rx;

// And any clock generators, etc...
// declared inside RX and TX module
always #10 clk = ~clk; //50 Mhz input

// Here's the UART signal generator...
behavioural_UART_Tx tx_model(.line(line));

// and here's your device-under-test...
Top_RXandTX DUT(clk, reset, serial_out, buffer_full, line, startC,
resetC, preset, read_buffer_rx); //<<ERROR HERE!!!

// and here's the test stimulus generator:
initial begin: StimGen
// Hang around for a while...
clk = 0;
//reset_buffer = 1;
#50;
reset = 1;
#50 reset = 0;
#50 read_buffer_rx = 1;
#100000;
// Use the Tx model to send a few characters to the DUT:
tx_model.send("A"); /*
tx_model.send("e");
tx_model.send("l");
tx_model.send("l");
tx_model.send("o"); */
// Idle awhile:
#200000;
// Send a newline character (LF = 10)
tx_model.send(10);
end


endmodule
 
On Mon, 6 Apr 2009 17:37:36 -0700 (PDT), hairyotter wrote:

BTW: vhdl can be quite painful itself.
I saw somebody trying to put together multiple modules.
Some had the clk defined as bit, some as std_logic, some as std_ulogic

Well, when simulating that you were suffering from clock skew at rtl
because of all the conversion routines !!!
Another example of people complaining about VHDL because
they don't properly understand it. If you put the
conversion routine IN THE PORT MAP, then it doesn't
cost a delta cycle.

Clock gating can't be done in the port map, and
definitely does cause delta-skew trouble in VHDL;
you can hack^wwork around that in Verilog by using
blocking assignment in your combinational clock-gate
logic and nonblocking assignment (of course) in all
registered logic. I haven't yet worked out which
of those two uglinesses I prefer.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Another example of people complaining about VHDL because
they don't properly understand it.  If you put the
conversion routine IN THE PORT MAP, then it doesn't
cost a delta cycle.
Jonathan, sorry, it's not easy to not take this personally.

Please do notice that I did not say I did this, I said somebody else
did it and (at the time I was a pretty junior designer) it took me a
day just to figure out what the ... was going on.

I still do think that VHDL is much easier to comprehend and is a much
better way of understanding how it works.
For one, there is no messing up with timescales, blocking and
nonblocking, the delta time concept is crystal clear.

Also, the xemacs vhdl mode is FAR superior to the verilog mode.

However, with all the strong typing it still is quite easy, if you're
not careful, to create unwanted phenomena, which is one of the things
that the language wanted to eliminate.

VHDL does even have dynamically allocated structures, but writing
complex behavioural testbenches is terribly complicated (tasks ?).

I still do love vhdl, as it was the language I learned first (first
kiss...) but I do not think that the reason why we have systemVlog and
not SystemVhdl is just because these were developed in the US.

Ciao, Marco.


Clock gating can't be done in the port map, and
definitely does cause delta-skew trouble in VHDL;
you can hack^wwork around that in Verilog by using
blocking assignment in your combinational clock-gate
logic and nonblocking assignment (of course) in all
registered logic.  I haven't yet worked out which
of those two uglinesses I prefer.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Tue, 7 Apr 2009 22:07:27 -0700 (PDT), hairyotter wrote:

Another example of people complaining about VHDL because
they don't properly understand it.  If you put the
conversion routine IN THE PORT MAP, then it doesn't
cost a delta cycle.

Jonathan, sorry, it's not easy to not take this personally.
No offence meant; it's just that I weary of all the anti-VHDL
canards that I routinely hear.

Please do notice that I did not say I did this, I said somebody else
did it
and I said "people" because I was pretty sure you didn't!

However, with all the strong typing it still is quite easy, if you're
not careful, to create unwanted phenomena, which is one of the things
that the language wanted to eliminate.
Yes, there are indeed some quite unfortunate things... fewer than
Verilog, for sure, and less pervasive, but unfortunate nonetheless.

VHDL does even have dynamically allocated structures, but writing
complex behavioural testbenches is terribly complicated (tasks ?).
Yes. I've said many times - and will no doubt say again - that
Verilog's ability to make procedural calls into a module is the
most important thing it does to help testbench construction.
On the other hand, it is not outrageously hard to work up
a block-to-block communication scheme for your VHDL testbench
that looks suspiciously like transaction-level modeling.

Thanks
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Apr 8, 3:13 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
On Tue, 7 Apr 2009 22:07:27 -0700 (PDT), hairyotter wrote:
Another example of people complaining about VHDL because
they don't properly understand it. If you put the
conversion routine IN THE PORT MAP, then it doesn't
cost a delta cycle.

Jonathan, sorry, it's not easy to not take this personally.

No offence meant; it's just that I weary of all the anti-VHDL
canards that I routinely hear.

Please do notice that I did not say I did this, I said somebody else
did it

and I said "people" because I was pretty sure you didn't!

However, with all the strong typing it still is quite easy, if you're
not careful, to create unwanted phenomena, which is one of the things
that the language wanted to eliminate.

Yes, there are indeed some quite unfortunate things... fewer than
Verilog, for sure, and less pervasive, but unfortunate nonetheless.

VHDL does even have dynamically allocated structures, but writing
complex behavioural testbenches is terribly complicated (tasks ?).

Yes.  I've said many times - and will no doubt say again - that
Verilog's ability to make procedural calls into a module is the
most important thing it does to help testbench construction.
On the other hand, it is not outrageously hard to work up
a block-to-block communication scheme for your VHDL testbench
that looks suspiciously like transaction-level modeling.

Thanks
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
Hey guys,

I am having a real problem with this UART stuff. My problem is sending
data from the bbfifo block of Ken Chapman's Transmitter module.
Initially, I have a 32 bit register, 8 bits gets written to the fifo
at every clock cycle. I am having problems sending this 32 bit to a PC
at 9600 bps. I have verified that my reciever module is working, the
problem is my transmitter module. My clock rate is 155.52 external
clock signal on the Spartan 3AN board. Please let me know if you have
any suggestions ..


/*
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 17:45:12 03/29/2009
// Design Name:
// Module Name: Top_RXandTX
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Top_RXandTX(clk, serial_out, buffer_full,serial_in, resetC,
startC, preset, reset);

//Protocol: Start, Wait for Complete, Read Numerator, Read
denominator, Reset, etc

wire [7:0] command;
reg en_16_x_baud;
reg [9:0] baud_count;
output reg resetC;
input reset;


input clk;
//input wire reset_buffer; //reset tranfer buffer
input serial_in;
//input [31:0] numerator;
reg [31:0] glum;
//input read_buffer_rx;
wire num_avail;
reg [4:0] counter;

output preset;
output serial_out;
output buffer_full;

output reg startC;
reg startT;
reg resetCounter;
reg resetCommand;
reg sendNum;
reg sendStart;



//read an 8bit command from the reciever buffer, translate the
commands to start and reset signals

always @ (command) //test when command changes
begin
case(command) //test the command

8'b01000001: begin startC <=0; resetC <= 0; end //start for one one
count session

8'b01000010: begin startC <=1; resetC <= 1; end //reset for one
count session

default : begin startC <=1; resetC <= 1; end //disable counter
and enable reset signals

endcase
end



always @ (posedge clk)
begin
if(reset) //software command reset
begin

baud_count <= 0;
en_16_x_baud <= 0;

end
else
begin
if (baud_count == 324) //enable data rate for uart_communication to PC
begin
baud_count <= 1'b0;
en_16_x_baud <= 1'b1;
end
else
begin
baud_count <= baud_count + 1;
en_16_x_baud <= 1'b0;
end
end
end

always @ (posedge clk)
begin
if(startC) //reset signals
begin
counter <= 0; //reset clock signa;
startT <= 0; //reset uart transfer
sendStart <= 1; //
end
else
begin
if (~startC & counter == 0 & sendStart) //start command detected,
reset counter completed, and data numerator available
begin
//numerator and denominator are ready for data transfer to the
computer
glum <= 32'b01000100010001000100010001000100; //tranfer COMPLETION
signal
startT<=1; //begin transfer
sendStart <= 0; //start is being processed
end
if(~sendStart & counter == 1) //wait two clocks after, glum transfer
complete
begin
startT<=0; //stop transfer after 3 clock cycles
sendStart <= 0; //start had been transfered
end

if (~startC & reset_buffer & counter == 4) //start command detected,
reset counter completed, and data numerator available
begin
//numerator and denominator are ready for data transfer to the
computer
glum <= numerator; //tranfer numerator/denominator
startT<=1; //begin transfer
sendNum <= 1; // numerator is being processed
end
else if(sendNum & counter == 6 ) //wait two clocks after, glum
transfer complete
begin
startT<=0; //stop transfer after 3 clock cycles
sendNum <= 0; //numerator has been transfered
end
//
counter <= counter + 1; //go to the next cycle

end
end


//when the endount is pulsed then the the glum value gets transfered
to the computer
Top_Tx u1(clk,
startC,
serial_out,
buffer_full,
buffer_half_full,
en_16_x_baud,
glum,
startT
); //transmit glum to computer

//when a command (8-bits) is recieved the fpga decodes it, and enables
thE FPGA for one of the actions
//as soon as a 8 bit signal comes in, we reset the buffer right away
Top_Rx u2(serial_in,
command,
read_buffer_rx,
en_16_x_baud, clk,
preset,
buffer_full_rx,
buffer_half_full_rx,
startC); //recieve start, stop, reset instruction from the
computer


endmodule
*/

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 17:45:12 03/29/2009
// Design Name:
// Module Name: Top_RXandTX
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Top_RXandTX(clk, serial_out, buffer_full,serial_in, resetC,
startC, preset, reset, numerator, done, denominator);

//Protocol: Start, Wait for Complete, Read Numerator, Read
denominator, Reset, etc
//Notes:
//altercation: 11:32 AM baud tranfer for 50 MHz used in this module
for Behavioral simulation,
//need to change to comment option for Implementation


wire [7:0] command;
reg en_16_x_baud;
reg [9:0] baud_count;
output reg resetC;
input reset;
input [31:0] numerator;
input [31:0] denominator;

input clk;
//input wire reset_buffer; //reset tranfer buffer
input serial_in;
//input [31:0] numerator;
reg [31:0] glum;
//input read_buffer_rx;
wire num_avail;
reg [9:0] counter;


output preset;
output serial_out;
output buffer_full;

output reg startC;
reg startT;
reg resetCounter;
reg resetCommand;
reg sendNum;
reg sendStart;
input done;
reg sendStart2;


//read an 8bit command from the reciever buffer, translate the
commands to start and reset signals

always @ (command) //test when command changes
begin
case(command) //test the command

8'b01000001: begin startC =0; resetC = 0; end //start for one one
count session

8'b01000010: begin startC =1; resetC = 1; end //reset for one
count session

//default : begin startC =1; resetC = 1; end //disable counter
and enable reset signals

endcase
end

always @ (posedge clk)
begin
if(reset ) //manual board reset
begin

baud_count <= 0;
en_16_x_baud <= 0;

end
else
begin
if (baud_count == 1013) //enable data rate for uart_communication to
PC
begin
baud_count <= 1'b0;
en_16_x_baud <= 1'b1;
end
else
begin
baud_count <= baud_count + 1;
en_16_x_baud <= 1'b0;
end
end
end

always @ (posedge clk)
begin
if(startC) //reset signals
begin
counter <= 0; //reset clock signal;
startT <= 0; //reset uart transfer
sendStart <= 1; //
sendStart2 <= 0; //
end
else
begin

if (~startT /*done*/ & sendStart) //start command detected, reset
counter completed, and data numerator available
begin
//numerator and denominator are ready for data transfer to the
computer
glum <= 32'b01010101011000110110100001100101 ;
startT<=1; //initialize device and reset fifo buffer
sendStart <= 0; //start is being processed
end
if(startT & baud_count == ) //reset transfer at 3rd clock cycle
begin
startT<=0; //stop initialization and start fifo buffer transfer
sendStart2 <= 1; //start numerator logic
end

if(~startT & sendStart2)
begin
glum <= 32'b01010101010010110100000101001010;
startT<=1; //initialize device and reset fifo buffer
sendStart2 <= 0; //disable the previous
end
if(startT)
begin
startT <= 0; //transfer transfer
end

counter <= counter + 1; //go to the next cycle
end
end



//when the endount is pulsed then the the glum value gets transfered
to the computer
Top_Tx u1(clk,
startC,
serial_out,
buffer_full,
buffer_half_full,
en_16_x_baud,
glum,
startT
); //transmit glum to computer

//when a command (8-bits) is recieved the fpga decodes it, and enables
thE FPGA for one of the actions
Top_Rx u2(serial_in,
command,
1'b1,
en_16_x_baud, clk,
preset,
buffer_full_rx,
buffer_half_full_rx,
startC); //recieve start, stop, reset instruction from the
computer

endmodule

module Top_Tx(clk, reset/*endcount*/, serial_out, buffer_full,
buffer_half_full, en_16_x_baud, glum
,startT);

reg [7:0] data_in;
input [31:0] glum;
reg [31:0] data;
reg write_buffer;
input en_16_x_baud;
input reset;
input clk; //50 Mhz master clock
output wire serial_out;
output wire buffer_full;
output wire buffer_half_full;
reg start;
input startT;
reg [3:0] counter;

// Set baud rate to 96 for the UART communications
// Requires en_16_x_baud to be 153600Hz which is a single cycle pulse
every 325 cycles at 50MHz
//
// NOTE : If the highest value for baud_count exceeds 127 you will
need to adjust
// the width in the reg declaration for baud_count.
//
//--------------------------------------------------------------------------------------------------------------------------------

always @ (posedge clk)
begin

if(startT) //initialize all registers fir one clock cycle
begin
//reset all signals
data_in<=0;
counter <= 0;
start<=1; //begin transfer
write_buffer <= 0;
data <= glum;
end
else
begin

if(start) //begin transfer
begin
if(counter == 1) //clock cycle 0
begin
data_in<=data[7:0]; //send data to port 1 byte
end

else if(counter == 2) write_buffer <= 1; //activate write to uart
port //WAIT

else if (counter == 3)
begin
data_in<=data[15:8];
end

else if (counter == 4)
begin
data_in<=data[23:16];
end

else if (counter == 5)
begin
data_in<=data[31:24];
end

else if(counter == 6)
begin
write_buffer <= 0; //stop burst writing
start <= 0; //stop transfer with uart transfer
end

counter <= counter + 1;
end

end
end

//when write is asserted, the uart_tx module writes the data_in into
the 128 bits into the buffer
//and activates the buffer_full signal
uart_tx uart_Tx(.data_in(data_in),
.write_buffer(write_buffer), //write the data_in bits into the
FIFO
.reset_buffer(startT),
.en_16_x_baud(en_16_x_baud),
.serial_out(serial_out),
.buffer_full(buffer_full),
.buffer_half_full(buffer_half_full),
.clk(clk));
//this is the reciever module. start, stop, reset bit patterns are
sent from the Rx line of the RS-232
//to this reciever module and then processed

endmodule
 
On Apr 14, 6:24 pm, uraniumore...@gmail.com wrote:
On Apr 8, 3:13 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com
wrote:





On Tue, 7 Apr 2009 22:07:27 -0700 (PDT), hairyotter wrote:
Another example of people complaining about VHDL because
they don't properly understand it. If you put the
conversion routine IN THE PORT MAP, then it doesn't
cost a delta cycle.

Jonathan, sorry, it's not easy to not take this personally.

No offence meant; it's just that I weary of all the anti-VHDL
canards that I routinely hear.

Please do notice that I did not say I did this, I said somebody else
did it

and I said "people" because I was pretty sure you didn't!

However, with all the strong typing it still is quite easy, if you're
not careful, to create unwanted phenomena, which is one of the things
that the language wanted to eliminate.

Yes, there are indeed some quite unfortunate things... fewer than
Verilog, for sure, and less pervasive, but unfortunate nonetheless.

VHDL does even have dynamically allocated structures, but writing
complex behavioural testbenches is terribly complicated (tasks ?).

Yes.  I've said many times - and will no doubt say again - that
Verilog's ability to make procedural calls into a module is the
most important thing it does to help testbench construction.
On the other hand, it is not outrageously hard to work up
a block-to-block communication scheme for your VHDL testbench
that looks suspiciously like transaction-level modeling.

Thanks
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.brom...@MYCOMPANY.comhttp://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.

Hey guys,

I am having a real problem with this UART stuff. My problem is sending
data from the bbfifo block of Ken Chapman's Transmitter module.
Initially, I have a 32 bit register, 8 bits gets written to the fifo
at every clock cycle. I am having problems sending this 32 bit to a PC
at 9600 bps. I have verified that my reciever module is working, the
problem is my transmitter module. My clock rate is 155.52 external
clock signal on the Spartan 3AN board. Please let me know if you have
any suggestions ..

/*
`timescale 1ns / 1ps
///////////////////////////////////////////////////////////////////////////­///////
// Company:
// Engineer:
//
// Create Date:    17:45:12 03/29/2009
// Design Name:
// Module Name:    Top_RXandTX
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
///////////////////////////////////////////////////////////////////////////­///////
module Top_RXandTX(clk, serial_out, buffer_full,serial_in, resetC,
startC, preset, reset);

//Protocol: Start, Wait for Complete, Read Numerator, Read
denominator, Reset, etc

wire [7:0] command;
reg en_16_x_baud;
reg  [9:0] baud_count;
output reg resetC;
input reset;

input clk;
//input wire reset_buffer; //reset tranfer buffer
input serial_in;
//input [31:0] numerator;
reg [31:0] glum;
//input read_buffer_rx;
wire num_avail;
reg [4:0] counter;

output preset;
output serial_out;
output buffer_full;

output reg startC;
reg startT;
reg resetCounter;
reg resetCommand;
reg sendNum;
reg sendStart;

//read an 8bit command from the reciever buffer, translate the
commands to start and reset signals

always @ (command) //test when command changes
begin
case(command) //test the command

        8'b01000001: begin  startC <=0; resetC <= 0; end  //start for one one
count session

   8'b01000010: begin  startC <=1; resetC <= 1; end       //reset for one
count session

        default   : begin  startC <=1; resetC <= 1; end   //disable counter
and enable reset signals

endcase
end

always @ (posedge clk)
begin
if(reset) //software command reset
begin

        baud_count <= 0;
        en_16_x_baud <= 0;

end
else
begin
if (baud_count == 324) //enable data rate for uart_communication to PC
                begin
                                        baud_count <= 1'b0;
                                        en_16_x_baud <= 1'b1;
                end
                else
                begin
                        baud_count <= baud_count + 1;
                        en_16_x_baud <= 1'b0;
                end
end
end

        always @ (posedge clk)
        begin
                if(startC) //reset signals
                begin
                        counter <= 0; //reset clock signa;
                        startT <= 0; //reset uart transfer
                        sendStart <= 1; //
                end
        else
        begin
                if (~startC & counter == 0 & sendStart) //start command detected,
reset counter completed, and data numerator available
                begin
                        //numerator and denominator are ready for data transfer to the
computer
                        glum <= 32'b01000100010001000100010001000100; //tranfer COMPLETION
signal
                        startT<=1; //begin transfer
                        sendStart <= 0; //start is being processed
                end
                if(~sendStart & counter == 1) //wait two clocks after, glum transfer
complete
                begin
                        startT<=0; //stop transfer after 3 clock cycles
                        sendStart <= 0; //start had been transfered
                end

                if (~startC & reset_buffer & counter == 4) //start command detected,
reset counter completed, and data numerator available
                begin
                        //numerator and denominator are ready for data transfer to the
computer
                        glum <= numerator; //tranfer numerator/denominator
                        startT<=1; //begin transfer
                        sendNum <= 1; // numerator is being processed
                end
                else if(sendNum & counter == 6 ) //wait two clocks after, glum
transfer complete
                begin
                        startT<=0; //stop transfer after 3 clock cycles
                        sendNum <= 0; //numerator has been transfered
                end
//
                counter <= counter + 1; //go to the next cycle

         end
end

//when the endount is pulsed then the the glum value gets transfered
to the computer
Top_Tx u1(clk,
                         startC,
                         serial_out,
                         buffer_full,
                         buffer_half_full,
                         en_16_x_baud,
                         glum,
                         startT
     ); //transmit glum to computer

//when a command (8-bits) is recieved the fpga decodes it, and enables
thE FPGA for one of the actions
//as soon as a 8 bit signal comes in, we reset the buffer right away
Top_Rx u2(serial_in,
                         command,
                         read_buffer_rx,
                         en_16_x_baud, clk,
                         preset,
                         buffer_full_rx,
                         buffer_half_full_rx,
                         startC); //recieve start, stop, reset instruction from the
computer

endmodule
*/

`timescale 1ns / 1ps
///////////////////////////////////////////////////////////////////////////­///////
// Company:
// Engineer:
//
// Create Date:    17:45:12 03/29/2009
// Design Name:
// Module Name:    Top_RXandTX
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
///////////////////////////////////////////////////////////////////////////­///////
module Top_RXandTX(clk, serial_out, buffer_full,serial_in, resetC,
startC, preset, reset, numerator, done, denominator);

//Protocol: Start, Wait for Complete, Read Numerator, Read
denominator, Reset, etc
//Notes:
//altercation: 11:32 AM baud tranfer for 50 MHz used in this module
for Behavioral simulation,
//need to change to comment option for Implementation

wire [7:0] command;
reg en_16_x_baud;
reg  [9:0] baud_count;
output reg resetC;
input reset;
input [31:0] numerator;
input [31:0] denominator;

input clk;
//input wire reset_buffer; //reset tranfer buffer
input serial_in;
//input [31:0] numerator;
reg [31:0] glum;
//input read_buffer_rx;
wire num_avail;
reg [9:0] counter;

output preset;
output serial_out;
output buffer_full;

output reg startC;
reg startT;
reg resetCounter;
reg resetCommand;
reg sendNum;
reg sendStart;
input done;
reg sendStart2;

//read an 8bit command from the reciever buffer, translate the
commands to start and reset signals

always @ (command) //test when command changes
begin
case(command) //test the command

        8'b01000001: begin  startC =0; resetC = 0; end  //start for one one
count session

   8'b01000010: begin  startC =1; resetC = 1; end       //reset for one
count session

        //default         : begin  startC =1; resetC = 1; end   //disable counter
and enable reset signals

endcase
end

always @ (posedge clk)
begin
if(reset ) //manual board reset
begin

        baud_count <= 0;
        en_16_x_baud <= 0;

end
else
begin
                if (baud_count == 1013) //enable data rate for uart_communication to
PC
                begin
                        baud_count <= 1'b0;
                        en_16_x_baud <= 1'b1;
                end
                else
                begin
                        baud_count <= baud_count + 1;
                        en_16_x_baud <= 1'b0;
                end
end
end

        always @ (posedge clk)
        begin
                if(startC) //reset signals
                begin
                        counter <= 0; //reset clock signal;
                        startT <= 0; //reset uart transfer
                        sendStart <= 1; //
                        sendStart2 <= 0; //
                end
                else
                begin

                if (~startT /*done*/  & sendStart) //start command detected, reset
counter completed, and data numerator available
                begin
                        //numerator and denominator are ready for data transfer to the
computer
                        glum <= 32'b01010101011000110110100001100101 ;
                        startT<=1; //initialize device and reset fifo buffer
                        sendStart <= 0; //start is being processed
                end
                if(startT & baud_count == ) //reset transfer at 3rd clock cycle
                begin
                        startT<=0; //stop initialization and start fifo buffer transfer
                        sendStart2 <= 1; //start numerator logic
                end

                if(~startT & sendStart2)
                begin
                        glum <= 32'b01010101010010110100000101001010;
                        startT<=1; //initialize device and reset fifo buffer
                        sendStart2 <= 0; //disable the previous
                end
                if(startT)
                begin
                        startT <= 0; //transfer transfer
                end

                counter <= counter + 1; //go to the next cycle
         end
end

//when the endount is pulsed then the the glum value gets transfered
to the computer
Top_Tx u1(clk,
                         startC,
                         serial_out,
                         buffer_full,
                         buffer_half_full,
                         en_16_x_baud,
                         glum,
                         startT
     ); //transmit glum to computer

//when a command (8-bits) is recieved the fpga decodes it, and enables
thE FPGA for one of the actions
Top_Rx u2(serial_in,
                         command,
                         1'b1,
                         en_16_x_baud, clk,
                         preset,
                         buffer_full_rx,
                         buffer_half_full_rx,
                         startC); //recieve

read more ť- Hide quoted text -

- Show quoted text -...
always @ (posedge clk)
begin

if(startT) //initialize all registers fir one clock cycle
begin
//reset all signals
data_in<=0;
counter <= 0;
start<=1; //begin transfer
write_buffer <= 0;
data <= glum;
end
else
begin

if(start) //begin transfer
begin
if(counter == 1) //clock cycle 0
begin
data_in<=data[7:0]; //send data to port 1 byte
end

else if(counter == 2) write_buffer <= 1; //activate write to uart
port //WAIT

else if (counter == 3)
begin
data_in<=data[15:8];
end

else if (counter == 4)
begin
data_in<=data[23:16];
end

else if (counter == 5)
begin
data_in<=data[31:24];
end

else if(counter == 6)
begin
write_buffer <= 0; //stop burst writing
start <= 0; //stop transfer with uart transfer
end

counter <= counter + 1;
end

end
end

//when write is asserted, the uart_tx module writes the data_in into
the 128 bits into the buffer
//and activates the buffer_full signal
uart_tx uart_Tx(.data_in(data_in),
.write_buffer(write_buffer), //write the data_in bits into the
FIFO
.reset_buffer(startT),
.en_16_x_baud(en_16_x_baud),
.serial_out(serial_out),
.buffer_full(buffer_full),
.buffer_half_full(buffer_half_full),
.clk(clk));
//this is the reciever module. start, stop, reset bit patterns are
sent from the Rx line of the RS-232
//to this reciever module and then processed

endmodule
 

Welcome to EDABoard.com

Sponsor

Back
Top