Line 19... |
Line 19... |
// Creator: Dan Gisselquist, Ph.D.
|
// Creator: Dan Gisselquist, Ph.D.
|
// Gisselquist Technology, LLC
|
// Gisselquist Technology, LLC
|
//
|
//
|
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
|
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
|
//
|
//
|
// This program is free software (firmware): you can redistribute it and/or
|
// 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
|
// 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
|
// by the Free Software Foundation, either version 3 of the License, or (at
|
// your option) any later version.
|
// your option) any later version.
|
Line 70... |
Line 70... |
// UART system from a 100MHz clock. This also sets us to an 8-bit data
|
// 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
|
// 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.
|
// i_setup, but at least it gives us something to start with/from.
|
parameter INITIAL_UART_SETUP = 31'd868;
|
parameter INITIAL_UART_SETUP = 31'd868;
|
|
|
|
// Let's set our message length, in case we ever wish to change it in
|
|
// the future
|
|
localparam MSGLEN=2203;
|
|
|
// The i_setup wires are input when run under Verilator, but need to
|
// 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
|
// be set internally if this is going to run as a standalone top level
|
// test configuration.
|
// test configuration.
|
`ifdef OPT_STANDALONE
|
`ifdef OPT_STANDALONE
|
wire [30:0] i_setup;
|
wire [30:0] i_setup;
|
Line 85... |
Line 89... |
reg restart;
|
reg restart;
|
reg wb_stb;
|
reg wb_stb;
|
reg [1:0] wb_addr;
|
reg [1:0] wb_addr;
|
reg [31:0] wb_data;
|
reg [31:0] wb_data;
|
|
|
wire uart_stall, uart_ack;
|
wire uart_stall;
|
|
|
|
// We aren't using the receive interrupts, or the received data, or the
|
|
// ready to send line, so we'll just mark them all here as ignored.
|
|
|
|
/* verilator lint_off UNUSED */
|
|
wire uart_ack, tx_int;
|
wire [31:0] uart_data;
|
wire [31:0] uart_data;
|
|
wire ignored_rx_int, ignored_rxfifo_int;
|
|
wire rts_n_ignored;
|
|
/* verilator lint_on UNUSED */
|
|
|
wire tx_int, txfifo_int;
|
/* verilator lint_on UNUSED */
|
|
|
|
wire txfifo_int;
|
|
|
// The next four lines create a strobe signal that is true on the first
|
// The next four lines create a strobe signal that is true on the first
|
// clock, but never after. This makes for a decent power-on reset
|
// clock, but never after. This makes for a decent power-on reset
|
// signal.
|
// signal.
|
reg pwr_reset;
|
reg pwr_reset;
|
Line 105... |
Line 120... |
//
|
//
|
// Since the message has fewer than 2048 elements in it, we preset every
|
// Since the message has fewer than 2048 elements in it, we preset every
|
// element to a space so that if (for some reason) we broadcast past the
|
// element to a space so that if (for some reason) we broadcast past the
|
// end of our message, we'll at least be sending something useful.
|
// end of our message, we'll at least be sending something useful.
|
integer i;
|
integer i;
|
reg [7:0] message [0:2047];
|
reg [7:0] message [0:4095];
|
initial begin
|
initial begin
|
// xx Verilator needs this file to be in the directory the file
|
// xx Verilator needs this file to be in the directory the file
|
// is run from. For that reason, the project builds, makes,
|
// is run from. For that reason, the project builds, makes,
|
// and keeps speech.hex in bench/cpp.
|
// and keeps speech.hex in bench/cpp.
|
//
|
//
|
Line 119... |
Line 134... |
// bench/verilog directory. You may need to make certain the
|
// bench/verilog directory. You may need to make certain the
|
// file is both built, and copied into a directory where your
|
// file is both built, and copied into a directory where your
|
// synthesis tool can find it.
|
// synthesis tool can find it.
|
//
|
//
|
$readmemh("speech.hex", message);
|
$readmemh("speech.hex", message);
|
for(i=1481; i<2048; i=i+1)
|
for(i=MSGLEN; i<4095; i=i+1)
|
message[i] = 8'h20;
|
message[i] = 8'h20;
|
|
|
//
|
//
|
// The problem with the above approach is Xilinx's ISE program.
|
// The problem with the above approach is Xilinx's ISE program.
|
// It's broken. It can't handle HEX files well (at all?) and
|
// It's broken. It can't handle HEX files well (at all?) and
|
// has more problems with HEX's defining ROM's. For that
|
// has more problems with HEX's defining ROM's. For that
|
// reason, the mkspeech program can be tuned to create an
|
// reason, the mkspeech program can be tuned to create an
|
Line 162... |
Line 178... |
|
|
// Our message index. This is the address of the character we wish to
|
// Our message index. This is the address of the character we wish to
|
// transmit next. Note, there's a clock delay between setting this
|
// transmit next. Note, there's a clock delay between setting this
|
// index and when the wb_data is valid. Hence, we set the index on
|
// index and when the wb_data is valid. Hence, we set the index on
|
// restart[0] to zero.
|
// restart[0] to zero.
|
reg [10:0] msg_index;
|
reg [11:0] msg_index;
|
initial msg_index = 11'd2040;
|
initial msg_index = 12'h000 - 12'h8;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
begin
|
begin
|
if (restart)
|
if (restart)
|
msg_index <= 0;
|
msg_index <= 0;
|
else if ((wb_stb)&&(!uart_stall))
|
else if ((wb_stb)&&(!uart_stall))
|
Line 218... |
Line 234... |
initial end_of_message = 1'b1;
|
initial end_of_message = 1'b1;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (restart)
|
if (restart)
|
end_of_message <= 1'b0;
|
end_of_message <= 1'b0;
|
else
|
else
|
end_of_message <= (msg_index >= 1481);
|
end_of_message <= (msg_index >= MSGLEN);
|
|
|
// The wb_stb signal indicates that we wish to write, using the wishbone
|
// The wb_stb signal indicates that we wish to write, using the wishbone
|
// to our peripheral. We have two separate types of writes. First,
|
// 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
|
// we wish to write our setup. Then we want to drop STB and write
|
// our data. Once we've filled half of the FIFO, we wait for the FIFO
|
// our data. Once we've filled half of the FIFO, we wait for the FIFO
|
Line 246... |
Line 262... |
wb_stb <= 1'b1;
|
wb_stb <= 1'b1;
|
else
|
else
|
// But once the FIFO gets to half full, stop.
|
// But once the FIFO gets to half full, stop.
|
wb_stb <= 1'b0;
|
wb_stb <= 1'b0;
|
|
|
// We aren't using the receive interrupts, so we'll just mark them
|
|
// here as ignored.
|
|
wire ignored_rx_int, ignored_rxfifo_int;
|
|
|
|
// The WBUART can handle hardware flow control signals. This test,
|
// The WBUART can handle hardware flow control signals. This test,
|
// however, cannot. The reason? Simply just to keep things simple.
|
// however, cannot. The reason? Simply just to keep things simple.
|
// If you want to add hardware flow control to your design, simply
|
// If you want to add hardware flow control to your design, simply
|
// make rts an input to this module.
|
// make rts an input to this module.
|
//
|
//
|
// Since this is an output only module demonstrator, what would be the
|
// Since this is an output only module demonstrator, what would be the
|
// cts output is unused.
|
// cts output is unused.
|
wire cts_n, rts_n_ignored;
|
wire cts_n;
|
assign cts_n = 1'b0;
|
assign cts_n = 1'b0;
|
|
|
// Finally--the unit under test--now that we've set up all the wires
|
// Finally--the unit under test--now that we've set up all the wires
|
// to run/test it.
|
// to run/test it.
|
wbuart #(INITIAL_UART_SETUP)
|
wbuart #(INITIAL_UART_SETUP)
|