URL
https://opencores.org/ocsvn/wbuart32/wbuart32/trunk
Subversion Repositories wbuart32
Compare Revisions
- This comparison shows the changes necessary to convert path
/wbuart32/trunk/bench
- from Rev 5 to Rev 6
- ↔ Reverse comparison
Rev 5 → Rev 6
/cpp/helloworld.cpp
44,6 → 44,7
#include <sys/types.h> |
#include <signal.h> |
#include "verilated.h" |
#include "verilated_vcd_c.h" |
#include "Vhelloworld.h" |
#include "uartsim.h" |
|
52,21 → 53,42
Vhelloworld tb; |
UARTSIM *uart; |
int port = 0; |
unsigned setup = 25, testcount = 0; |
unsigned setup = 868, clocks = 0, baudclocks; |
|
tb.i_setup = setup; |
uart = new UARTSIM(port); |
uart->setup(tb.i_setup); |
baudclocks = tb.i_setup & 0xfffffff; |
|
while(testcount++ < 0x7f000000) { |
#define VCDTRACE |
#ifdef VCDTRACE |
Verilated::traceEverOn(true); |
VerilatedVcdC* tfp = new VerilatedVcdC; |
tb.trace(tfp, 99); |
tfp->open("helloworld.vcd"); |
#define TRACE_POSEDGE tfp->dump(10*clocks) |
#define TRACE_NEGEDGE tfp->dump(10*clocks+5) |
#define TRACE_CLOSE tfp->close() |
#else |
#define TRACE_POSEDGE |
#define TRACE_NEGEDGE |
#define TRACE_CLOSE |
#endif |
|
clocks = 0; |
while(clocks < 16*32*baudclocks) { |
|
tb.i_clk = 1; |
tb.eval(); |
TRACE_POSEDGE; |
tb.i_clk = 0; |
tb.eval(); |
TRACE_NEGEDGE; |
|
(*uart)(tb.o_uart_tx); |
clocks++; |
} |
|
TRACE_CLOSE; |
printf("\n\nSimulation complete\n"); |
} |
/verilog/echotest.v
0,0 → 1,138
//////////////////////////////////////////////////////////////////////////////// |
// |
// Filename: echotest.v |
// |
// Project: wbuart32, a full featured UART with simulator |
// |
// Purpose: To test that the txuart and rxuart modules work properly, by |
// echoing the input directly to the output. |
// |
// This module may be run as either a DUMBECHO, simply forwarding the input |
// wire to the output with a touch of clock in between, or it can run as |
// a smarter echo routine that decodes text before returning it. The |
// difference depends upon whether or not OPT_DUMBECHO is defined, as |
// discussed below. |
// |
// With some modifications (discussed below), this RTL should be able to |
// run as a top-level testing file, requiring only the transmit and receive |
// UART pins and the clock to work. |
// |
// DON'T FORGET TO TURN OFF HARDWARE FLOW CONTROL! ... or this'll never |
// work. If you want to run with hardware flow control on, add another |
// wire to this module in order to set o_cts to 1'b1. |
// |
// |
// Creator: Dan Gisselquist, Ph.D. |
// Gisselquist Technology, LLC |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// Copyright (C) 2015-2016, Gisselquist Technology, LLC |
// |
// This program is free software (firmware): you can redistribute it and/or |
// modify it under the terms of the GNU General Public License as published |
// by the Free Software Foundation, either version 3 of the License, or (at |
// your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, but WITHOUT |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with this program. (It's in the $(ROOT)/doc directory, run make with no |
// target there if the PDF file isn't present.) If not, see |
// <http://www.gnu.org/licenses/> for a copy. |
// |
// License: GPL, v3, as defined and found on www.gnu.org, |
// http://www.gnu.org/licenses/gpl.html |
// |
// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// |
// Uncomment the next line defining OPT_DUMBECHO in order to test the wires |
// and external functionality of any UART, independent of the UART protocol. |
// |
`define OPT_DUMBECHO |
// |
// |
// Uncomment the next line if you want this program to work as a standalone |
// (not verilated) RTL "program" to test your UART. You'll also need to set |
// your setup condition properly, though. I recommend setting it to the |
// ratio of your onboard clock to your desired baud rate. For more information |
// about how to set this, please see the specification. |
// |
`define OPT_STANDALONE |
// |
module echotest(i_clk, |
`ifndef OPT_STANDALONE |
i_setup, |
`endif |
i_uart_rx, o_uart_tx); |
input i_clk; |
`ifndef OPT_STANDALONE |
input [29:0] i_setup; |
`endif |
input i_uart_rx; |
output wire o_uart_tx; |
|
`ifdef OPT_DUMBECHO |
reg r_uart_tx; |
|
initial r_uart_tx = 1'b1; |
always @(posedge i_clk) |
r_uart_tx <= i_uart_rx; |
assign o_uart_tx = r_uart_tx; |
`else |
// This is the "smart" echo verion--one that decodes, and then |
// re-encodes, values over the UART. There is a risk, though, doing |
// things in this manner that the receive UART might run *just* a touch |
// faster than the transmitter, and hence drop a bit every now and |
// then. Hence, it works nicely for hand-testing, but not as nicely |
// for high-speed UART testing. |
|
|
|
// If i_setup isnt set up as an input parameter, it needs to be set. |
// We do so here, to a setting appropriate to create a 115200 Baud |
// comms system from a 100MHz clock. This also sets us to an 8-bit |
// data word, 1-stop bit, and no parity. |
// |
// This code only applies if OPT_DUMBECHO is not defined. |
`ifdef OPT_STANDALONE |
wire [29:0] i_setup; |
assign i_setup = 30'd868; // 115200 Baud, if clk @ 100MHz |
`endif |
|
// Create a reset line that will always be true on a power on reset |
reg pwr_reset; |
initial pwr_reset = 1'b1; |
always @(posedge i_clk) |
pwr_reset = 1'b0; |
|
|
|
// The UART Receiver |
// |
// This is where everything begins, by reading data from the UART. |
// |
// Data (rx_data) is present when rx_stb is true. Any parity or |
// frame errors will also be valid at that time. Finally, we'll ignore |
// errors, and even the clocked uart input distributed from here. |
// |
// This code only applies if OPT_DUMBECHO is not defined. |
wire rx_stb, rx_break, rx_perr, rx_ferr, rx_ignored; |
wire [7:0] rx_data; |
|
rxuart receiver(i_clk, pwr_reset, i_setup, i_uart_rx, rx_stb, rx_data, |
rx_break, rx_perr, rx_ferr, rx_ignored); |
|
wire tx_busy; |
txuart transmitter(i_clk, pwr_reset, i_setup, rx_break, |
rx_stb, rx_data, o_uart_tx, tx_busy); |
|
`endif |
|
endmodule |
|
/verilog/speechfifo.v
61,20 → 61,23
input i_clk; |
output wire o_uart_tx; |
|
// Here we set i_setup to something appropriate to create a 115200 Baud |
// UART system from a 100MHz clock. This also sets us to an 8-bit data |
// word, 1-stop bit, and no parity. This will be overwritten by |
// i_setup, but at least it gives us something to start with/from. |
parameter INITIAL_UART_SETUP = 30'd868; |
|
// The i_setup wires are input when run under Verilator, but need to |
// be set internally if this is going to run as a standalone top level |
// test configuration. |
`ifdef OPT_STANDALONE |
wire [29:0] i_setup; |
|
// Here we set i_setup to something appropriate to create a 115200 Baud |
// UART system from a 100MHz clock. This also sets us to an 8-bit data |
// word, 1-stop bit, and no parity. |
assign i_setup = 30'd868; |
assign i_setup = INITIAL_UART_SETUP; |
`else |
input [29:0] i_setup; |
`endif |
|
reg restart; |
reg wb_stb; |
reg [1:0] wb_addr; |
reg [31:0] wb_data; |
101,9 → 104,9
integer i; |
reg [7:0] message [0:2047]; |
initial begin |
for(i=0; i<2048; i=i+1) |
$readmemh("speech.hex",message); |
for(i=1481; i<2048; i=i+1) |
message[i] = 8'h20; |
$readmemh("speech.hex",message); |
end |
|
// Let's keep track of time, and send our message over and over again. |
121,12 → 124,9
// let's build a set of signals that we can use to get things started |
// again. This will be the restart signal. On this signal, we just |
// restart everything. |
reg restart; |
initial restart = 0; |
always @(posedge i_clk) |
begin |
restart <= (restart_counter == 0); |
end |
|
// Our message index. This is the address of the character we wish to |
// transmit next. Note, there's a clock delay between setting this |
175,6 → 175,21
else // if (!uart_stall)?? |
wb_addr <= 2'b11; |
|
// Knowing when to stop sending the speech is important, but depends |
// upon an 11 bit comparison. Since FPGA logic is best measured by the |
// number of inputs to an always block, we pull those 11-bits out of |
// the always block for wb_stb, and place them here on the clock prior. |
// If end_of_message is true, then we need to stop transmitting, and |
// wait for the next (restart) to get us started again. We set that |
// flag hee. |
reg end_of_message; |
initial end_of_message = 1'b1; |
always @(posedge i_clk) |
if (restart) |
end_of_message <= 1'b0; |
else |
end_of_message <= (msg_index >= 1481); |
|
// The wb_stb signal indicates that we wish to write, using the wishbone |
// to our peripheral. We have two separate types of writes. First, |
// we wish to write our setup. Then we want to drop STB and write |
184,14 → 199,26
initial wb_stb = 1'b0; |
always @(posedge i_clk) |
if (restart) |
// Start sending to the UART on a reset. The first |
// thing we'll send will be the configuration, but |
// that's done elsewhere. This just starts up the |
// writes to the peripheral wbuart. |
wb_stb <= 1'b1; |
else if (msg_index >= 1481) |
else if (end_of_message) |
// Stop transmitting when we get to the end of our |
// message. |
wb_stb <= 1'b0; |
else if (tx_int) |
// If we aren't at the end of the message, and tx_int |
// tells us the FIFO is empty, then start writing into |
// the FIFO> |
wb_stb <= 1'b1; |
else if (txfifo_int) |
// If we are writing into the FIFO, and it's less than |
// half full (i.e. txfifo_int is true) then keep going. |
wb_stb <= wb_stb; |
else |
// But once the FIFO gets to half full, stop. |
wb_stb <= 1'b0; |
|
// We aren't using the receive interrupts, so we'll just mark them |
200,7 → 227,7
|
// Finally--the unit under test--now that we've set up all the wires |
// to run/test it. |
wbuart #(30'h868) |
wbuart #(INITIAL_UART_SETUP) |
wbuarti(i_clk, pwr_reset, |
wb_stb, wb_stb, 1'b1, wb_addr, wb_data, |
uart_stall, uart_ack, uart_data, |