initial
This commit is contained in:
commit
038be21f4f
34
.vscode/tasks.json
vendored
Normal file
34
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Compile design",
|
||||
"type": "shell",
|
||||
"command": "./sims/compile_design.sh ${file}",
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Compile & simulate design",
|
||||
"type": "shell",
|
||||
"command": "./sims/compile_design.sh ${file} && cd sims && ./gtkwave \"${fileBasename}.vcd\" && cd -",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Simulate design",
|
||||
"type": "shell",
|
||||
"command": "cd sims && ./gtkwave \"${fileBasename}.vcd\" && cd -",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Simulate design with TCL",
|
||||
"type": "shell",
|
||||
"command": "cd sims && ./gtkwave \"${fileBasename}.vcd\" -T \"${fileBasename}.tcl\" && cd -",
|
||||
"problemMatcher": []
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
30
sims/.gtkwaverc
Normal file
30
sims/.gtkwaverc
Normal file
@ -0,0 +1,30 @@
|
||||
do_initial_zoom_fit 1
|
||||
enable_vcd_autosave yes
|
||||
splash_disable on
|
||||
dynamic_resing 1
|
||||
initial_window_x 1920
|
||||
initial_window_y 1120
|
||||
|
||||
# ablak háttérszíne
|
||||
color_back gray90
|
||||
|
||||
# értékek színe
|
||||
color_value blue
|
||||
|
||||
# rács színe
|
||||
color_grid light steel blue
|
||||
|
||||
# jelek színe
|
||||
#color_1 light sea green
|
||||
color_1 dark olive green
|
||||
#color_0 dark sea green
|
||||
color_0 dark olive green
|
||||
|
||||
vector_padding 16
|
||||
enable_vert_grid 1
|
||||
enable_horiz_grid 0
|
||||
|
||||
color_vbox dark olive green
|
||||
color_xfill dark red
|
||||
|
||||
color_time dark orange
|
||||
80
sims/compile_design.sh
Executable file
80
sims/compile_design.sh
Executable file
@ -0,0 +1,80 @@
|
||||
#!/bin/sh
|
||||
|
||||
FILENAME=$1
|
||||
BASENAME=`basename $1`
|
||||
DUMPFILE=$BASENAME.vcd
|
||||
PREPROCFILE=$BASENAME.preproc
|
||||
OUTFILE=$BASENAME.out
|
||||
|
||||
echo "\n"
|
||||
|
||||
# modul nevének kinyerése
|
||||
MODULENAME=$(grep -E "^module (.)+" "$FILENAME" | cut -d\; -f1 | awk '{print $2}')
|
||||
|
||||
echo "Module: '$MODULENAME'"
|
||||
|
||||
# szimulációban szerepeltetendő jelek kinyerése
|
||||
SIMSIGNALS=$(grep -E '^([^/]+)( `s )' "$FILENAME" | sed 's/[#(;][.]*//' | awk '{print $NF}')
|
||||
|
||||
if [ "$SIMSIGNALS" ] # ha vannak kiválasztott jelek
|
||||
then
|
||||
VARSTODUMP=""
|
||||
|
||||
# szimulálandó jelek összeírása a $dumpvars-hoz
|
||||
for SIGNAME in $SIMSIGNALS
|
||||
do
|
||||
if [ "$VARSTODUMP" ]
|
||||
then
|
||||
VARSTODUMP="$VARSTODUMP, $MODULENAME.$SIGNAME"
|
||||
else
|
||||
VARSTODUMP="$MODULENAME.$SIGNAME"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Signals to display: $VARSTODUMP"
|
||||
|
||||
else # ha nincsenek
|
||||
echo "No signals marked explicitly to simulate. Dumping all."
|
||||
|
||||
VARSTODUMP=$MODULENAME
|
||||
fi
|
||||
|
||||
# szimulációs kiírási sorrend kinyerése
|
||||
SIGSORT=$(grep -E '^(//# )' "$FILENAME" | sed 's|//# ||' | sed 's/, /,/g')
|
||||
|
||||
if [ "$SIGSORT" ] # ha meg van adva lista, akkor TCL-scriptet generál belőle
|
||||
then
|
||||
TCLSCRIPT="gtkwave::deleteSignalsFromListIncludingDuplicates [ gtkwave::getDisplayedSignals ]\n\n"
|
||||
|
||||
for line in $SIGSORT # parancs generálása soronként
|
||||
do
|
||||
TCLSCRIPT="$TCLSCRIPT gtkwave::addSignalsFromList [split \"$line\" ,]\n"
|
||||
done
|
||||
|
||||
TCLFILENAME="$BASENAME.tcl";
|
||||
|
||||
# TCL-script kimentése
|
||||
echo "$TCLSCRIPT" > "sims/$TCLFILENAME"
|
||||
|
||||
echo "Signal sorting TCL-file saved in 'sims/$TCLFILENAME'"
|
||||
fi
|
||||
|
||||
|
||||
# $dumpvars(...) beírása a fájlba
|
||||
sed "/initial begin/a \$dumpfile(\"$DUMPFILE\");\n \$dumpvars(0, $VARSTODUMP);" "$FILENAME" > "$PREPROCFILE"
|
||||
|
||||
echo "\n"
|
||||
|
||||
# Verilog-fájl fordítása
|
||||
iverilog -Wall "$PREPROCFILE" -o "sims/$OUTFILE"
|
||||
|
||||
rm "$PREPROCFILE"
|
||||
|
||||
#cd sims
|
||||
|
||||
# szimuláció futtatása
|
||||
vvp "sims/$OUTFILE"
|
||||
|
||||
mv $DUMPFILE "sims/$DUMPFILE"
|
||||
|
||||
#cd -
|
||||
92
sims/configuration.gtkw
Normal file
92
sims/configuration.gtkw
Normal file
@ -0,0 +1,92 @@
|
||||
[*]
|
||||
[*] GTKWave Analyzer v3.3.103 (w)1999-2019 BSI
|
||||
[*] Sun Mar 29 08:49:22 2020
|
||||
[*]
|
||||
[dumpfile] "/home/epagris/EGYETEM/RA/ra_hf/sims/TB_APB_master_dump.vcd"
|
||||
[dumpfile_mtime] "Sun Mar 29 08:35:11 2020"
|
||||
[dumpfile_size] 3919
|
||||
[savefile] "/home/epagris/EGYETEM/RA/ra_hf/sims/configuration.gtkw"
|
||||
[timestart] 0
|
||||
[size] 1920 1110
|
||||
[pos] -1 -1
|
||||
*-15.000000 134790 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||
[treeopen] TB_APB_master.
|
||||
[sst_width] 211
|
||||
[signals_width] 365
|
||||
[sst_expanded] 1
|
||||
[sst_vpaned_height] 321
|
||||
@200
|
||||
-MASTER
|
||||
@22
|
||||
TB_APB_master.apb_master_uut.PADDR[31:0]
|
||||
@28
|
||||
TB_APB_master.apb_master_uut.PCLK
|
||||
TB_APB_master.apb_master_uut.PENABLE
|
||||
@22
|
||||
TB_APB_master.apb_master_uut.PRDATA[31:0]
|
||||
@28
|
||||
TB_APB_master.apb_master_uut.PREADY
|
||||
TB_APB_master.apb_master_uut.PRESETn
|
||||
TB_APB_master.apb_master_uut.PSEL0
|
||||
TB_APB_master.apb_master_uut.PSLVERR
|
||||
@22
|
||||
TB_APB_master.apb_master_uut.PWDATA[31:0]
|
||||
@28
|
||||
TB_APB_master.apb_master_uut.PWRITE
|
||||
@22
|
||||
TB_APB_master.apb_master_uut.addr[31:0]
|
||||
@420
|
||||
TB_APB_master.apb_master_uut.bus_state
|
||||
@28
|
||||
TB_APB_master.apb_master_uut.clk
|
||||
@22
|
||||
TB_APB_master.apb_master_uut.data_read[31:0]
|
||||
TB_APB_master.apb_master_uut.data_write[31:0]
|
||||
@28
|
||||
TB_APB_master.apb_master_uut.rst
|
||||
@22
|
||||
TB_APB_master.apb_master_uut.sampled_addr[31:0]
|
||||
TB_APB_master.apb_master_uut.sampled_write_data[31:0]
|
||||
@28
|
||||
TB_APB_master.apb_master_uut.setup_valid
|
||||
@420
|
||||
TB_APB_master.apb_master_uut.transaction_type
|
||||
@28
|
||||
TB_APB_master.apb_master_uut.transfer_done
|
||||
TB_APB_master.apb_master_uut.write_not_read
|
||||
@200
|
||||
-SLAVE
|
||||
@22
|
||||
TB_APB_master.apb_slave_uut.PADDR[31:0]
|
||||
@28
|
||||
TB_APB_master.apb_slave_uut.PCLK
|
||||
TB_APB_master.apb_slave_uut.PENABLE
|
||||
@22
|
||||
TB_APB_master.apb_slave_uut.PRDATA[31:0]
|
||||
@28
|
||||
TB_APB_master.apb_slave_uut.PREADY
|
||||
TB_APB_master.apb_slave_uut.PRESETn
|
||||
TB_APB_master.apb_slave_uut.PSEL0
|
||||
TB_APB_master.apb_slave_uut.PSLVERR
|
||||
@22
|
||||
TB_APB_master.apb_slave_uut.PWDATA[31:0]
|
||||
@28
|
||||
TB_APB_master.apb_slave_uut.PWRITE
|
||||
@22
|
||||
TB_APB_master.apb_slave_uut.addr[31:0]
|
||||
@28
|
||||
TB_APB_master.apb_slave_uut.bWithinAddressRange
|
||||
TB_APB_master.apb_slave_uut.clk
|
||||
@22
|
||||
TB_APB_master.apb_slave_uut.data_read[31:0]
|
||||
TB_APB_master.apb_slave_uut.data_write[31:0]
|
||||
@28
|
||||
TB_APB_master.apb_slave_uut.ready
|
||||
TB_APB_master.apb_slave_uut.request_from_master
|
||||
TB_APB_master.apb_slave_uut.rst
|
||||
@420
|
||||
TB_APB_master.apb_slave_uut.state
|
||||
@28
|
||||
TB_APB_master.apb_slave_uut.write_not_read
|
||||
[pattern_trace] 1
|
||||
[pattern_trace] 0
|
||||
BIN
sims/gtkwave
Executable file
BIN
sims/gtkwave
Executable file
Binary file not shown.
47
src/del_meas/del_meas.v
Normal file
47
src/del_meas/del_meas.v
Normal file
@ -0,0 +1,47 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module del_meas #(
|
||||
parameter WIDTH = 10
|
||||
)(
|
||||
input wire clk, // clock
|
||||
input wire rst, // reset
|
||||
|
||||
input wire ref, // reference signal
|
||||
input wire sig, // signal being measured
|
||||
|
||||
input wire arm, // arm the next measurement cycle
|
||||
output wire listening, // indicated that measurement is armed
|
||||
output reg done, // signals when measurement has concluded
|
||||
input wire ack, // acknowledge latest measurement, turn off done
|
||||
|
||||
output reg negative, // indicates if delay is negative
|
||||
output reg [WIDTH-1:0] delay // delay in ticks
|
||||
);
|
||||
|
||||
// named states
|
||||
localparam S_IDLE = 2'b0;
|
||||
localparam S_LISTEN = 2'b1;
|
||||
|
||||
// inner state
|
||||
reg [1:0] state;
|
||||
|
||||
// main state machine
|
||||
always@(posedge clk)
|
||||
begin
|
||||
if (rst)
|
||||
begin
|
||||
done <= 0;
|
||||
negative <= 0;
|
||||
delay <= 0;
|
||||
state <= S_IDLE;
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
// output logic
|
||||
assign listening = (state == S_LISTEN);
|
||||
|
||||
endmodule
|
||||
73
src/eth/crc32.v
Normal file
73
src/eth/crc32.v
Normal file
@ -0,0 +1,73 @@
|
||||
`timescale 1ns / 1ps
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 OutputLogic.com
|
||||
// This source file may be used and distributed without restriction
|
||||
// provided that this copyright statement is not removed from the file
|
||||
// and that any derivative work contains the original copyright notice
|
||||
// and the associated disclaimer.
|
||||
//
|
||||
// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
|
||||
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
// CRC module for data[7:0] , crc[31:0]=1+x^1+x^2+x^4+x^5+x^7+x^8+x^10+x^11+x^12+x^16+x^22+x^23+x^26+x^32;
|
||||
//-----------------------------------------------------------------------------
|
||||
module crc32(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
input wire clear,
|
||||
|
||||
input wire [7:0] data_in,
|
||||
input wire crc_en,
|
||||
output wire [31:0] crc_out
|
||||
);
|
||||
|
||||
reg [31:0] lfsr_q,lfsr_c;
|
||||
|
||||
assign crc_out = ~lfsr_q;
|
||||
|
||||
always @(*) begin
|
||||
lfsr_c[0] = lfsr_q[24] ^ lfsr_q[30] ^ data_in[0] ^ data_in[6];
|
||||
lfsr_c[1] = lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[0] ^ data_in[1] ^ data_in[6] ^ data_in[7];
|
||||
lfsr_c[2] = lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[6] ^ data_in[7];
|
||||
lfsr_c[3] = lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[31] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[7];
|
||||
lfsr_c[4] = lfsr_q[24] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[30] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6];
|
||||
lfsr_c[5] = lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7];
|
||||
lfsr_c[6] = lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7];
|
||||
lfsr_c[7] = lfsr_q[24] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[29] ^ lfsr_q[31] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[7];
|
||||
lfsr_c[8] = lfsr_q[0] ^ lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[27] ^ lfsr_q[28] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4];
|
||||
lfsr_c[9] = lfsr_q[1] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[28] ^ lfsr_q[29] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5];
|
||||
lfsr_c[10] = lfsr_q[2] ^ lfsr_q[24] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[29] ^ data_in[0] ^ data_in[2] ^ data_in[3] ^ data_in[5];
|
||||
lfsr_c[11] = lfsr_q[3] ^ lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[27] ^ lfsr_q[28] ^ data_in[0] ^ data_in[1] ^ data_in[3] ^ data_in[4];
|
||||
lfsr_c[12] = lfsr_q[4] ^ lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[30] ^ data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[4] ^ data_in[5] ^ data_in[6];
|
||||
lfsr_c[13] = lfsr_q[5] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[29] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[5] ^ data_in[6] ^ data_in[7];
|
||||
lfsr_c[14] = lfsr_q[6] ^ lfsr_q[26] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[6] ^ data_in[7];
|
||||
lfsr_c[15] = lfsr_q[7] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[31] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[7];
|
||||
lfsr_c[16] = lfsr_q[8] ^ lfsr_q[24] ^ lfsr_q[28] ^ lfsr_q[29] ^ data_in[0] ^ data_in[4] ^ data_in[5];
|
||||
lfsr_c[17] = lfsr_q[9] ^ lfsr_q[25] ^ lfsr_q[29] ^ lfsr_q[30] ^ data_in[1] ^ data_in[5] ^ data_in[6];
|
||||
lfsr_c[18] = lfsr_q[10] ^ lfsr_q[26] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[2] ^ data_in[6] ^ data_in[7];
|
||||
lfsr_c[19] = lfsr_q[11] ^ lfsr_q[27] ^ lfsr_q[31] ^ data_in[3] ^ data_in[7];
|
||||
lfsr_c[20] = lfsr_q[12] ^ lfsr_q[28] ^ data_in[4];
|
||||
lfsr_c[21] = lfsr_q[13] ^ lfsr_q[29] ^ data_in[5];
|
||||
lfsr_c[22] = lfsr_q[14] ^ lfsr_q[24] ^ data_in[0];
|
||||
lfsr_c[23] = lfsr_q[15] ^ lfsr_q[24] ^ lfsr_q[25] ^ lfsr_q[30] ^ data_in[0] ^ data_in[1] ^ data_in[6];
|
||||
lfsr_c[24] = lfsr_q[16] ^ lfsr_q[25] ^ lfsr_q[26] ^ lfsr_q[31] ^ data_in[1] ^ data_in[2] ^ data_in[7];
|
||||
lfsr_c[25] = lfsr_q[17] ^ lfsr_q[26] ^ lfsr_q[27] ^ data_in[2] ^ data_in[3];
|
||||
lfsr_c[26] = lfsr_q[18] ^ lfsr_q[24] ^ lfsr_q[27] ^ lfsr_q[28] ^ lfsr_q[30] ^ data_in[0] ^ data_in[3] ^ data_in[4] ^ data_in[6];
|
||||
lfsr_c[27] = lfsr_q[19] ^ lfsr_q[25] ^ lfsr_q[28] ^ lfsr_q[29] ^ lfsr_q[31] ^ data_in[1] ^ data_in[4] ^ data_in[5] ^ data_in[7];
|
||||
lfsr_c[28] = lfsr_q[20] ^ lfsr_q[26] ^ lfsr_q[29] ^ lfsr_q[30] ^ data_in[2] ^ data_in[5] ^ data_in[6];
|
||||
lfsr_c[29] = lfsr_q[21] ^ lfsr_q[27] ^ lfsr_q[30] ^ lfsr_q[31] ^ data_in[3] ^ data_in[6] ^ data_in[7];
|
||||
lfsr_c[30] = lfsr_q[22] ^ lfsr_q[28] ^ lfsr_q[31] ^ data_in[4] ^ data_in[7];
|
||||
lfsr_c[31] = lfsr_q[23] ^ lfsr_q[29] ^ data_in[5];
|
||||
|
||||
end // always
|
||||
|
||||
always @(posedge clk, posedge rst) begin
|
||||
if(rst | clear) begin
|
||||
lfsr_q <= {32{1'b0}};
|
||||
end
|
||||
else begin
|
||||
lfsr_q <= crc_en ? lfsr_c : lfsr_q;
|
||||
end
|
||||
end // always
|
||||
endmodule // crc32
|
||||
76
src/eth/crc32_test.v
Normal file
76
src/eth/crc32_test.v
Normal file
@ -0,0 +1,76 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module crc32_test;
|
||||
|
||||
// Inputs
|
||||
reg clk;
|
||||
reg rst;
|
||||
reg clear;
|
||||
reg [7:0] data_in;
|
||||
reg crc_en;
|
||||
|
||||
// Outputs
|
||||
wire [31:0] crc_out;
|
||||
|
||||
// Instantiate the Unit Under Test (UUT)
|
||||
crc32 uut (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.clear(clear),
|
||||
.data_in(data_in),
|
||||
.crc_en(crc_en),
|
||||
.crc_out(crc_out)
|
||||
);
|
||||
|
||||
always #10 clk = ~clk;
|
||||
|
||||
integer ifile;
|
||||
integer c;
|
||||
|
||||
initial begin
|
||||
// Initialize Inputs
|
||||
clk = 0;
|
||||
rst = 1;
|
||||
clear = 0;
|
||||
data_in = 0;
|
||||
crc_en = 0;
|
||||
|
||||
// Wait 100 ns for global reset to finish
|
||||
#100;
|
||||
rst = 0;
|
||||
|
||||
// Add stimulus here
|
||||
|
||||
// open file holding the test input
|
||||
ifile = $fopen("src/sim/lorem_ipsum.txt", "r");
|
||||
if (ifile == 0)
|
||||
begin
|
||||
$display("Error on opening test input!\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
while (!$feof(ifile))
|
||||
begin
|
||||
@(posedge clk);
|
||||
c = $fgetc(ifile);
|
||||
if (c != -1)
|
||||
begin
|
||||
data_in = c[7:0];
|
||||
crc_en = 1;
|
||||
$display("%c", data_in);
|
||||
end
|
||||
else
|
||||
begin
|
||||
crc_en = 0;
|
||||
end
|
||||
end
|
||||
|
||||
$fclose(ifile);
|
||||
|
||||
#100;
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
96
src/eth/eth_mac.v
Normal file
96
src/eth/eth_mac.v
Normal file
@ -0,0 +1,96 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
`include "src/eth/mac_memory_access_controller.v"
|
||||
`include "src/rmii/rmii_clock_generator.v"
|
||||
`include "src/rmii/rmii_transmit_controller.v"
|
||||
|
||||
module eth_mac #(
|
||||
parameter MAIN_CLK_FREQ = 200,
|
||||
parameter MEM_DATA_WIDTH = 8,
|
||||
parameter MEM_ADDR_WIDTH = 12,
|
||||
|
||||
// AUTOCALCULATED
|
||||
parameter MEM_ADDR_MSB = MEM_ADDR_WIDTH - 1,
|
||||
parameter LEN_WIDTH = 11,
|
||||
parameter LEN_MSB = LEN_WIDTH - 1,
|
||||
parameter CTRL_WORD_WIDTH = 32
|
||||
)(
|
||||
input clk, rst, clear,
|
||||
|
||||
input [MEM_DATA_WIDTH-1:0] mem_data,
|
||||
output [MEM_ADDR_WIDTH-1:0] mem_addr,
|
||||
|
||||
input [CTRL_WORD_WIDTH-1:0] ctrl_word,
|
||||
|
||||
output REF_CLK,
|
||||
output TXEN,
|
||||
output [1:0] TXD
|
||||
|
||||
//input CRS_DV,
|
||||
//input [1:0] RXD
|
||||
);
|
||||
|
||||
wire REF_pulse;
|
||||
|
||||
rmii_clock_generator #(
|
||||
.MAIN_CLK_FREQ(MAIN_CLK_FREQ)
|
||||
) clk_gen (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.REF_CLK(REF_CLK),
|
||||
.rising(REF_pulse)
|
||||
);
|
||||
|
||||
wire tx_wrt;
|
||||
wire tx_not_full;
|
||||
wire transmitter_busy;
|
||||
|
||||
rmii_transmit_controller #(
|
||||
.STORAGE_WIDTH(MEM_DATA_WIDTH)
|
||||
) tx_ctrl (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.clear(clear),
|
||||
|
||||
.REF_pulse(REF_pulse),
|
||||
.data_in(mem_data),
|
||||
.wrt(tx_wrt),
|
||||
.not_full(tx_not_full),
|
||||
.busy(transmitter_busy),
|
||||
|
||||
.TXEN(TXEN),
|
||||
.TXD(TXD)
|
||||
);
|
||||
|
||||
wire [MEM_ADDR_MSB:0] frame_addr = ctrl_word[MEM_ADDR_WIDTH-1:0];
|
||||
wire [LEN_MSB:0] frame_len = ctrl_word[MEM_ADDR_WIDTH + LEN_WIDTH - 1:MEM_ADDR_WIDTH];
|
||||
wire start = ctrl_word[CTRL_WORD_WIDTH - 1];
|
||||
|
||||
wire mem_acc_busy;
|
||||
|
||||
mac_memory_access_controller #(
|
||||
.DATA_WIDTH(MEM_DATA_WIDTH),
|
||||
.ADDR_WIDTH(MEM_ADDR_WIDTH)
|
||||
) mem_acc_ctrl (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.clear(clear),
|
||||
|
||||
.mem_data(mem_data),
|
||||
.mem_addr(mem_addr),
|
||||
|
||||
.transmitter_busy(transmitter_busy),
|
||||
.start(start),
|
||||
.frame_addr(frame_addr),
|
||||
.frame_len(frame_len),
|
||||
|
||||
.busy(mem_acc_busy),
|
||||
.tx_data_in(),
|
||||
.tx_not_full(tx_not_full),
|
||||
.tx_wrt(tx_wrt)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
98
src/eth/mac_memory_access_controller.v
Normal file
98
src/eth/mac_memory_access_controller.v
Normal file
@ -0,0 +1,98 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module mac_memory_access_controller #(
|
||||
parameter DATA_WIDTH = 8,
|
||||
parameter ADDR_WIDTH = 12,
|
||||
|
||||
// AUTOCALCULATED
|
||||
parameter DATA_MSB = DATA_WIDTH - 1,
|
||||
parameter ADDR_MSB = ADDR_WIDTH - 1,
|
||||
parameter LEN_MSB = 10
|
||||
)(
|
||||
input clk, rst, clear, // general signals
|
||||
|
||||
input [DATA_MSB:0] mem_data, // data fetched from the memory
|
||||
output reg [ADDR_MSB:0] mem_addr, // memory address for data fetching
|
||||
|
||||
input transmitter_busy, // indicates that the transmitter is busy with previous transmission
|
||||
input start, // start a new transmission
|
||||
input [ADDR_MSB:0] frame_addr, // starting address of the Ethernet frame
|
||||
input [LEN_MSB:0] frame_len, // length of the Ethernet frame
|
||||
|
||||
output busy, // a frame is currently being processed and transmitted
|
||||
|
||||
output [DATA_MSB:0] tx_data_in, // data input for the transmitter block
|
||||
input tx_not_full, // transmitter block supports storing new blocks of data
|
||||
output tx_wrt // issue a write onto the transmitter block
|
||||
);
|
||||
|
||||
wire rstclr = rst | clear;
|
||||
|
||||
// state machine states
|
||||
localparam IDLE = 0;
|
||||
localparam FETCH_FRAME = 1;
|
||||
localparam WAIT_TX_COMPL = 2;
|
||||
|
||||
// main state machine
|
||||
reg [1:0] state;
|
||||
wire frame_params_valid = frame_len != 0;
|
||||
|
||||
// frame setup and transmission
|
||||
reg [LEN_MSB:0] len_left;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (rstclr)
|
||||
begin
|
||||
len_left <= 0;
|
||||
//tx_wrt <= 0;
|
||||
mem_addr <= 0;
|
||||
len_left <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
case (state)
|
||||
IDLE:
|
||||
begin
|
||||
mem_addr <= frame_addr;
|
||||
len_left <= frame_len - 1;
|
||||
end
|
||||
|
||||
FETCH_FRAME:
|
||||
begin
|
||||
if (len_left != 0)
|
||||
begin
|
||||
//tx_wrt <= 1;
|
||||
|
||||
if (tx_not_full)
|
||||
begin
|
||||
mem_addr <= mem_addr + 1;
|
||||
len_left <= len_left - 1;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
//tx_wrt <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
// next state logic
|
||||
case (state)
|
||||
IDLE: if (start && frame_params_valid) state <= FETCH_FRAME;
|
||||
FETCH_FRAME: if ((len_left == 0) && tx_not_full) state <= WAIT_TX_COMPL;
|
||||
WAIT_TX_COMPL: if (!transmitter_busy) state <= IDLE;
|
||||
default: state <= IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// combinatorial outputs
|
||||
assign busy = (state != IDLE);
|
||||
assign tx_data_in = mem_data;
|
||||
assign tx_wrt = (state == FETCH_FRAME);
|
||||
|
||||
endmodule
|
||||
108
src/fifo.v
Normal file
108
src/fifo.v
Normal file
@ -0,0 +1,108 @@
|
||||
`timescale 1ns / 1ps
|
||||
module fifo #(
|
||||
parameter WIDTH = 8,
|
||||
parameter DEPTH = 8,
|
||||
|
||||
// AUTOCALCULATED
|
||||
parameter STORAGE_MSB = WIDTH - 1,
|
||||
parameter INDEX_MSB = $clog2(DEPTH) - 1
|
||||
)(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
input wire clear,
|
||||
|
||||
input wire [STORAGE_MSB:0] in,
|
||||
input wire push,
|
||||
|
||||
output reg [STORAGE_MSB:0] out,
|
||||
input wire pop,
|
||||
|
||||
output wire empty,
|
||||
output reg out_valid,
|
||||
output wire full
|
||||
);
|
||||
|
||||
// combined clear and reset
|
||||
wire rstclr = rst | clear;
|
||||
|
||||
// inner state
|
||||
reg [STORAGE_MSB:0] mem [DEPTH-1:0]; // buffer
|
||||
reg [INDEX_MSB + 1:0] level; // fill level
|
||||
reg [INDEX_MSB:0] push_idx; // this is where the next data will be pushed
|
||||
reg [INDEX_MSB:0] pop_idx; // this is the index that is going to be popped next
|
||||
|
||||
wire will_pop = pop && !empty; // the FIFO will pop in this cycle
|
||||
wire will_push = push && !full; // the FIFO will store a new item in this cycle
|
||||
|
||||
// push
|
||||
integer i;
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (rstclr)
|
||||
begin
|
||||
for (i = 0; i < DEPTH; i = i + 1)
|
||||
begin
|
||||
mem[i] <= 0;
|
||||
end
|
||||
push_idx <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (will_push)
|
||||
begin
|
||||
mem[push_idx] <= in;
|
||||
push_idx <= push_idx + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// pop
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (rst)
|
||||
begin
|
||||
pop_idx <= 0;
|
||||
out <= 0;
|
||||
out_valid <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (will_pop)
|
||||
begin
|
||||
out <= mem[pop_idx];
|
||||
pop_idx <= pop_idx + 1;
|
||||
out_valid <= 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
out_valid <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// level maintenance
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (rst)
|
||||
begin
|
||||
level <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (will_push && !will_pop)
|
||||
begin
|
||||
level <= level + 1;
|
||||
end
|
||||
|
||||
if (will_pop && !will_push)
|
||||
begin
|
||||
level <= level - 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// state flags
|
||||
assign empty = (level == 0);
|
||||
assign full = (level == DEPTH);
|
||||
|
||||
endmodule
|
||||
45
src/jitmeas_top.v
Normal file
45
src/jitmeas_top.v
Normal file
@ -0,0 +1,45 @@
|
||||
`timescale 1ns / 1ps
|
||||
module jitmeas_top(
|
||||
input wire clk50M, // 50MHz clock input
|
||||
input wire rstbt,
|
||||
|
||||
//output wire clk200M
|
||||
output wire [16:4] aio
|
||||
);
|
||||
|
||||
wire rst = ~rstbt;
|
||||
|
||||
/* Main Clock Generation module */
|
||||
wire main_pll_locked;
|
||||
wire clk200M;
|
||||
|
||||
MainPLL main_pll (
|
||||
// Clock in ports
|
||||
.In_50MHz(clk50M), // IN
|
||||
|
||||
// Clock out ports
|
||||
.Out_200MHz(clk200M), // OUT
|
||||
|
||||
// Status and control signals
|
||||
.RESET(rst), // IN
|
||||
.LOCKED(main_pll_locked) // OUT
|
||||
);
|
||||
|
||||
localparam MAIN_CLK_FREQ = 200; // Main Clock Frequency in MHz
|
||||
|
||||
assign aio[16:5] = 0;
|
||||
|
||||
eth_mac eth_mac_inst (
|
||||
.clk(clk200M),
|
||||
.rst(rst),
|
||||
|
||||
.REF_CLK(REF_CLK),
|
||||
|
||||
//.TXEN(TXEN),
|
||||
//.TXD(TXD),
|
||||
|
||||
.CRS_DV(0),
|
||||
.RXD(0)
|
||||
);
|
||||
|
||||
endmodule
|
||||
37
src/rmii/rmii_clock_generator.v
Normal file
37
src/rmii/rmii_clock_generator.v
Normal file
@ -0,0 +1,37 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module rmii_clock_generator #(
|
||||
parameter MAIN_CLK_FREQ = 200, // frequency of the main clock
|
||||
|
||||
// AUTOCALCULATED
|
||||
parameter CNTR_WIDTH = $clog2(MAIN_CLK_FREQ / 50), // width of the CNTR
|
||||
parameter CNTR_MSB = CNTR_WIDTH - 1 // index of the counter's MSB
|
||||
)(
|
||||
input wire clk, // main clock input
|
||||
input wire rst, // synchronous reset
|
||||
|
||||
output wire REF_CLK, // RMII REF_CLK output
|
||||
output wire rising, // the next clk cycle comes with a rising edge on the REF_CLK
|
||||
output wire falling // ... falling ...
|
||||
);
|
||||
|
||||
reg [CNTR_MSB:0] ref_clk_cntr;
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (rst)
|
||||
begin
|
||||
ref_clk_cntr = 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ref_clk_cntr = ref_clk_cntr + 1;
|
||||
end
|
||||
end
|
||||
|
||||
assign REF_CLK = ref_clk_cntr[CNTR_MSB];
|
||||
assign rising = (&ref_clk_cntr[CNTR_MSB-1:0]) & (~ref_clk_cntr[CNTR_MSB]);
|
||||
assign falling = &ref_clk_cntr;
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
43
src/rmii/rmii_controller.v
Normal file
43
src/rmii/rmii_controller.v
Normal file
@ -0,0 +1,43 @@
|
||||
`timescale 1ns / 1ps
|
||||
module rmii_controller #(
|
||||
parameter MAIN_CLK_FREQ = 200
|
||||
)(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
/* RMII signals */
|
||||
|
||||
// reference clock
|
||||
output wire REF_CLK,
|
||||
|
||||
// transmit signals
|
||||
output wire [1:0] TXD,
|
||||
output wire TXEN,
|
||||
|
||||
// receive signals
|
||||
input wire [1:0] RXD,
|
||||
input wire CRS_DV
|
||||
);
|
||||
|
||||
|
||||
/* RMII Reference Clock Generation state machine */
|
||||
wire ref_clk_rising;
|
||||
wire ref_clk_falling;
|
||||
rmii_clock_generator #(
|
||||
.MAIN_CLK_FREQ(MAIN_CLK_FREQ)
|
||||
) clk_gen (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
.REF_CLK(REF_CLK),
|
||||
.rising(ref_clk_rising),
|
||||
.falling(ref_clk_falling)
|
||||
);
|
||||
|
||||
/* */
|
||||
assign TXD = 0;
|
||||
assign TXEN = 0;
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
61
src/rmii/rmii_serializer.v
Normal file
61
src/rmii/rmii_serializer.v
Normal file
@ -0,0 +1,61 @@
|
||||
`timescale 1ns / 1ps
|
||||
module rmii_serializer #(
|
||||
parameter SHIFT_SIZE = 2,
|
||||
parameter STORE_SIZE = 8,
|
||||
parameter DIR = 0, // 0 -> left; 1 -> right
|
||||
|
||||
// AUTOCALCULATED
|
||||
parameter SHIFT_COUNT = STORE_SIZE / SHIFT_SIZE,
|
||||
parameter SHIFT_COUNT_MSB = $clog2(SHIFT_COUNT) - 1
|
||||
)(
|
||||
input clk, rst, clear, // main clock, reset, clear
|
||||
|
||||
input [STORE_SIZE-1:0] par_in, // parallel input
|
||||
input load, // load parallel data
|
||||
output [SHIFT_SIZE-1:0] ser_out, // serialized output
|
||||
input shift, // enable shifting
|
||||
|
||||
output empty // the inner buffer has depleted
|
||||
);
|
||||
|
||||
// a combine reset or clear signal
|
||||
wire rstclr = rst | clear;
|
||||
|
||||
// shift work register
|
||||
reg [STORE_SIZE-1:0] shift_work;
|
||||
|
||||
// shift count register
|
||||
reg [SHIFT_COUNT_MSB:0] shift_count;
|
||||
|
||||
/* main state machine */
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (rstclr)
|
||||
begin
|
||||
shift_work <= 0;
|
||||
shift_count <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (load) // load the parallel data
|
||||
begin
|
||||
shift_work <= par_in;
|
||||
shift_count <= SHIFT_COUNT - 1; // data must be shifted SHIFT_COUNT - 1 times
|
||||
end
|
||||
else if (shift)
|
||||
begin
|
||||
if (shift_count > 0)
|
||||
begin
|
||||
shift_count <= shift_count - 1; // decrease shift count
|
||||
shift_work <= DIR ? (shift_work >> SHIFT_SIZE) : (shift_work << SHIFT_SIZE); // shift the contents of the work register
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// output logic
|
||||
assign empty = (shift_count == 0); // indication for depletion
|
||||
assign ser_out = DIR ? shift_work[SHIFT_SIZE-1:0] : shift_work[STORE_SIZE-1:STORE_SIZE-SHIFT_SIZE]; // serial output
|
||||
|
||||
endmodule
|
||||
99
src/rmii/rmii_transmit_controller.v
Normal file
99
src/rmii/rmii_transmit_controller.v
Normal file
@ -0,0 +1,99 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
`include "src/fifo.v"
|
||||
`include "src/rmii/rmii_serializer.v"
|
||||
|
||||
module rmii_transmit_controller #(
|
||||
parameter FIFO_DEPTH = 16,
|
||||
parameter STORAGE_WIDTH = 8,
|
||||
|
||||
// AUTOCALCULATED
|
||||
parameter STORAGE_MSB = STORAGE_WIDTH - 1,
|
||||
parameter SHIFT_COUNT = FIFO_DEPTH
|
||||
)(
|
||||
input clk, rst, clear, // general signals
|
||||
input REF_pulse, // pulse that signals the coming rising edge on REF_CLK
|
||||
|
||||
/* FIFO signals */
|
||||
input [STORAGE_MSB:0] data_in, // input data
|
||||
input wrt, // store the data
|
||||
output not_full, // the internal buffer is not full
|
||||
|
||||
/* RMII signals */
|
||||
output reg TXEN, // transmit enable
|
||||
output [1:0] TXD, // transmit data
|
||||
|
||||
output busy // there's an ongoing transmission
|
||||
);
|
||||
|
||||
/* TX FIFO and its signals */
|
||||
wire tx_fifo_empty;
|
||||
wire tx_fifo_out_valid;
|
||||
wire tx_fifo_full;
|
||||
wire [STORAGE_WIDTH-1:0]tx_fifo_out;
|
||||
wire tx_fifo_pop = oser_empty && REF_pulse;
|
||||
|
||||
fifo #(
|
||||
.DEPTH(FIFO_DEPTH),
|
||||
.WIDTH(STORAGE_WIDTH)
|
||||
) tx_fifo (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.clear(clear),
|
||||
|
||||
.empty(tx_fifo_empty),
|
||||
.out_valid(tx_fifo_out_valid),
|
||||
.full(tx_fifo_full),
|
||||
|
||||
.in(data_in),
|
||||
.push(wrt),
|
||||
|
||||
.out(tx_fifo_out),
|
||||
.pop(tx_fifo_pop)
|
||||
);
|
||||
|
||||
assign not_full = !tx_fifo_full;
|
||||
|
||||
/* output serializer */
|
||||
|
||||
wire oser_load = tx_fifo_out_valid;
|
||||
wire oser_empty;
|
||||
|
||||
rmii_serializer #(
|
||||
.STORE_SIZE(STORAGE_WIDTH),
|
||||
.DIR(0) // LEFT
|
||||
) out_serializer (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.clear(clear),
|
||||
|
||||
.par_in(tx_fifo_out),
|
||||
.ser_out(TXD),
|
||||
.load(oser_load),
|
||||
.shift(REF_pulse),
|
||||
.empty(oser_empty)
|
||||
);
|
||||
|
||||
/* TXEN control */
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (rst | clear)
|
||||
begin
|
||||
TXEN <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (oser_load) // assert the same time the shift register loading occurs
|
||||
begin
|
||||
TXEN <= 1;
|
||||
end
|
||||
else if (REF_pulse && oser_empty && tx_fifo_empty) // deassert only when all buffers has depleted
|
||||
begin
|
||||
TXEN <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign busy = TXEN;
|
||||
|
||||
endmodule
|
||||
1
src/sim/eth_frame_mem.mem
Normal file
1
src/sim/eth_frame_mem.mem
Normal file
@ -0,0 +1 @@
|
||||
4C 6F 72 65 6D 20 69 70 73 75 6D 20 64 6F 6C 6F 72 20 73 69 74 20 61 6D 65 74
|
||||
98
src/sim/eth_mac_test.v
Normal file
98
src/sim/eth_mac_test.v
Normal file
@ -0,0 +1,98 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
`include "src/eth/eth_mac.v"
|
||||
|
||||
module eth_mac_test;
|
||||
|
||||
// Inputs
|
||||
reg clk;
|
||||
reg rst;
|
||||
reg clear;
|
||||
wire [7:0] mem_data;
|
||||
reg [31:0] ctrl_word;
|
||||
|
||||
// Outputs
|
||||
wire [11:0] mem_addr;
|
||||
wire REF_CLK;
|
||||
wire TXEN;
|
||||
wire [1:0] TXD;
|
||||
|
||||
// Instantiate the Unit Under Test (UUT)
|
||||
eth_mac uut (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.clear(clear),
|
||||
.mem_data(mem_data),
|
||||
.mem_addr(mem_addr),
|
||||
.ctrl_word(ctrl_word),
|
||||
.REF_CLK(REF_CLK),
|
||||
.TXEN(TXEN),
|
||||
.TXD(TXD)
|
||||
);
|
||||
|
||||
always #2.5 clk <= ~clk;
|
||||
reg run;
|
||||
|
||||
// memory
|
||||
localparam MEM_SIZE = 26;
|
||||
reg [7:0] mem [0:MEM_SIZE-1];
|
||||
assign mem_data = mem[mem_addr];
|
||||
|
||||
// frame data
|
||||
localparam FRAME_ADDR = 0;
|
||||
localparam FRAME_LENGTH = 26;
|
||||
localparam START = (1 << 31);
|
||||
|
||||
// RMII deserializer
|
||||
integer wrt_cntr;
|
||||
reg [7:0] deser;
|
||||
always @(posedge REF_CLK)
|
||||
begin
|
||||
if (TXEN && run)
|
||||
begin
|
||||
deser = {deser[5:0], TXD};
|
||||
wrt_cntr = wrt_cntr + 1;
|
||||
if ((wrt_cntr & 32'b11) == 0)
|
||||
begin
|
||||
//$fwrite(ofile, "%c", deser);
|
||||
$display("%c", deser);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
// Initialize Inputs
|
||||
clk <= 0;
|
||||
rst <= 1;
|
||||
clear <= 0;
|
||||
ctrl_word <= 0;
|
||||
|
||||
deser = 0;
|
||||
wrt_cntr = 0;
|
||||
run <= 0;
|
||||
|
||||
// populate memory
|
||||
$readmemh("src/sim/eth_frame_mem.mem", mem);
|
||||
|
||||
// Wait 20 ns for global reset to finish
|
||||
#20;
|
||||
rst <= 0;
|
||||
|
||||
// Add stimulus here
|
||||
#20;
|
||||
@(posedge clk);
|
||||
|
||||
ctrl_word <= START | (FRAME_LENGTH << 12) | (FRAME_ADDR);
|
||||
run <= 1;
|
||||
|
||||
@(TXEN == 1);
|
||||
|
||||
@(TXEN == 0);
|
||||
|
||||
#20;
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
121
src/sim/fifo_test.v
Normal file
121
src/sim/fifo_test.v
Normal file
@ -0,0 +1,121 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
`include "src/fifo.v"
|
||||
|
||||
module fifo_test;
|
||||
// Inputs
|
||||
reg clk;
|
||||
reg rst;
|
||||
reg clear;
|
||||
reg [7:0] in;
|
||||
reg push;
|
||||
reg pop;
|
||||
|
||||
// Outputs
|
||||
wire [7:0] out;
|
||||
wire empty;
|
||||
wire out_valid;
|
||||
wire full;
|
||||
|
||||
// Instantiate the Unit Under Test (UUT)
|
||||
fifo uut (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.clear(clear),
|
||||
.in(in),
|
||||
.push(push),
|
||||
.out(out),
|
||||
.pop(pop),
|
||||
.empty(empty),
|
||||
.out_valid(out_valid),
|
||||
.full(full)
|
||||
);
|
||||
|
||||
always #10 clk = ~clk;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (c >= 0 && !rst)
|
||||
begin
|
||||
pop <= $random & 1'b1;
|
||||
push <= $random & 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
push <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (out_valid)
|
||||
begin
|
||||
$display("%c", out);
|
||||
//$fdisplay(ofile, "%c", out);
|
||||
$fwrite(ofile, "%c", out);
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if ((!full && push) || start)
|
||||
begin
|
||||
c = $fgetc(ifile);
|
||||
if (c != -1)
|
||||
begin
|
||||
in <= c[7:0];
|
||||
end
|
||||
end
|
||||
start <= 0;
|
||||
end
|
||||
|
||||
integer ifile, ofile, c;
|
||||
reg start;
|
||||
|
||||
initial begin
|
||||
// Initialize Inputs
|
||||
clk <= 0;
|
||||
rst <= 1;
|
||||
clear <= 0;
|
||||
in <= 0;
|
||||
pop <= 0;
|
||||
push <= 0;
|
||||
|
||||
c = 0;
|
||||
start <= 0;
|
||||
|
||||
// Wait 20ns for global reset to finish
|
||||
#20;
|
||||
rst <= 0;
|
||||
|
||||
// Add stimulus here
|
||||
|
||||
// open file holding the test input
|
||||
ifile = $fopen("src/sim/lorem_ipsum.txt", "r");
|
||||
ofile = $fopen("src/sim/fifo_out.txt", "w");
|
||||
if ((ifile == 0) || (ofile == 0))
|
||||
begin
|
||||
$display("Error on opening at least one of the files!\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
// start simulation
|
||||
start <= 1;
|
||||
|
||||
// wait until EOF is reached
|
||||
@(c == -1);
|
||||
|
||||
// wait for FIFO depletion
|
||||
if (!empty)
|
||||
begin
|
||||
@(posedge empty);
|
||||
end
|
||||
|
||||
$fclose(ifile);
|
||||
$fclose(ofile);
|
||||
$finish;
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
1
src/sim/lorem_ipsum.txt
Normal file
1
src/sim/lorem_ipsum.txt
Normal file
@ -0,0 +1 @@
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
1
src/sim/lorem_rovid.txt
Normal file
1
src/sim/lorem_rovid.txt
Normal file
@ -0,0 +1 @@
|
||||
Lorem ipsum dolor sit amet
|
||||
39
src/sim/rmii_ctrl_test.v
Normal file
39
src/sim/rmii_ctrl_test.v
Normal file
@ -0,0 +1,39 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module rmii_ctrl_test;
|
||||
|
||||
// Inputs
|
||||
reg clk;
|
||||
reg rst;
|
||||
|
||||
// Outputs
|
||||
wire REF_CLK;
|
||||
wire [1:0] TXD;
|
||||
wire TXEN;
|
||||
|
||||
// Instantiate the Unit Under Test (UUT)
|
||||
rmii_controller uut (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.REF_CLK(REF_CLK),
|
||||
.TXD(TXD),
|
||||
.TXEN(TXEN)
|
||||
);
|
||||
|
||||
always #2.5 clk = ~clk;
|
||||
|
||||
initial begin
|
||||
// input initialization
|
||||
clk = 0;
|
||||
rst = 1;
|
||||
|
||||
// global reset
|
||||
#5;
|
||||
|
||||
// stimulus
|
||||
rst = 0;
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
133
src/sim/rmii_transmit_controller_test.v
Normal file
133
src/sim/rmii_transmit_controller_test.v
Normal file
@ -0,0 +1,133 @@
|
||||
`timescale 1ns / 500ps
|
||||
|
||||
module rmii_transmit_controller_test;
|
||||
|
||||
// Inputs
|
||||
reg clk;
|
||||
reg rst;
|
||||
reg clear;
|
||||
reg [7:0] data_in;
|
||||
reg wrt;
|
||||
wire REF_pulse;
|
||||
wire REF_CLK;
|
||||
wire REF_negpulse;
|
||||
|
||||
// Outputs
|
||||
wire not_full;
|
||||
wire TXEN;
|
||||
wire [1:0] TXD;
|
||||
|
||||
// Instantiate the Unit Under Test (UUT)
|
||||
rmii_transmit_controller uut (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.clear(clear),
|
||||
.data_in(data_in),
|
||||
.wrt(wrt),
|
||||
.not_full(not_full),
|
||||
.REF_pulse(REF_pulse),
|
||||
.TXEN(TXEN),
|
||||
.TXD(TXD)
|
||||
);
|
||||
|
||||
always #2.5 clk = ~clk;
|
||||
|
||||
rmii_clock_generator clk_gen(
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
.REF_CLK(REF_CLK),
|
||||
.rising(REF_pulse),
|
||||
.falling(REF_negpulse)
|
||||
);
|
||||
|
||||
integer ifile = 0, ofile = 0;
|
||||
reg run;
|
||||
reg read_input;
|
||||
integer c;
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (read_input)
|
||||
begin
|
||||
if (not_full)
|
||||
begin
|
||||
c = $fgetc(ifile);
|
||||
if (c != -1)
|
||||
begin
|
||||
data_in <= c[7:0];
|
||||
wrt <= 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
read_input <= 0;
|
||||
wrt <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
integer wrt_cntr;
|
||||
reg [7:0] deser;
|
||||
always @(posedge REF_pulse)
|
||||
begin
|
||||
if (TXEN && run)
|
||||
begin
|
||||
deser = {deser[5:0], TXD};
|
||||
wrt_cntr = wrt_cntr + 1;
|
||||
if ((wrt_cntr & 32'b11) == 0)
|
||||
begin
|
||||
$fwrite(ofile, "%c", deser);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
// Initialize Inputs
|
||||
clk <= 0;
|
||||
rst <= 1;
|
||||
clear <= 0;
|
||||
data_in <= 0;
|
||||
wrt <= 0;
|
||||
|
||||
run <= 0;
|
||||
c = 0;
|
||||
wrt_cntr = 0;
|
||||
deser = 0;
|
||||
wrt <= 0;
|
||||
read_input <= 0;
|
||||
|
||||
// Wait 20 ns for global reset to finish
|
||||
#20;
|
||||
rst <= 0;
|
||||
|
||||
// Add stimulus here
|
||||
|
||||
// open file holding the test input
|
||||
ifile = $fopen("src/sim/lorem_ipsum.txt", "r");
|
||||
ofile = $fopen("src/sim/rmii_TXD.txt", "w");
|
||||
if ((ifile == 0) || (ofile == 0))
|
||||
begin
|
||||
$display("Error on opening at least one of the files!\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
// start simulation
|
||||
run <= 1;
|
||||
read_input <= 1;
|
||||
|
||||
// wait for the deassertion of run
|
||||
@(TXEN == 1);
|
||||
@(TXEN == 0);
|
||||
run <= 0;
|
||||
|
||||
@(posedge REF_CLK);
|
||||
@(posedge REF_CLK);
|
||||
|
||||
$fclose(ifile);
|
||||
$fclose(ofile);
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
34
src/sim/top_sim.v
Normal file
34
src/sim/top_sim.v
Normal file
@ -0,0 +1,34 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module top_sim;
|
||||
|
||||
// Inputs
|
||||
reg clk50M;
|
||||
reg rstbt;
|
||||
|
||||
// Outputs
|
||||
wire [16:4] aio;
|
||||
|
||||
// Instantiate the Unit Under Test (UUT)
|
||||
jitmeas_top uut (
|
||||
.clk50M(clk50M),
|
||||
.rstbt(rstbt),
|
||||
.aio(aio)
|
||||
);
|
||||
|
||||
always #10 clk50M = ~clk50M;
|
||||
|
||||
initial begin
|
||||
// Initialize Inputs
|
||||
clk50M = 0;
|
||||
rstbt = 1;
|
||||
|
||||
// Wait 100 ns for global reset to finish
|
||||
#20;
|
||||
|
||||
// Add stimulus here
|
||||
rstbt = 0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user