-
Notifications
You must be signed in to change notification settings - Fork 253
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
42 changed files
with
2,884 additions
and
306 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# This Source Code Form is subject to the terms of the Mozilla Public | ||
# License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
# You can obtain one at http://mozilla.org/MPL/2.0/. | ||
# | ||
# Copyright (c) 2014-2015, Lars Asplund lars.anders.asplund@gmail.com | ||
|
||
from os.path import join, dirname | ||
from vunit.verilog import VUnit | ||
|
||
ui = VUnit.from_argv() | ||
|
||
src_path = join(dirname(__file__), "src") | ||
|
||
uart_lib = ui.add_library("uart_lib") | ||
uart_lib.add_source_files(join(src_path, "*.sv")) | ||
|
||
tb_uart_lib = ui.add_library("tb_uart_lib") | ||
tb_uart_lib.add_source_files(join(src_path, "test", "*.sv")) | ||
|
||
ui.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
// You can obtain one at http://mozilla.org/MPL/2.0/. | ||
// | ||
// Copyright (c) 2015, Lars Asplund lars.anders.asplund@gmail.com | ||
|
||
`include "vunit_defines.svh" | ||
|
||
module tb_uart_rx; | ||
localparam integer baud_rate = 115200; // bits / s | ||
localparam integer clk_period = 20; // ns | ||
localparam integer cycles_per_bit = 50 * 10**6 / baud_rate; | ||
localparam time_per_bit = (10**9 / baud_rate); | ||
localparam time_per_half_bit = time_per_bit/2; | ||
logic clk = 1'b0; | ||
|
||
// Serial input bit | ||
logic rx = 1'b0; | ||
|
||
// AXI stream for input bytes | ||
logic overflow; | ||
logic tready = 1'b0; | ||
logic tvalid; | ||
logic [7:0]tdata; | ||
integer num_overflows = 0; | ||
|
||
`TEST_SUITE begin | ||
`TEST_CASE("test_tvalid_low_at_start") begin | ||
fork : tvalid_low_check | ||
begin | ||
wait (tvalid == 1'b1); | ||
$error("tvalid should not be high unless data received"); | ||
disable tvalid_low_check; | ||
end | ||
begin | ||
#100ns; | ||
disable tvalid_low_check; | ||
end | ||
join | ||
end | ||
|
||
`TEST_CASE("test_receives_one_byte") begin | ||
uart_send(77, rx, baud_rate); | ||
tready <= 1'b1; | ||
@(posedge clk iff tready == 1'b1 && tvalid == 1'b1); | ||
`CHECK_EQUAL(tdata, 77); | ||
tready <= 1'b0; | ||
`CHECK_EQUAL(num_overflows, 0); | ||
@(posedge clk); | ||
`CHECK_EQUAL(tvalid, 1'b0); | ||
end | ||
|
||
`TEST_CASE("test_two_bytes_cause_overflow") begin | ||
uart_send(77, rx, baud_rate); | ||
@(posedge clk iff tvalid == 1'b1); | ||
`CHECK_EQUAL(num_overflows, 0); | ||
uart_send(77, rx, baud_rate); | ||
`CHECK_EQUAL(num_overflows, 1); | ||
end | ||
end | ||
|
||
`WATCHDOG(10ms); | ||
|
||
task automatic uart_send(input integer data, ref logic rx, input integer baud_rate); | ||
integer time_per_bit; | ||
time_per_bit = (10**9 / baud_rate); | ||
rx = 1'b0; | ||
#(time_per_bit * 1ns); | ||
|
||
for (int i=0; i<8; i++) begin | ||
rx = data[i]; | ||
#(time_per_bit * 1ns); | ||
end | ||
|
||
rx = 1'b1; | ||
#(time_per_bit * 1ns); | ||
endtask | ||
|
||
always begin | ||
#(clk_period/2 * 1ns); | ||
clk <= !clk; | ||
end | ||
|
||
always @(posedge clk iff overflow == 1'b1) begin | ||
num_overflows <= num_overflows + 1; | ||
end | ||
|
||
uart_rx #(.cycles_per_bit(cycles_per_bit)) dut(.*); | ||
|
||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
// You can obtain one at http://mozilla.org/MPL/2.0/. | ||
// | ||
// Copyright (c) 2015, Lars Asplund lars.anders.asplund@gmail.com | ||
|
||
`include "vunit_defines.svh" | ||
|
||
module tb_uart_tx; | ||
localparam integer baud_rate = 115200; // bits / s | ||
localparam integer clk_period = 20; // ns | ||
localparam integer cycles_per_bit = 50 * 10**6 / baud_rate; | ||
localparam time_per_bit = (10**9 / baud_rate); | ||
localparam time_per_half_bit = time_per_bit/2; | ||
logic clk = 1'b0; | ||
|
||
// Serial output bit | ||
logic tx; | ||
|
||
// AXI stream for input bytes | ||
logic tready; | ||
logic tvalid = 1'b0; | ||
logic [7:0]tdata; | ||
|
||
int words[$]; | ||
int num_recv; | ||
|
||
task automatic send(); | ||
int word = $urandom_range(255); | ||
tvalid <= 1'b1; | ||
tdata <= word; | ||
words.push_back(word); | ||
@(posedge clk iff tvalid == 1'b1 && tready == 1'b1); | ||
$info("AXI: Sent word ", word); | ||
tvalid <= 1'b0; | ||
endtask | ||
|
||
task automatic check_all_was_received(); | ||
wait (words.size() == num_recv); | ||
endtask | ||
|
||
`TEST_SUITE begin | ||
`TEST_CASE("test_send_one_byte") begin | ||
send(); | ||
check_all_was_received(); | ||
end | ||
`TEST_CASE("test_send_many_bytes") begin | ||
for (int i=0; i<7; i++) begin | ||
send(); | ||
end | ||
check_all_was_received(); | ||
end | ||
end | ||
|
||
`WATCHDOG(10ms); | ||
|
||
always begin | ||
#(clk_period/2 * 1ns); | ||
clk <= !clk; | ||
end | ||
|
||
task automatic uart_recv(output integer data); | ||
data = 0; | ||
wait(tx == 1'b0); | ||
#(time_per_half_bit * 1ns); | ||
`CHECK_EQUAL(tx, 1'b0, "Expected low tx"); | ||
#(time_per_bit * 1ns); | ||
for (int i=0; i<8; i++) begin | ||
data[i] = tx; | ||
#(time_per_bit * 1ns); | ||
end | ||
`CHECK_EQUAL(tx, 1'b1, "Expected high tx"); | ||
#(time_per_half_bit * 1ns); | ||
endtask | ||
|
||
always begin | ||
integer data; | ||
uart_recv(data); | ||
$info("WIRE: Received data ", data); | ||
`CHECK_EQUAL(data, words[num_recv]); | ||
num_recv = num_recv + 1; | ||
end | ||
|
||
uart_tx #(.cycles_per_bit(cycles_per_bit)) dut(.*); | ||
|
||
|
||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
// You can obtain one at http://mozilla.org/MPL/2.0/. | ||
// | ||
// Copyright (c) 2015, Lars Asplund lars.anders.asplund@gmail.com | ||
|
||
module uart_rx(clk, rx, overflow, tready, tvalid, tdata); | ||
parameter integer cycles_per_bit = 434; | ||
|
||
input logic clk; | ||
|
||
// Serial input bit | ||
input logic rx; | ||
|
||
output logic overflow = 1'b0; | ||
|
||
// AXI stream for input bytes | ||
input logic tready; | ||
output logic tvalid = 1'b0; | ||
output logic [7:0] tdata; | ||
|
||
typedef enum {idle, receiving, done} state_t; | ||
state_t state = idle; | ||
|
||
logic [7:0] data; | ||
logic [$bits(cycles_per_bit)-1:0] cycles = 0; | ||
logic [$bits($size(data))-1:0] index; | ||
|
||
always @(posedge clk) begin | ||
overflow <= 1'b0; | ||
|
||
case (state) | ||
idle : begin | ||
if (rx == 1'b0) begin | ||
if (cycles == cycles_per_bit/2 - 1) begin | ||
state = receiving; | ||
cycles <= 0; | ||
index <= 0; | ||
end else begin | ||
cycles <= cycles + 1; | ||
end | ||
end else begin | ||
cycles <= 0; | ||
end | ||
end | ||
|
||
receiving : begin | ||
if (cycles == cycles_per_bit - 1) begin | ||
data <= {rx, data[$size(data)-1:1]}; | ||
cycles <= 0; | ||
|
||
if (index == $size(data) - 1) begin | ||
state <= done; | ||
end else begin | ||
index <= index + 1; | ||
end | ||
end else begin | ||
cycles <= cycles + 1; | ||
end | ||
end | ||
|
||
done : begin | ||
overflow <= tvalid && !tready; | ||
tvalid <= 1'b1; | ||
tdata <= data; | ||
state <= idle; | ||
end | ||
endcase | ||
|
||
if (tvalid == 1'b1 && tready == 1'b1) begin | ||
tvalid <= 1'b0; | ||
end | ||
end | ||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
// You can obtain one at http://mozilla.org/MPL/2.0/. | ||
// | ||
// Copyright (c) 2015, Lars Asplund lars.anders.asplund@gmail.com | ||
|
||
module uart_tx(clk, tx, tready, tvalid, tdata); | ||
parameter integer cycles_per_bit = 434; | ||
|
||
input logic clk; | ||
|
||
// Serial output bit | ||
output logic tx = 1'b1; | ||
|
||
// AXI stream for input bytes | ||
output logic tready = 1'b1; | ||
input logic tvalid; | ||
input logic [7:0] tdata; | ||
|
||
typedef enum {idle, sending} state_t; | ||
state_t state = idle; | ||
|
||
logic [9:0] data; | ||
logic [$bits(cycles_per_bit)-1:0] cycles; | ||
logic [$bits($size(data))-1:0] index; | ||
|
||
|
||
always @(posedge clk) | ||
begin | ||
case (state) | ||
idle : begin | ||
tx <= 1'b1; | ||
if (tvalid == 1'b1 && tready == 1'b1) begin | ||
state <= sending; | ||
tready <= 1'b0; | ||
cycles <= 0; | ||
index <= 0; | ||
data <= {1'b1, tdata, 1'b0}; | ||
end | ||
end | ||
|
||
sending : begin | ||
tx <= data[0]; | ||
|
||
if (cycles == cycles_per_bit - 1) begin | ||
if (index == $size(data)-1) begin | ||
state <= idle; | ||
tready <= 1'b1; | ||
end else begin | ||
index <= index + 1; | ||
end | ||
data <= {1'b0, data[$size(data)-1:1]}; | ||
cycles <= 0; | ||
end else begin | ||
cycles <= cycles + 1; | ||
end | ||
end | ||
endcase | ||
end | ||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# This Source Code Form is subject to the terms of the Mozilla Public | ||
# License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
# You can obtain one at http://mozilla.org/MPL/2.0/. | ||
# | ||
# Copyright (c) 2014-2015, Lars Asplund lars.anders.asplund@gmail.com | ||
|
||
from os.path import join, dirname | ||
from vunit.verilog import VUnit | ||
|
||
root = dirname(__file__) | ||
|
||
ui = VUnit.from_argv() | ||
lib = ui.add_library("lib") | ||
lib.add_source_files(join(root, "*.sv")) | ||
ui.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
// You can obtain one at http://mozilla.org/MPL/2.0/. | ||
// | ||
// Copyright (c) 2015, Lars Asplund lars.anders.asplund@gmail.com | ||
|
||
`include "vunit_defines.svh" | ||
|
||
module tb_example; | ||
`TEST_SUITE begin | ||
|
||
`TEST_SUITE_SETUP begin | ||
$info("test suite setup"); | ||
end | ||
|
||
`TEST_CASE_SETUP begin | ||
$info("test case setup"); | ||
end | ||
|
||
`TEST_CASE("Test that pass") begin | ||
$info("pass"); | ||
end | ||
|
||
`TEST_CASE("Test that fail") begin | ||
`CHECK_EQUAL(0, 1); | ||
end | ||
|
||
`TEST_CASE("Test that timeouts") begin | ||
#2ns; | ||
end | ||
|
||
`TEST_CASE_TEARDOWN begin | ||
$info("test case teardown"); | ||
end | ||
|
||
`TEST_SUITE_TEARDOWN begin | ||
$info("test suite teardown"); | ||
end | ||
end; | ||
|
||
`WATCHDOG(1ns); | ||
endmodule |
Oops, something went wrong.