From cacbcb6fcfea866319b6571dd541aae709cd106d Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 23 Jan 2024 16:16:29 -0600 Subject: [PATCH 01/95] Created the basic synthesizable wally tracer for fpga. --- src/wally/rvvisynth.sv | 72 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/wally/rvvisynth.sv diff --git a/src/wally/rvvisynth.sv b/src/wally/rvvisynth.sv new file mode 100644 index 000000000..457cf05e2 --- /dev/null +++ b/src/wally/rvvisynth.sv @@ -0,0 +1,72 @@ +/////////////////////////////////////////// +// rvvisynth.sv +// +// Written: Rose Thompson ross1728@gmail.com +// Created: 23 January 2024 +// Modified: 23 January 2024 +// +// Purpose: Synthesizable rvvi bridge from Wally to generic compressed format. +// +// Documentation: +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module rvvisynth import cvw::*; #(parameter cvw_t P, + parameter integer MAX_CSR)( + input logic clk, reset, + output logic valid, + output logic [163+P.XLEN-1:0] Requied, + output logic [12+2*P.XLEN-1:0] Registers, + output logic [12+MAX_CSR*(P.XLEN+12)-1:0] CSRs + ); + + logic [P.XLEN-1:0] PCM, PCW; + logic StallW, FlushW; + logic InstrValidM, InstrValidW; + logic [31:0] InstrRawD, InstrRawE, InstrRawM, InstrRawW; + logic [63:0] Mcycle, Minstret; + logic TrapM, TrapW; + logic [1:0] PrivilegeModeW; + + // get signals from the core. + assign StallW = testbench.dut.core.StallW; + assign FlushW = testbench.dut.core.FlushW; + assign InstrValidM = testbench.dut.core.ieu.InstrValidM; + assign InstrRawD = testbench.dut.core.ifu.InstrRawD; + assign PCM = testbench.dut.core.ifu.PCM; + assign Mcycle = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; + assign Minstret = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; + assign TrapM = testbench.dut.core.TrapM; + assign PrivilegeModeW = testbench.dut.core.priv.priv.privmode.PrivilegeModeW; + + // start out easy and just populate Required + // PC, inst, mcycle, minstret, trap, mode + + flopenrc #(1) InstrValidMReg (clk, reset, FlushW, ~StallW, InstrValidM, InstrValidW); + flopenrc #(P.XLEN) PCWReg (clk, reset, FlushW, ~StallW, PCM, PCW); + flopenrc #(32) InstrRawEReg (clk, reset, FlushE, ~StallE, InstrRawD, InstrRawE); + flopenrc #(32) InstrRawMReg (clk, reset, FlushM, ~StallM, InstrRawE, InstrRawM); + flopenrc #(32) InstrRawWReg (clk, reset, FlushW, ~StallW, InstrRawM, InstrRawW); + flopenrc #(1) TrapWReg (clk, reset, 1'b0, ~StallW, TrapM, TrapW); + + assign valid = InstrValidW & ~StallW; + assign Required = {PrivilegeModeW, TrapW, Minstret, Mcycle, InstrRawW, PCW}; + +endmodule + From 0babb011c2f51b1849876b4458e00dc489a05f24 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 23 Jan 2024 16:27:50 -0600 Subject: [PATCH 02/95] Synthesizable rvvi tracer output G/FPRs. --- src/wally/rvvisynth.sv | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/wally/rvvisynth.sv b/src/wally/rvvisynth.sv index 457cf05e2..2d894696d 100644 --- a/src/wally/rvvisynth.sv +++ b/src/wally/rvvisynth.sv @@ -36,13 +36,20 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, output logic [12+MAX_CSR*(P.XLEN+12)-1:0] CSRs ); - logic [P.XLEN-1:0] PCM, PCW; + // pipeline controlls logic StallW, FlushW; + // required + logic [P.XLEN-1:0] PCM, PCW; logic InstrValidM, InstrValidW; logic [31:0] InstrRawD, InstrRawE, InstrRawM, InstrRawW; logic [63:0] Mcycle, Minstret; logic TrapM, TrapW; logic [1:0] PrivilegeModeW; + // registers gpr and fpr + logic GPRWen, FPRWen; + logic [4:0] GPRAddr, FPRAddr; + logic [P.XLEN-1:0] GPRValue, FPRValue; + logic [P.XLEN-1:0] XLENZeros; // get signals from the core. assign StallW = testbench.dut.core.StallW; @@ -50,23 +57,37 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, assign InstrValidM = testbench.dut.core.ieu.InstrValidM; assign InstrRawD = testbench.dut.core.ifu.InstrRawD; assign PCM = testbench.dut.core.ifu.PCM; - assign Mcycle = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; - assign Minstret = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; + assign Mcycle = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; + assign Minstret = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; assign TrapM = testbench.dut.core.TrapM; assign PrivilegeModeW = testbench.dut.core.priv.priv.privmode.PrivilegeModeW; + assign GPRAddr = testbench.dut.core.ieu.dp.regf.a3; + assign GPRWen = testbench.dut.core.ieu.dp.regf.we3; + assign GPRValue = testbench.dut.core.ieu.dp.regf.wd3; + assign FPRAddr = testbench.dut.core.fpu.fpu.fregfile.a4; + assign FPRWen = testbench.dut.core.fpu.fpu.fregfile.we4; + assign FPRValue = testbench.dut.core.fpu.fpu.fregfile.wd4; + + + // + assign XLENZeros = '0; // start out easy and just populate Required // PC, inst, mcycle, minstret, trap, mode - flopenrc #(1) InstrValidMReg (clk, reset, FlushW, ~StallW, InstrValidM, InstrValidW); + flopenrc #(1) InstrValidMReg (clk, reset, FlushW, ~StallW, InstrValidM, InstrValidW); flopenrc #(P.XLEN) PCWReg (clk, reset, FlushW, ~StallW, PCM, PCW); - flopenrc #(32) InstrRawEReg (clk, reset, FlushE, ~StallE, InstrRawD, InstrRawE); - flopenrc #(32) InstrRawMReg (clk, reset, FlushM, ~StallM, InstrRawE, InstrRawM); - flopenrc #(32) InstrRawWReg (clk, reset, FlushW, ~StallW, InstrRawM, InstrRawW); - flopenrc #(1) TrapWReg (clk, reset, 1'b0, ~StallW, TrapM, TrapW); + flopenrc #(32) InstrRawEReg (clk, reset, FlushE, ~StallE, InstrRawD, InstrRawE); + flopenrc #(32) InstrRawMReg (clk, reset, FlushM, ~StallM, InstrRawE, InstrRawM); + flopenrc #(32) InstrRawWReg (clk, reset, FlushW, ~StallW, InstrRawM, InstrRawW); + flopenrc #(1) TrapWReg (clk, reset, 1'b0, ~StallW, TrapM, TrapW); assign valid = InstrValidW & ~StallW; assign Required = {PrivilegeModeW, TrapW, Minstret, Mcycle, InstrRawW, PCW}; - + assign Registers = {FPRWen, GPRWen} == 2'b11 ? {FPRValue, FPRAddr, GPRValue, GPRAddr, FPRWen, GPRWen} : + {FPRWen, GPRWen} == 2'b01 ? {XLENZeros, 5'b0, GPRValue, GPRAddr, FPRWen, GPRWen} : + {FPRWen, GPRWen} == 2'b10 ? {FPRValue, FPRAddr, XLENZeros, 5'b0, FPRWen, GPRWen} : + {XLENZeros, 5'b0, XLENZeros, 5'b0, FPRWen, GPRWen}; + endmodule From fd032a7e106cfe2022b5afb6d1d8e7f467256603 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Wed, 24 Jan 2024 15:06:13 -0600 Subject: [PATCH 03/95] Draft implementation of synth rvvi. --- src/wally/csrindextoaddr.sv | 77 ++++++++++++++++++++++++++++++++++++ src/wally/priorityaomux.sv | 47 ++++++++++++++++++++++ src/wally/regchangedetect.sv | 41 +++++++++++++++++++ src/wally/rvvisynth.sv | 73 ++++++++++++++++++++++++++++++++-- 4 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 src/wally/csrindextoaddr.sv create mode 100644 src/wally/priorityaomux.sv create mode 100644 src/wally/regchangedetect.sv diff --git a/src/wally/csrindextoaddr.sv b/src/wally/csrindextoaddr.sv new file mode 100644 index 000000000..e06508bdf --- /dev/null +++ b/src/wally/csrindextoaddr.sv @@ -0,0 +1,77 @@ +/////////////////////////////////////////// +// csrindextoaddr.sv +// +// Written: Rose Thompson ross1728@gmail.com +// Created: 24 January 2024 +// Modified: 24 January 2024 +// +// Purpose: Converts the rvvi CSR index into the CSR address +// +// Documentation: +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module csrindextoaddr #(parameter NUM_CSRS = 36) ( + input logic [ROWS-1:0] CSRWen, + output logic [11:0] CSRAddr); + + always_comb begin + case(CSRWen) begin + 36'h0_0000_0000: CSRAddr = 13'h000; + 36'h0_0000_0001: CSRAddr = 13'h300; + 36'h0_0000_0002: CSRAddr = 13'h310; + 36'h0_0000_0004: CSRAddr = 13'h305; + 36'h0_0000_0008: CSRAddr = 13'h341; + 36'h0_0000_0010: CSRAddr = 13'h306; + 36'h0_0000_0020: CSRAddr = 13'h320; + 36'h0_0000_0040: CSRAddr = 13'h302; + 36'h0_0000_0080: CSRAddr = 13'h303; + 36'h0_0000_0100: CSRAddr = 13'h344; + 36'h0_0000_0200: CSRAddr = 13'h304; + 36'h0_0000_0400: CSRAddr = 13'h301; + 36'h0_0000_0800: CSRAddr = 13'h30A; + 36'h0_0000_1000: CSRAddr = 13'hF14; + 36'h0_0000_2000: CSRAddr = 13'h340; + 36'h0_0000_4000: CSRAddr = 13'h342; + 36'h0_0000_8000: CSRAddr = 13'h343; + 36'h0_0001_0000: CSRAddr = 13'hF11; + 36'h0_0002_0000: CSRAddr = 13'hF12; + 36'h0_0004_0000: CSRAddr = 13'hF13; + 36'h0_0008_0000: CSRAddr = 13'hF15; + 36'h0_0010_0000: CSRAddr = 13'h34A; + 36'h0_0020_0000: CSRAddr = 13'h100; + 36'h0_0040_0000: CSRAddr = 13'h104; + 36'h0_0080_0000: CSRAddr = 13'h105; + 36'h0_0100_0000: CSRAddr = 13'h141; + 36'h0_0200_0000: CSRAddr = 13'h106; + 36'h0_0400_0000: CSRAddr = 13'h10A; + 36'h0_0800_0000: CSRAddr = 13'h180; + 36'h0_1000_0000: CSRAddr = 13'h140; + 36'h0_2000_0000: CSRAddr = 13'h143; + 36'h0_4000_0000: CSRAddr = 13'h142; + 36'h0_8000_0000: CSRAddr = 13'h144; + 36'h1_0000_0000: CSRAddr = 13'h14D; + 36'h2_0000_0000: CSRAddr = 13'h001; + 36'h4_0000_0000: CSRAddr = 13'h002; + 36'h8_0000_0000: CSRAddr = 13'h003; + default : CSRAddr = 13'h000; + end + end +endmodule + diff --git a/src/wally/priorityaomux.sv b/src/wally/priorityaomux.sv new file mode 100644 index 000000000..c99b0e1ed --- /dev/null +++ b/src/wally/priorityaomux.sv @@ -0,0 +1,47 @@ +/////////////////////////////////////////// +// priorityaomux.sv +// +// Written: Rose Thompson ross1728@gmail.com +// Created: 24 January 2024 +// Modified: 24 January 2024 +// +// Purpose: priority AND-OR MUX. +// +// Documentation: +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module priorityaomux #(parameter ROWS = 8, COLS = 64) ( + input logic [ROWS-1:0] Sel, + input var logic [COLS-1:0] A [ROWS-1:0], + output logic [COLS-1:0] Y, + output logic [ROWS-1:0] SelPriority); + + logic [ROWS-1:0] SelPriority; + logic [COLS-1:0] AMasked [ROWS-1:0]; + genvar index; + + priorityonehot #(ROWS) priorityonehot(Sel, SelPriority); + for(index = 0; index < ROWS; index = index + 1) begin + assign AMasked[index] = SelPriority[index] ? A[index] : '0; + end + or_rows #(ROWS, COLS) or_rows(AMasked, Y); + +endmodule + diff --git a/src/wally/regchangedetect.sv b/src/wally/regchangedetect.sv new file mode 100644 index 000000000..8becf867d --- /dev/null +++ b/src/wally/regchangedetect.sv @@ -0,0 +1,41 @@ +/////////////////////////////////////////// +// regchangedetect.sv +// +// Written: Rose Thompson ross1728@gmail.com +// Created: 24 January 2024 +// Modified: 24 January 2024 +// +// Purpose: +// +// Documentation: +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module regchangedetect #(parameter XLEN = 64) ( + input clk, reset, + input logic [XLEN-1:0] Value, + output logic Change); + + logic [XLEN-1:0] ValueD; + + flopr #(XLEN) register(clk, reset, Value, ValueD); + assign Change = |(Value ^ ValueD); + +endmodule + diff --git a/src/wally/rvvisynth.sv b/src/wally/rvvisynth.sv index 2d894696d..019000915 100644 --- a/src/wally/rvvisynth.sv +++ b/src/wally/rvvisynth.sv @@ -28,14 +28,16 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module rvvisynth import cvw::*; #(parameter cvw_t P, - parameter integer MAX_CSR)( + parameter integer MAX_CSRS)( input logic clk, reset, output logic valid, output logic [163+P.XLEN-1:0] Requied, output logic [12+2*P.XLEN-1:0] Registers, - output logic [12+MAX_CSR*(P.XLEN+12)-1:0] CSRs + output logic [12+MAX_CSRS*(P.XLEN+12)-1:0] CSRs ); + localparam TOTAL_CSRS = 36; + // pipeline controlls logic StallW, FlushW; // required @@ -50,7 +52,12 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, logic [4:0] GPRAddr, FPRAddr; logic [P.XLEN-1:0] GPRValue, FPRValue; logic [P.XLEN-1:0] XLENZeros; - + logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0]; + logic [TOTAL_CSRS-1:0] CSRArrayWen; + logic [MAX_CSRS-1:0] CSRValue [P.XLEN-1:0]; + logic [MAX_CSRS-1:0] CSRWen [TOTAL_CSRS-1:0]; + logic [MAX_CSRS-1:0] CSRAddr [11:0]; + // get signals from the core. assign StallW = testbench.dut.core.StallW; assign FlushW = testbench.dut.core.FlushW; @@ -68,6 +75,44 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, assign FPRWen = testbench.dut.core.fpu.fpu.fregfile.we4; assign FPRValue = testbench.dut.core.fpu.fpu.fregfile.wd4; + assign CSRArray[0] = testbench.dut.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 + assign CSRArray[1] = testbench.dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 + assign CSRArray[2] = testbench.dut.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 + assign CSRArray[3] = testbench.dut.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 + assign CSRArray[4] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 + assign CSRArray[5] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 + assign CSRArray[6] = testbench.dut.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 + assign CSRArray[7] = testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 + assign CSRArray[8] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 + assign CSRArray[9] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 + assign CSRArray[10] = testbench.dut.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 + assign CSRArray[11] = testbench.dut.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A + assign CSRArray[12] = testbench.dut.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 + assign CSRArray[13] = testbench.dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 + assign CSRArray[14] = testbench.dut.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 + assign CSRArray[15] = testbench.dut.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 + assign CSRArray[16] = 0; // 12'hF11 + assign CSRArray[17] = 0; // 12'hF12 + assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 + assign CSRArray[19] = 0; // 12'hF15 + assign CSRArray[20] = 0; // 12'h34A + // supervisor CSRs + assign CSRArray[21] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 + assign CSRArray[22] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 + assign CSRArray[23] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 + assign CSRArray[24] = testbench.dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 + assign CSRArray[25] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 + assign CSRArray[26] = testbench.dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A + assign CSRArray[27] = testbench.dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 + assign CSRArray[28] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 + assign CSRArray[29] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 + assign CSRArray[30] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 + assign CSRArray[31] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 + assign CSRArray[32] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D + // user CSRs + assign CSRArray[33] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 + assign CSRArray[34] = testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 + assign CSRArray[35] = {testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 // assign XLENZeros = '0; @@ -89,5 +134,27 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, {FPRWen, GPRWen} == 2'b10 ? {FPRValue, FPRAddr, XLENZeros, 5'b0, FPRWen, GPRWen} : {XLENZeros, 5'b0, XLENZeros, 5'b0, FPRWen, GPRWen}; + // the CSRs are complex + // 1. we need to get the CSR values + // 2. we check if the CSR value changes by registering the value then XORing with the old value. + // 3. Then use priorityaomux to collect CSR values and addresses for compating into the compressed rvvi format + + // step 2 + genvar index; + for (index = 0; index < TOTAL_CSRS; index = index + 1) begin + regchangedetect #(P.XLEN) changedetect(clk, reset, CSRArray[index], CSRArrayWen[index]); + end + + // step 3a + for(index = 0; index < MAX_CSRS; index = index + 1) begin + logic [NUM_CSRS-index-1:0] CSRWenShort; + priorityaomux #(NUM_CSRS-index, P.XLEN) priorityaomux(CSRArrayWen[MAX_CSRS-1:index], CSRArray[MAX_CSRS-1:index], CSRValue[index], CSRWenShort); + assign CSRWen[index] = {{{index}{1'b0}}, CSRWenShort}; + // step 3b + csrindextoaddr #(NUM_CSRS) csrindextoaddr(CSRWen, CSRAddr); + assign CSRs[(index+1) * P.XLEN - 1 + 12 + 12: index * P.XLEN + 12] = {CSRValue[index], CSRAddr[index]}; + end + + endmodule From 29db2cd931e95e4d429941d03404858c66f5ce56 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 8 Mar 2024 12:38:27 -0600 Subject: [PATCH 04/95] Basic hardware tracer works! Next step is to package the buses into packets to ethernet transmission. --- sim/wave.do | 186 ++++++++++++++++++++------------- src/wally/csrindextoaddr.sv | 8 +- src/wally/priorityaomux.sv | 1 - src/wally/rvvisynth.sv | 21 ++-- src/wally/wallypipelinedsoc.sv | 8 ++ 5 files changed, 134 insertions(+), 90 deletions(-) diff --git a/sim/wave.do b/sim/wave.do index 8717f667d..41cb4ba42 100644 --- a/sim/wave.do +++ b/sim/wave.do @@ -1,48 +1,68 @@ onerror {resume} quietly virtual signal -install /testbench/dut/core/ifu/bpred/bpred { /testbench/dut/core/ifu/bpred/bpred/PostSpillInstrRawF[11:7]} rd +quietly virtual function -install /testbench/dut/rvvisynth -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/rvvisynth/CSRs[11], /testbench/dut/rvvisynth/CSRs[10], /testbench/dut/rvvisynth/CSRs[9], /testbench/dut/rvvisynth/CSRs[8], /testbench/dut/rvvisynth/CSRs[7], /testbench/dut/rvvisynth/CSRs[6], /testbench/dut/rvvisynth/CSRs[5], /testbench/dut/rvvisynth/CSRs[4], /testbench/dut/rvvisynth/CSRs[3], /testbench/dut/rvvisynth/CSRs[2], /testbench/dut/rvvisynth/CSRs[1], /testbench/dut/rvvisynth/CSRs[0] }} NumCSRs +quietly virtual function -install /testbench/dut/rvvisynth -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/rvvisynth/CSRs[23], /testbench/dut/rvvisynth/CSRs[22], /testbench/dut/rvvisynth/CSRs[21], /testbench/dut/rvvisynth/CSRs[20], /testbench/dut/rvvisynth/CSRs[19], /testbench/dut/rvvisynth/CSRs[18], /testbench/dut/rvvisynth/CSRs[17], /testbench/dut/rvvisynth/CSRs[16], /testbench/dut/rvvisynth/CSRs[15], /testbench/dut/rvvisynth/CSRs[14], /testbench/dut/rvvisynth/CSRs[13], /testbench/dut/rvvisynth/CSRs[12] }} CSRAdr0 +quietly virtual function -install /testbench/dut/rvvisynth -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/rvvisynth/CSRs[87], /testbench/dut/rvvisynth/CSRs[86], /testbench/dut/rvvisynth/CSRs[85], /testbench/dut/rvvisynth/CSRs[84], /testbench/dut/rvvisynth/CSRs[83], /testbench/dut/rvvisynth/CSRs[82], /testbench/dut/rvvisynth/CSRs[81], /testbench/dut/rvvisynth/CSRs[80], /testbench/dut/rvvisynth/CSRs[79], /testbench/dut/rvvisynth/CSRs[78], /testbench/dut/rvvisynth/CSRs[77], /testbench/dut/rvvisynth/CSRs[76], /testbench/dut/rvvisynth/CSRs[75], /testbench/dut/rvvisynth/CSRs[74], /testbench/dut/rvvisynth/CSRs[73], /testbench/dut/rvvisynth/CSRs[72], /testbench/dut/rvvisynth/CSRs[71], /testbench/dut/rvvisynth/CSRs[70], /testbench/dut/rvvisynth/CSRs[69], /testbench/dut/rvvisynth/CSRs[68], /testbench/dut/rvvisynth/CSRs[67], /testbench/dut/rvvisynth/CSRs[66], /testbench/dut/rvvisynth/CSRs[65], /testbench/dut/rvvisynth/CSRs[64], /testbench/dut/rvvisynth/CSRs[63], /testbench/dut/rvvisynth/CSRs[62], /testbench/dut/rvvisynth/CSRs[61], /testbench/dut/rvvisynth/CSRs[60], /testbench/dut/rvvisynth/CSRs[59], /testbench/dut/rvvisynth/CSRs[58], /testbench/dut/rvvisynth/CSRs[57], /testbench/dut/rvvisynth/CSRs[56], /testbench/dut/rvvisynth/CSRs[55], /testbench/dut/rvvisynth/CSRs[54], /testbench/dut/rvvisynth/CSRs[53], /testbench/dut/rvvisynth/CSRs[52], /testbench/dut/rvvisynth/CSRs[51], /testbench/dut/rvvisynth/CSRs[50], /testbench/dut/rvvisynth/CSRs[49], /testbench/dut/rvvisynth/CSRs[48], /testbench/dut/rvvisynth/CSRs[47], /testbench/dut/rvvisynth/CSRs[46], /testbench/dut/rvvisynth/CSRs[45], /testbench/dut/rvvisynth/CSRs[44], /testbench/dut/rvvisynth/CSRs[43], /testbench/dut/rvvisynth/CSRs[42], /testbench/dut/rvvisynth/CSRs[41], /testbench/dut/rvvisynth/CSRs[40], /testbench/dut/rvvisynth/CSRs[39], /testbench/dut/rvvisynth/CSRs[38], /testbench/dut/rvvisynth/CSRs[37], /testbench/dut/rvvisynth/CSRs[36], /testbench/dut/rvvisynth/CSRs[35], /testbench/dut/rvvisynth/CSRs[34], /testbench/dut/rvvisynth/CSRs[33], /testbench/dut/rvvisynth/CSRs[32], /testbench/dut/rvvisynth/CSRs[31], /testbench/dut/rvvisynth/CSRs[30], /testbench/dut/rvvisynth/CSRs[29], /testbench/dut/rvvisynth/CSRs[28], /testbench/dut/rvvisynth/CSRs[27], /testbench/dut/rvvisynth/CSRs[26], /testbench/dut/rvvisynth/CSRs[25], /testbench/dut/rvvisynth/CSRs[24] }} CSRData0 +quietly virtual function -install /testbench/dut/rvvisynth -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/rvvisynth/CSRs[163], /testbench/dut/rvvisynth/CSRs[162], /testbench/dut/rvvisynth/CSRs[161], /testbench/dut/rvvisynth/CSRs[160], /testbench/dut/rvvisynth/CSRs[159], /testbench/dut/rvvisynth/CSRs[158], /testbench/dut/rvvisynth/CSRs[157], /testbench/dut/rvvisynth/CSRs[156], /testbench/dut/rvvisynth/CSRs[155], /testbench/dut/rvvisynth/CSRs[154], /testbench/dut/rvvisynth/CSRs[153], /testbench/dut/rvvisynth/CSRs[152], /testbench/dut/rvvisynth/CSRs[151], /testbench/dut/rvvisynth/CSRs[150], /testbench/dut/rvvisynth/CSRs[149], /testbench/dut/rvvisynth/CSRs[148], /testbench/dut/rvvisynth/CSRs[147], /testbench/dut/rvvisynth/CSRs[146], /testbench/dut/rvvisynth/CSRs[145], /testbench/dut/rvvisynth/CSRs[144], /testbench/dut/rvvisynth/CSRs[143], /testbench/dut/rvvisynth/CSRs[142], /testbench/dut/rvvisynth/CSRs[141], /testbench/dut/rvvisynth/CSRs[140], /testbench/dut/rvvisynth/CSRs[139], /testbench/dut/rvvisynth/CSRs[138], /testbench/dut/rvvisynth/CSRs[137], /testbench/dut/rvvisynth/CSRs[136], /testbench/dut/rvvisynth/CSRs[135], /testbench/dut/rvvisynth/CSRs[134], /testbench/dut/rvvisynth/CSRs[133], /testbench/dut/rvvisynth/CSRs[132], /testbench/dut/rvvisynth/CSRs[131], /testbench/dut/rvvisynth/CSRs[130], /testbench/dut/rvvisynth/CSRs[129], /testbench/dut/rvvisynth/CSRs[128], /testbench/dut/rvvisynth/CSRs[127], /testbench/dut/rvvisynth/CSRs[126], /testbench/dut/rvvisynth/CSRs[125], /testbench/dut/rvvisynth/CSRs[124], /testbench/dut/rvvisynth/CSRs[123], /testbench/dut/rvvisynth/CSRs[122], /testbench/dut/rvvisynth/CSRs[121], /testbench/dut/rvvisynth/CSRs[120], /testbench/dut/rvvisynth/CSRs[119], /testbench/dut/rvvisynth/CSRs[118], /testbench/dut/rvvisynth/CSRs[117], /testbench/dut/rvvisynth/CSRs[116], /testbench/dut/rvvisynth/CSRs[115], /testbench/dut/rvvisynth/CSRs[114], /testbench/dut/rvvisynth/CSRs[113], /testbench/dut/rvvisynth/CSRs[112], /testbench/dut/rvvisynth/CSRs[111], /testbench/dut/rvvisynth/CSRs[110], /testbench/dut/rvvisynth/CSRs[109], /testbench/dut/rvvisynth/CSRs[108], /testbench/dut/rvvisynth/CSRs[107], /testbench/dut/rvvisynth/CSRs[106], /testbench/dut/rvvisynth/CSRs[105], /testbench/dut/rvvisynth/CSRs[104], /testbench/dut/rvvisynth/CSRs[103], /testbench/dut/rvvisynth/CSRs[102], /testbench/dut/rvvisynth/CSRs[101], /testbench/dut/rvvisynth/CSRs[100] }} CSRData1 +quietly virtual function -install /testbench/dut/rvvisynth -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/rvvisynth/CSRs[175], /testbench/dut/rvvisynth/CSRs[174], /testbench/dut/rvvisynth/CSRs[173], /testbench/dut/rvvisynth/CSRs[172], /testbench/dut/rvvisynth/CSRs[171], /testbench/dut/rvvisynth/CSRs[170], /testbench/dut/rvvisynth/CSRs[169], /testbench/dut/rvvisynth/CSRs[168], /testbench/dut/rvvisynth/CSRs[167], /testbench/dut/rvvisynth/CSRs[166], /testbench/dut/rvvisynth/CSRs[165], /testbench/dut/rvvisynth/CSRs[164] }} CSRAdr2 +quietly virtual function -install /testbench/dut/rvvisynth -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/rvvisynth/CSRs[239], /testbench/dut/rvvisynth/CSRs[238], /testbench/dut/rvvisynth/CSRs[237], /testbench/dut/rvvisynth/CSRs[236], /testbench/dut/rvvisynth/CSRs[235], /testbench/dut/rvvisynth/CSRs[234], /testbench/dut/rvvisynth/CSRs[233], /testbench/dut/rvvisynth/CSRs[232], /testbench/dut/rvvisynth/CSRs[231], /testbench/dut/rvvisynth/CSRs[230], /testbench/dut/rvvisynth/CSRs[229], /testbench/dut/rvvisynth/CSRs[228], /testbench/dut/rvvisynth/CSRs[227], /testbench/dut/rvvisynth/CSRs[226], /testbench/dut/rvvisynth/CSRs[225], /testbench/dut/rvvisynth/CSRs[224], /testbench/dut/rvvisynth/CSRs[223], /testbench/dut/rvvisynth/CSRs[222], /testbench/dut/rvvisynth/CSRs[221], /testbench/dut/rvvisynth/CSRs[220], /testbench/dut/rvvisynth/CSRs[219], /testbench/dut/rvvisynth/CSRs[218], /testbench/dut/rvvisynth/CSRs[217], /testbench/dut/rvvisynth/CSRs[216], /testbench/dut/rvvisynth/CSRs[215], /testbench/dut/rvvisynth/CSRs[214], /testbench/dut/rvvisynth/CSRs[213], /testbench/dut/rvvisynth/CSRs[212], /testbench/dut/rvvisynth/CSRs[211], /testbench/dut/rvvisynth/CSRs[210], /testbench/dut/rvvisynth/CSRs[209], /testbench/dut/rvvisynth/CSRs[208], /testbench/dut/rvvisynth/CSRs[207], /testbench/dut/rvvisynth/CSRs[206], /testbench/dut/rvvisynth/CSRs[205], /testbench/dut/rvvisynth/CSRs[204], /testbench/dut/rvvisynth/CSRs[203], /testbench/dut/rvvisynth/CSRs[202], /testbench/dut/rvvisynth/CSRs[201], /testbench/dut/rvvisynth/CSRs[200], /testbench/dut/rvvisynth/CSRs[199], /testbench/dut/rvvisynth/CSRs[198], /testbench/dut/rvvisynth/CSRs[197], /testbench/dut/rvvisynth/CSRs[196], /testbench/dut/rvvisynth/CSRs[195], /testbench/dut/rvvisynth/CSRs[194], /testbench/dut/rvvisynth/CSRs[193], /testbench/dut/rvvisynth/CSRs[192], /testbench/dut/rvvisynth/CSRs[191], /testbench/dut/rvvisynth/CSRs[190], /testbench/dut/rvvisynth/CSRs[189], /testbench/dut/rvvisynth/CSRs[188], /testbench/dut/rvvisynth/CSRs[187], /testbench/dut/rvvisynth/CSRs[186], /testbench/dut/rvvisynth/CSRs[185], /testbench/dut/rvvisynth/CSRs[184], /testbench/dut/rvvisynth/CSRs[183], /testbench/dut/rvvisynth/CSRs[182], /testbench/dut/rvvisynth/CSRs[181], /testbench/dut/rvvisynth/CSRs[180], /testbench/dut/rvvisynth/CSRs[179], /testbench/dut/rvvisynth/CSRs[178], /testbench/dut/rvvisynth/CSRs[177], /testbench/dut/rvvisynth/CSRs[176] }} CSRData2 +quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Required[63], /testbench/dut/Required[62], /testbench/dut/Required[61], /testbench/dut/Required[60], /testbench/dut/Required[59], /testbench/dut/Required[58], /testbench/dut/Required[57], /testbench/dut/Required[56], /testbench/dut/Required[55], /testbench/dut/Required[54], /testbench/dut/Required[53], /testbench/dut/Required[52], /testbench/dut/Required[51], /testbench/dut/Required[50], /testbench/dut/Required[49], /testbench/dut/Required[48], /testbench/dut/Required[47], /testbench/dut/Required[46], /testbench/dut/Required[45], /testbench/dut/Required[44], /testbench/dut/Required[43], /testbench/dut/Required[42], /testbench/dut/Required[41], /testbench/dut/Required[40], /testbench/dut/Required[39], /testbench/dut/Required[38], /testbench/dut/Required[37], /testbench/dut/Required[36], /testbench/dut/Required[35], /testbench/dut/Required[34], /testbench/dut/Required[33], /testbench/dut/Required[32], /testbench/dut/Required[31], /testbench/dut/Required[30], /testbench/dut/Required[29], /testbench/dut/Required[28], /testbench/dut/Required[27], /testbench/dut/Required[26], /testbench/dut/Required[25], /testbench/dut/Required[24], /testbench/dut/Required[23], /testbench/dut/Required[22], /testbench/dut/Required[21], /testbench/dut/Required[20], /testbench/dut/Required[19], /testbench/dut/Required[18], /testbench/dut/Required[17], /testbench/dut/Required[16], /testbench/dut/Required[15], /testbench/dut/Required[14], /testbench/dut/Required[13], /testbench/dut/Required[12], /testbench/dut/Required[11], /testbench/dut/Required[10], /testbench/dut/Required[9], /testbench/dut/Required[8], /testbench/dut/Required[7], /testbench/dut/Required[6], /testbench/dut/Required[5], /testbench/dut/Required[4], /testbench/dut/Required[3], /testbench/dut/Required[2], /testbench/dut/Required[1], /testbench/dut/Required[0] }} PCW +quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Required[95], /testbench/dut/Required[94], /testbench/dut/Required[93], /testbench/dut/Required[92], /testbench/dut/Required[91], /testbench/dut/Required[90], /testbench/dut/Required[89], /testbench/dut/Required[88], /testbench/dut/Required[87], /testbench/dut/Required[86], /testbench/dut/Required[85], /testbench/dut/Required[84], /testbench/dut/Required[83], /testbench/dut/Required[82], /testbench/dut/Required[81], /testbench/dut/Required[80], /testbench/dut/Required[79], /testbench/dut/Required[78], /testbench/dut/Required[77], /testbench/dut/Required[76], /testbench/dut/Required[75], /testbench/dut/Required[74], /testbench/dut/Required[73], /testbench/dut/Required[72], /testbench/dut/Required[71], /testbench/dut/Required[70], /testbench/dut/Required[69], /testbench/dut/Required[68], /testbench/dut/Required[67], /testbench/dut/Required[66], /testbench/dut/Required[65], /testbench/dut/Required[64] }} InstrW +quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Required[159], /testbench/dut/Required[158], /testbench/dut/Required[157], /testbench/dut/Required[156], /testbench/dut/Required[155], /testbench/dut/Required[154], /testbench/dut/Required[153], /testbench/dut/Required[152], /testbench/dut/Required[151], /testbench/dut/Required[150], /testbench/dut/Required[149], /testbench/dut/Required[148], /testbench/dut/Required[147], /testbench/dut/Required[146], /testbench/dut/Required[145], /testbench/dut/Required[144], /testbench/dut/Required[143], /testbench/dut/Required[142], /testbench/dut/Required[141], /testbench/dut/Required[140], /testbench/dut/Required[139], /testbench/dut/Required[138], /testbench/dut/Required[137], /testbench/dut/Required[136], /testbench/dut/Required[135], /testbench/dut/Required[134], /testbench/dut/Required[133], /testbench/dut/Required[132], /testbench/dut/Required[131], /testbench/dut/Required[130], /testbench/dut/Required[129], /testbench/dut/Required[128], /testbench/dut/Required[127], /testbench/dut/Required[126], /testbench/dut/Required[125], /testbench/dut/Required[124], /testbench/dut/Required[123], /testbench/dut/Required[122], /testbench/dut/Required[121], /testbench/dut/Required[120], /testbench/dut/Required[119], /testbench/dut/Required[118], /testbench/dut/Required[117], /testbench/dut/Required[116], /testbench/dut/Required[115], /testbench/dut/Required[114], /testbench/dut/Required[113], /testbench/dut/Required[112], /testbench/dut/Required[111], /testbench/dut/Required[110], /testbench/dut/Required[109], /testbench/dut/Required[108], /testbench/dut/Required[107], /testbench/dut/Required[106], /testbench/dut/Required[105], /testbench/dut/Required[104], /testbench/dut/Required[103], /testbench/dut/Required[102], /testbench/dut/Required[101], /testbench/dut/Required[100], /testbench/dut/Required[99], /testbench/dut/Required[98], /testbench/dut/Required[97], /testbench/dut/Required[96] }} Mcycle +quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Required[223], /testbench/dut/Required[222], /testbench/dut/Required[221], /testbench/dut/Required[220], /testbench/dut/Required[219], /testbench/dut/Required[218], /testbench/dut/Required[217], /testbench/dut/Required[216], /testbench/dut/Required[215], /testbench/dut/Required[214], /testbench/dut/Required[213], /testbench/dut/Required[212], /testbench/dut/Required[211], /testbench/dut/Required[210], /testbench/dut/Required[209], /testbench/dut/Required[208], /testbench/dut/Required[207], /testbench/dut/Required[206], /testbench/dut/Required[205], /testbench/dut/Required[204], /testbench/dut/Required[203], /testbench/dut/Required[202], /testbench/dut/Required[201], /testbench/dut/Required[200], /testbench/dut/Required[199], /testbench/dut/Required[198], /testbench/dut/Required[197], /testbench/dut/Required[196], /testbench/dut/Required[195], /testbench/dut/Required[194], /testbench/dut/Required[193], /testbench/dut/Required[192], /testbench/dut/Required[191], /testbench/dut/Required[190], /testbench/dut/Required[189], /testbench/dut/Required[188], /testbench/dut/Required[187], /testbench/dut/Required[186], /testbench/dut/Required[185], /testbench/dut/Required[184], /testbench/dut/Required[183], /testbench/dut/Required[182], /testbench/dut/Required[181], /testbench/dut/Required[180], /testbench/dut/Required[179], /testbench/dut/Required[178], /testbench/dut/Required[177], /testbench/dut/Required[176], /testbench/dut/Required[175], /testbench/dut/Required[174], /testbench/dut/Required[173], /testbench/dut/Required[172], /testbench/dut/Required[171], /testbench/dut/Required[170], /testbench/dut/Required[169], /testbench/dut/Required[168], /testbench/dut/Required[167], /testbench/dut/Required[166], /testbench/dut/Required[165], /testbench/dut/Required[164], /testbench/dut/Required[163], /testbench/dut/Required[162], /testbench/dut/Required[161], /testbench/dut/Required[160] }} Minstret +quietly virtual signal -install /testbench/dut {/testbench/dut/Required[224] } TrapW +quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Required[226], /testbench/dut/Required[225] }} PrivilegeModeW +quietly virtual signal -install /testbench/dut {/testbench/dut/Registers[0] } GPRWen +quietly virtual signal -install /testbench/dut {/testbench/dut/Registers[1] } FPRWen +quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Registers[6], /testbench/dut/Registers[5], /testbench/dut/Registers[4], /testbench/dut/Registers[3], /testbench/dut/Registers[2] }} GPRAdr +quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Registers[71], /testbench/dut/Registers[70], /testbench/dut/Registers[69], /testbench/dut/Registers[68], /testbench/dut/Registers[67], /testbench/dut/Registers[66], /testbench/dut/Registers[65], /testbench/dut/Registers[64], /testbench/dut/Registers[63], /testbench/dut/Registers[62], /testbench/dut/Registers[61], /testbench/dut/Registers[60], /testbench/dut/Registers[59], /testbench/dut/Registers[58], /testbench/dut/Registers[57], /testbench/dut/Registers[56], /testbench/dut/Registers[55], /testbench/dut/Registers[54], /testbench/dut/Registers[53], /testbench/dut/Registers[52], /testbench/dut/Registers[51], /testbench/dut/Registers[50], /testbench/dut/Registers[49], /testbench/dut/Registers[48], /testbench/dut/Registers[47], /testbench/dut/Registers[46], /testbench/dut/Registers[45], /testbench/dut/Registers[44], /testbench/dut/Registers[43], /testbench/dut/Registers[42], /testbench/dut/Registers[41], /testbench/dut/Registers[40], /testbench/dut/Registers[39], /testbench/dut/Registers[38], /testbench/dut/Registers[37], /testbench/dut/Registers[36], /testbench/dut/Registers[35], /testbench/dut/Registers[34], /testbench/dut/Registers[33], /testbench/dut/Registers[32], /testbench/dut/Registers[31], /testbench/dut/Registers[30], /testbench/dut/Registers[29], /testbench/dut/Registers[28], /testbench/dut/Registers[27], /testbench/dut/Registers[26], /testbench/dut/Registers[25], /testbench/dut/Registers[24], /testbench/dut/Registers[23], /testbench/dut/Registers[22], /testbench/dut/Registers[21], /testbench/dut/Registers[20], /testbench/dut/Registers[19], /testbench/dut/Registers[18], /testbench/dut/Registers[17], /testbench/dut/Registers[16], /testbench/dut/Registers[15], /testbench/dut/Registers[14], /testbench/dut/Registers[13], /testbench/dut/Registers[12], /testbench/dut/Registers[11], /testbench/dut/Registers[10], /testbench/dut/Registers[9], /testbench/dut/Registers[8], /testbench/dut/Registers[7] }} GPRValue +quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Registers[76], /testbench/dut/Registers[75], /testbench/dut/Registers[74], /testbench/dut/Registers[73], /testbench/dut/Registers[72], /testbench/dut/Registers[71] }} GPRAdr001 +quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Registers[139], /testbench/dut/Registers[138], /testbench/dut/Registers[137], /testbench/dut/Registers[136], /testbench/dut/Registers[135], /testbench/dut/Registers[134], /testbench/dut/Registers[133], /testbench/dut/Registers[132], /testbench/dut/Registers[131], /testbench/dut/Registers[130], /testbench/dut/Registers[129], /testbench/dut/Registers[128], /testbench/dut/Registers[127], /testbench/dut/Registers[126], /testbench/dut/Registers[125], /testbench/dut/Registers[124], /testbench/dut/Registers[123], /testbench/dut/Registers[122], /testbench/dut/Registers[121], /testbench/dut/Registers[120], /testbench/dut/Registers[119], /testbench/dut/Registers[118], /testbench/dut/Registers[117], /testbench/dut/Registers[116], /testbench/dut/Registers[115], /testbench/dut/Registers[114], /testbench/dut/Registers[113], /testbench/dut/Registers[112], /testbench/dut/Registers[111], /testbench/dut/Registers[110], /testbench/dut/Registers[109], /testbench/dut/Registers[108], /testbench/dut/Registers[107], /testbench/dut/Registers[106], /testbench/dut/Registers[105], /testbench/dut/Registers[104], /testbench/dut/Registers[103], /testbench/dut/Registers[102], /testbench/dut/Registers[101], /testbench/dut/Registers[100], /testbench/dut/Registers[99], /testbench/dut/Registers[98], /testbench/dut/Registers[97], /testbench/dut/Registers[96], /testbench/dut/Registers[95], /testbench/dut/Registers[94], /testbench/dut/Registers[93], /testbench/dut/Registers[92], /testbench/dut/Registers[91], /testbench/dut/Registers[90], /testbench/dut/Registers[89], /testbench/dut/Registers[88], /testbench/dut/Registers[87], /testbench/dut/Registers[86], /testbench/dut/Registers[85], /testbench/dut/Registers[84], /testbench/dut/Registers[83], /testbench/dut/Registers[82], /testbench/dut/Registers[81], /testbench/dut/Registers[80], /testbench/dut/Registers[79], /testbench/dut/Registers[78], /testbench/dut/Registers[77], /testbench/dut/Registers[76] }} FPRValue +quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Registers[70], /testbench/dut/Registers[69], /testbench/dut/Registers[68], /testbench/dut/Registers[67], /testbench/dut/Registers[66], /testbench/dut/Registers[65], /testbench/dut/Registers[64], /testbench/dut/Registers[63], /testbench/dut/Registers[62], /testbench/dut/Registers[61], /testbench/dut/Registers[60], /testbench/dut/Registers[59], /testbench/dut/Registers[58], /testbench/dut/Registers[57], /testbench/dut/Registers[56], /testbench/dut/Registers[55], /testbench/dut/Registers[54], /testbench/dut/Registers[53], /testbench/dut/Registers[52], /testbench/dut/Registers[51], /testbench/dut/Registers[50], /testbench/dut/Registers[49], /testbench/dut/Registers[48], /testbench/dut/Registers[47], /testbench/dut/Registers[46], /testbench/dut/Registers[45], /testbench/dut/Registers[44], /testbench/dut/Registers[43], /testbench/dut/Registers[42], /testbench/dut/Registers[41], /testbench/dut/Registers[40], /testbench/dut/Registers[39], /testbench/dut/Registers[38], /testbench/dut/Registers[37], /testbench/dut/Registers[36], /testbench/dut/Registers[35], /testbench/dut/Registers[34], /testbench/dut/Registers[33], /testbench/dut/Registers[32], /testbench/dut/Registers[31], /testbench/dut/Registers[30], /testbench/dut/Registers[29], /testbench/dut/Registers[28], /testbench/dut/Registers[27], /testbench/dut/Registers[26], /testbench/dut/Registers[25], /testbench/dut/Registers[24], /testbench/dut/Registers[23], /testbench/dut/Registers[22], /testbench/dut/Registers[21], /testbench/dut/Registers[20], /testbench/dut/Registers[19], /testbench/dut/Registers[18], /testbench/dut/Registers[17], /testbench/dut/Registers[16], /testbench/dut/Registers[15], /testbench/dut/Registers[14], /testbench/dut/Registers[13], /testbench/dut/Registers[12], /testbench/dut/Registers[11], /testbench/dut/Registers[10], /testbench/dut/Registers[9], /testbench/dut/Registers[8], /testbench/dut/Registers[7] }} GPRValue001 +quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Registers[75], /testbench/dut/Registers[74], /testbench/dut/Registers[73], /testbench/dut/Registers[72], /testbench/dut/Registers[71] }} FPRAdr quietly WaveActivateNextPane {} 0 add wave -noupdate /testbench/clk add wave -noupdate /testbench/reset add wave -noupdate /testbench/memfilename add wave -noupdate /testbench/dut/core/SATP_REGW add wave -noupdate /testbench/dut/core/InstrValidM -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/hzu/RetM -add wave -noupdate -expand -group HDU -expand -group hazards -color Pink /testbench/dut/core/hzu/TrapM -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/ieu/c/LoadStallD -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/ifu/IFUStallF -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/hzu/BPWrongE -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/hzu/LSUStallM -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/ieu/c/MDUStallD -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/hzu/DivBusyE -add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/core/hzu/FDivBusyE -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrAccessFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/IllegalInstrFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/BreakpointFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/LoadMisalignedFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StoreAmoMisalignedFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/LoadAccessFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StoreAmoAccessFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/EcallFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrPageFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/LoadPageFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StoreAmoPageFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InterruptM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/HPTWInstrAccessFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/core/priv/priv/pmd/WFITimeoutM -add wave -noupdate -expand -group HDU -group Flush -color Yellow /testbench/dut/core/FlushD -add wave -noupdate -expand -group HDU -group Flush -color Yellow /testbench/dut/core/FlushE -add wave -noupdate -expand -group HDU -group Flush -color Yellow /testbench/dut/core/FlushM -add wave -noupdate -expand -group HDU -group Flush -color Yellow /testbench/dut/core/FlushW -add wave -noupdate -expand -group HDU -group Stall -color Orange /testbench/dut/core/StallF -add wave -noupdate -expand -group HDU -group Stall -color Orange /testbench/dut/core/StallD -add wave -noupdate -expand -group HDU -group Stall -color Orange /testbench/dut/core/StallE -add wave -noupdate -expand -group HDU -group Stall -color Orange /testbench/dut/core/StallM -add wave -noupdate -expand -group HDU -group Stall -color Orange /testbench/dut/core/StallW -add wave -noupdate -expand -group HDU -group interrupts /testbench/dut/core/priv/priv/trap/PendingIntsM -add wave -noupdate -expand -group HDU -group interrupts /testbench/dut/core/priv/priv/trap/InstrValidM -add wave -noupdate -expand -group HDU -group interrupts /testbench/dut/core/priv/priv/trap/ValidIntsM -add wave -noupdate -expand -group HDU -group interrupts /testbench/dut/core/hzu/WFIInterruptedM +add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/RetM +add wave -noupdate -group HDU -expand -group hazards -color Pink /testbench/dut/core/hzu/TrapM +add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/ieu/c/LoadStallD +add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/ifu/IFUStallF +add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/BPWrongE +add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/LSUStallM +add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/ieu/c/MDUStallD +add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/DivBusyE +add wave -noupdate -group HDU -expand -group hazards /testbench/dut/core/hzu/FDivBusyE +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrAccessFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/IllegalInstrFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/BreakpointFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/LoadMisalignedFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StoreAmoMisalignedFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/LoadAccessFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StoreAmoAccessFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/EcallFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InstrPageFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/LoadPageFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/StoreAmoPageFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/InterruptM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/trap/HPTWInstrAccessFaultM +add wave -noupdate -group HDU -expand -group traps /testbench/dut/core/priv/priv/pmd/WFITimeoutM +add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/core/FlushD +add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/core/FlushE +add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/core/FlushM +add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/core/FlushW +add wave -noupdate -group HDU -group Stall -color Orange /testbench/dut/core/StallF +add wave -noupdate -group HDU -group Stall -color Orange /testbench/dut/core/StallD +add wave -noupdate -group HDU -group Stall -color Orange /testbench/dut/core/StallE +add wave -noupdate -group HDU -group Stall -color Orange /testbench/dut/core/StallM +add wave -noupdate -group HDU -group Stall -color Orange /testbench/dut/core/StallW +add wave -noupdate -group HDU -group interrupts /testbench/dut/core/priv/priv/trap/PendingIntsM +add wave -noupdate -group HDU -group interrupts /testbench/dut/core/priv/priv/trap/InstrValidM +add wave -noupdate -group HDU -group interrupts /testbench/dut/core/priv/priv/trap/ValidIntsM +add wave -noupdate -group HDU -group interrupts /testbench/dut/core/hzu/WFIInterruptedM add wave -noupdate -group {instruction pipeline} /testbench/InstrFName add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/PostSpillInstrRawF add wave -noupdate -group {instruction pipeline} /testbench/dut/core/ifu/InstrD @@ -239,7 +259,6 @@ add wave -noupdate -expand -group lsu -group alignment /testbench/dut/core/lsu/z add wave -noupdate -expand -group lsu -group alignment /testbench/dut/core/lsu/ziccslm_align/align/SelSpillM add wave -noupdate -expand -group lsu -group alignment /testbench/dut/core/lsu/ByteMaskSpillM add wave -noupdate -expand -group lsu -group alignment /testbench/dut/core/lsu/LSUWriteDataM -add wave -noupdate -expand -group lsu -group alignment /testbench/dut/core/lsu/LSUWriteDataSpillM add wave -noupdate -expand -group lsu -group alignment /testbench/dut/core/lsu/bus/dcache/dcache/CacheWriteData add wave -noupdate -expand -group lsu -group alignment /testbench/dut/core/lsu/bus/dcache/dcache/ByteMask add wave -noupdate -expand -group lsu -group alignment /testbench/dut/core/lsu/bus/dcache/dcache/WriteSelLogic/BlankByteMask @@ -252,20 +271,18 @@ add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/bus/dcache/dcache/ add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/CacheRW add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/CMOpM add wave -noupdate -expand -group lsu -expand -group dcache -color Gold /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/CurrState -add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/SetValid -add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/ClearValid -add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/SetDirty -add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty -add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/SelWay -add wave -noupdate -expand -group lsu -expand -group dcache -group {requesting address} /testbench/dut/core/lsu/IEUAdrE -add wave -noupdate -expand -group lsu -expand -group dcache -group {requesting address} /testbench/dut/core/lsu/bus/dcache/dcache/PAdr +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/SetValid +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/ClearValid +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/SetDirty +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {requesting address} /testbench/dut/core/lsu/IEUAdrE +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {requesting address} /testbench/dut/core/lsu/bus/dcache/dcache/PAdr add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-outputs /testbench/dut/core/lsu/bus/dcache/dcache/ReadDataLineWay add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-outputs /testbench/dut/core/lsu/bus/dcache/dcache/ReadDataLineCache add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-outputs /testbench/dut/core/lsu/bus/dcache/dcache/TagWay add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-outputs /testbench/dut/core/lsu/bus/dcache/dcache/Tag add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-outputs /testbench/dut/core/lsu/bus/dcache/dcache/ValidWay add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-outputs /testbench/dut/core/lsu/bus/dcache/dcache/HitWay -add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-outputs -color {Blue Violet} /testbench/dut/core/lsu/bus/dcache/dcache/CacheHit add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-outputs /testbench/dut/core/lsu/bus/dcache/dcache/DirtyWay add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-outputs {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/Dirty} add wave -noupdate -expand -group lsu -expand -group dcache -group SRAM-outputs /testbench/dut/core/lsu/bus/dcache/dcache/HitDirtyWay @@ -294,7 +311,6 @@ add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM w add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/SetDirty add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/LineByteMask -add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SelData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SelectedWriteWordEn} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SetValidWay} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ClearValidWay} @@ -316,7 +332,6 @@ add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM w add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way0 -expand -group Way0Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[3]/wordram/CacheDataMem/bwe} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way0 -expand -group Way0Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[3]/wordram/CacheDataMem/RAM} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SelNonHit} -add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SelData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SelectedWriteWordEn} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SetValidWay} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/ClearValidWay} @@ -410,30 +425,29 @@ add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dm add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPInstrAccessFaultF add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPLoadAccessFaultM add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPStoreAmoAccessFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/SelHPTW -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/HPTWStall -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/DTLBWalk -add wave -noupdate -expand -group lsu -expand -group ptwalker -color Gold /testbench/dut/core/lsu/hptw/hptw/WalkerState -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/NextWalkerState -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/HPTWAdr -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/PTE -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/NextPageType -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/PageType -add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/hptw/hptw/ValidNonLeafPTE -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/ITLBMissF -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/DTLBMissM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/hptw/hptw/ITLBWriteF -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/hptw/hptw/DTLBWriteM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/HPTWFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LSUAccessFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/DCacheStallM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/HPTWInstrAccessFaultF -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LSULoadAccessFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LSUStoreAmoAccessFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LoadAccessFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/StoreAmoAccessFaultM -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/HPTWInstrAccessFault -add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/PBMTFaultM +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/hptw/hptw/SelHPTW +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/hptw/hptw/HPTWStall +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/hptw/hptw/DTLBWalk +add wave -noupdate -expand -group lsu -group ptwalker -color Gold /testbench/dut/core/lsu/hptw/hptw/WalkerState +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/hptw/hptw/NextWalkerState +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/hptw/hptw/HPTWAdr +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/hptw/hptw/PTE +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/hptw/hptw/NextPageType +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/hptw/hptw/PageType +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/core/lsu/hptw/hptw/ValidNonLeafPTE +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/ITLBMissF +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/DTLBMissM +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/hptw/hptw/ITLBWriteF +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/core/lsu/hptw/hptw/DTLBWriteM +add wave -noupdate -expand -group lsu -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/HPTWFaultM +add wave -noupdate -expand -group lsu -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LSUAccessFaultM +add wave -noupdate -expand -group lsu -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/HPTWInstrAccessFaultF +add wave -noupdate -expand -group lsu -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LSULoadAccessFaultM +add wave -noupdate -expand -group lsu -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LSUStoreAmoAccessFaultM +add wave -noupdate -expand -group lsu -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/LoadAccessFaultM +add wave -noupdate -expand -group lsu -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/StoreAmoAccessFaultM +add wave -noupdate -expand -group lsu -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/HPTWInstrAccessFault +add wave -noupdate -expand -group lsu -group ptwalker -expand -group faults /testbench/dut/core/lsu/hptw/hptw/PBMTFaultM add wave -noupdate -group {WriteBack stage} /testbench/InstrW add wave -noupdate -group {WriteBack stage} /testbench/InstrWName add wave -noupdate -group {WriteBack stage} /testbench/dut/core/priv/priv/pmd/wfiW @@ -665,9 +679,31 @@ add wave -noupdate -group wfi /testbench/dut/core/priv/priv/pmd/WFITimeoutM add wave -noupdate -expand -group testbench /testbench/DCacheFlushStart add wave -noupdate /testbench/dut/core/lsu/hptw/hptw/HPTWLoadPageFault add wave -noupdate /testbench/dut/core/lsu/hptw/hptw/HPTWLoadPageFaultDelay +add wave -noupdate /testbench/dut/GPRWen +add wave -noupdate /testbench/dut/FPRWen +add wave -noupdate /testbench/dut/GPRAdr +add wave -noupdate /testbench/dut/FPRValue +add wave -noupdate /testbench/dut/GPRValue001 +add wave -noupdate /testbench/dut/FPRAdr +add wave -noupdate /testbench/dut/Registers +add wave -noupdate /testbench/dut/PCW +add wave -noupdate /testbench/dut/InstrW +add wave -noupdate /testbench/dut/Mcycle +add wave -noupdate /testbench/dut/Minstret +add wave -noupdate /testbench/dut/TrapW +add wave -noupdate /testbench/dut/PrivilegeModeW +add wave -noupdate /testbench/dut/Required +add wave -noupdate /testbench/dut/rvvisynth/NumCSRs +add wave -noupdate /testbench/dut/rvvisynth/CSRAdr0 +add wave -noupdate /testbench/dut/rvvisynth/CSRData0 +add wave -noupdate /testbench/dut/rvvisynth/CSRData1 +add wave -noupdate /testbench/dut/rvvisynth/CSRAdr2 +add wave -noupdate /testbench/dut/rvvisynth/CSRData2 +add wave -noupdate /testbench/dut/rvvisynth/CSRs +add wave -noupdate /testbench/dut/rvvisynth/valid TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 4} {6586 ns} 1} {{Cursor 4} {11656 ns} 0} {{Cursor 3} {403021 ns} 1} -quietly wave cursor active 2 +WaveRestoreCursors {{Cursor 4} {2298495 ns} 0} {{Cursor 4} {69146 ns} 1} {{Cursor 3} {403021 ns} 1} +quietly wave cursor active 1 configure wave -namecolwidth 250 configure wave -valuecolwidth 194 configure wave -justifyvalue left @@ -682,4 +718,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {11566 ns} {11760 ns} +WaveRestoreZoom {2298408 ns} {2298612 ns} diff --git a/src/wally/csrindextoaddr.sv b/src/wally/csrindextoaddr.sv index e06508bdf..8b2d9e6b7 100644 --- a/src/wally/csrindextoaddr.sv +++ b/src/wally/csrindextoaddr.sv @@ -27,12 +27,12 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -module csrindextoaddr #(parameter NUM_CSRS = 36) ( - input logic [ROWS-1:0] CSRWen, +module csrindextoaddr #(parameter TOTAL_CSRS = 36) ( + input logic [TOTAL_CSRS-1:0] CSRWen, output logic [11:0] CSRAddr); always_comb begin - case(CSRWen) begin + case(CSRWen) 36'h0_0000_0000: CSRAddr = 13'h000; 36'h0_0000_0001: CSRAddr = 13'h300; 36'h0_0000_0002: CSRAddr = 13'h310; @@ -71,7 +71,7 @@ module csrindextoaddr #(parameter NUM_CSRS = 36) ( 36'h4_0000_0000: CSRAddr = 13'h002; 36'h8_0000_0000: CSRAddr = 13'h003; default : CSRAddr = 13'h000; - end + endcase end endmodule diff --git a/src/wally/priorityaomux.sv b/src/wally/priorityaomux.sv index c99b0e1ed..d542c946f 100644 --- a/src/wally/priorityaomux.sv +++ b/src/wally/priorityaomux.sv @@ -33,7 +33,6 @@ module priorityaomux #(parameter ROWS = 8, COLS = 64) ( output logic [COLS-1:0] Y, output logic [ROWS-1:0] SelPriority); - logic [ROWS-1:0] SelPriority; logic [COLS-1:0] AMasked [ROWS-1:0]; genvar index; diff --git a/src/wally/rvvisynth.sv b/src/wally/rvvisynth.sv index 019000915..1bdc627d8 100644 --- a/src/wally/rvvisynth.sv +++ b/src/wally/rvvisynth.sv @@ -31,7 +31,7 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, parameter integer MAX_CSRS)( input logic clk, reset, output logic valid, - output logic [163+P.XLEN-1:0] Requied, + output logic [163+P.XLEN-1:0] Required, output logic [12+2*P.XLEN-1:0] Registers, output logic [12+MAX_CSRS*(P.XLEN+12)-1:0] CSRs ); @@ -54,9 +54,10 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, logic [P.XLEN-1:0] XLENZeros; logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0]; logic [TOTAL_CSRS-1:0] CSRArrayWen; - logic [MAX_CSRS-1:0] CSRValue [P.XLEN-1:0]; - logic [MAX_CSRS-1:0] CSRWen [TOTAL_CSRS-1:0]; - logic [MAX_CSRS-1:0] CSRAddr [11:0]; + logic [P.XLEN-1:0] CSRValue [MAX_CSRS-1:0]; + logic [TOTAL_CSRS-1:0] CSRWen [MAX_CSRS-1:0]; + logic [11:0] CSRAddr [MAX_CSRS-1:0]; + logic [MAX_CSRS-1:0] EnabledCSRs; // get signals from the core. assign StallW = testbench.dut.core.StallW; @@ -147,14 +148,14 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, // step 3a for(index = 0; index < MAX_CSRS; index = index + 1) begin - logic [NUM_CSRS-index-1:0] CSRWenShort; - priorityaomux #(NUM_CSRS-index, P.XLEN) priorityaomux(CSRArrayWen[MAX_CSRS-1:index], CSRArray[MAX_CSRS-1:index], CSRValue[index], CSRWenShort); + logic [MAX_CSRS-index-1:0] CSRWenShort; + priorityaomux #(MAX_CSRS-index, P.XLEN) priorityaomux(CSRArrayWen[MAX_CSRS-1:index], CSRArray[MAX_CSRS-1:index], CSRValue[index], CSRWenShort); assign CSRWen[index] = {{{index}{1'b0}}, CSRWenShort}; // step 3b - csrindextoaddr #(NUM_CSRS) csrindextoaddr(CSRWen, CSRAddr); - assign CSRs[(index+1) * P.XLEN - 1 + 12 + 12: index * P.XLEN + 12] = {CSRValue[index], CSRAddr[index]}; + csrindextoaddr #(TOTAL_CSRS) csrindextoaddr(CSRWen[index], CSRAddr[index]); + assign CSRs[(index+1) * (P.XLEN + 12) + 12 - 1: index * (P.XLEN + 12) + 12] = {CSRValue[index], CSRAddr[index]}; + assign EnabledCSRs[index] = |CSRWenShort; end - - + assign CSRs[11:0] = +EnabledCSRs; endmodule diff --git a/src/wally/wallypipelinedsoc.sv b/src/wally/wallypipelinedsoc.sv index d82a5c0d4..5b359eedf 100644 --- a/src/wally/wallypipelinedsoc.sv +++ b/src/wally/wallypipelinedsoc.sv @@ -87,4 +87,12 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( .UARTSout, .MTIME_CLINT, .SDCIntr, .SPIIn, .SPIOut, .SPICS); end + + localparam MAX_CSRS = 3; + logic valid; + logic [163+P.XLEN-1:0] Required; + logic [12+2*P.XLEN-1:0] Registers; + logic [12+MAX_CSRS*(P.XLEN+12)-1:0] CSRs; + rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .Required, .Registers, .CSRs); + endmodule From ea5d780adf50f78b9ebe06a02c3c6248372e07e0 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 21 May 2024 12:42:43 -0500 Subject: [PATCH 05/95] Closer to synthesized rvvi --- src/wally/rvvisynth.sv | 28 +++++++++++++++++----------- src/wally/wallypipelinedsoc.sv | 6 ++---- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/wally/rvvisynth.sv b/src/wally/rvvisynth.sv index 1bdc627d8..a8c3a608c 100644 --- a/src/wally/rvvisynth.sv +++ b/src/wally/rvvisynth.sv @@ -31,15 +31,13 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, parameter integer MAX_CSRS)( input logic clk, reset, output logic valid, - output logic [163+P.XLEN-1:0] Required, - output logic [12+2*P.XLEN-1:0] Registers, - output logic [12+MAX_CSRS*(P.XLEN+12)-1:0] CSRs + output logic [199+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi ); localparam TOTAL_CSRS = 36; // pipeline controlls - logic StallW, FlushW; + logic StallE, StallM, StallW, FlushE, FlushM, FlushW; // required logic [P.XLEN-1:0] PCM, PCW; logic InstrValidM, InstrValidW; @@ -58,9 +56,17 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, logic [TOTAL_CSRS-1:0] CSRWen [MAX_CSRS-1:0]; logic [11:0] CSRAddr [MAX_CSRS-1:0]; logic [MAX_CSRS-1:0] EnabledCSRs; + logic [11:0] CSRCount; + logic [177+P.XLEN-1:0] Required; + logic [10+2*P.XLEN-1:0] Registers; + logic [12+MAX_CSRS*(P.XLEN+12)-1:0] CSRs; // get signals from the core. + assign StallE = testbench.dut.core.StallE; + assign StallM = testbench.dut.core.StallM; assign StallW = testbench.dut.core.StallW; + assign FlushE = testbench.dut.core.FlushE; + assign FlushM = testbench.dut.core.FlushM; assign FlushW = testbench.dut.core.FlushW; assign InstrValidM = testbench.dut.core.ieu.InstrValidM; assign InstrRawD = testbench.dut.core.ifu.InstrRawD; @@ -129,11 +135,11 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, flopenrc #(1) TrapWReg (clk, reset, 1'b0, ~StallW, TrapM, TrapW); assign valid = InstrValidW & ~StallW; - assign Required = {PrivilegeModeW, TrapW, Minstret, Mcycle, InstrRawW, PCW}; - assign Registers = {FPRWen, GPRWen} == 2'b11 ? {FPRValue, FPRAddr, GPRValue, GPRAddr, FPRWen, GPRWen} : - {FPRWen, GPRWen} == 2'b01 ? {XLENZeros, 5'b0, GPRValue, GPRAddr, FPRWen, GPRWen} : - {FPRWen, GPRWen} == 2'b10 ? {FPRValue, FPRAddr, XLENZeros, 5'b0, FPRWen, GPRWen} : - {XLENZeros, 5'b0, XLENZeros, 5'b0, FPRWen, GPRWen}; + assign Required = {CSRCount, FPRWen, GPRWen, PrivilegeModeW, TrapW, Minstret, Mcycle, InstrRawW, PCW}; + assign Registers = {FPRWen, GPRWen} == 2'b11 ? {FPRValue, FPRAddr, GPRValue, GPRAddr} : + {FPRWen, GPRWen} == 2'b01 ? {XLENZeros, 5'b0, GPRValue, GPRAddr} : + {FPRWen, GPRWen} == 2'b10 ? {XLENZeros, 5'b0, FPRValue, FPRAddr} : + '0; // the CSRs are complex // 1. we need to get the CSR values @@ -153,9 +159,9 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, assign CSRWen[index] = {{{index}{1'b0}}, CSRWenShort}; // step 3b csrindextoaddr #(TOTAL_CSRS) csrindextoaddr(CSRWen[index], CSRAddr[index]); - assign CSRs[(index+1) * (P.XLEN + 12) + 12 - 1: index * (P.XLEN + 12) + 12] = {CSRValue[index], CSRAddr[index]}; + assign CSRs[(index+1) * (P.XLEN + 12)- 1: index * (P.XLEN + 12)] = {CSRValue[index], CSRAddr[index]}; assign EnabledCSRs[index] = |CSRWenShort; end - assign CSRs[11:0] = +EnabledCSRs; + assign CSRCount = +EnabledCSRs; endmodule diff --git a/src/wally/wallypipelinedsoc.sv b/src/wally/wallypipelinedsoc.sv index 63f10549c..1d4680e30 100644 --- a/src/wally/wallypipelinedsoc.sv +++ b/src/wally/wallypipelinedsoc.sv @@ -93,9 +93,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( localparam MAX_CSRS = 3; logic valid; - logic [163+P.XLEN-1:0] Required; - logic [12+2*P.XLEN-1:0] Registers; - logic [12+MAX_CSRS*(P.XLEN+12)-1:0] CSRs; - rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .Required, .Registers, .CSRs); + logic [199+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; + rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .rvvi); endmodule From 8fd278b322b7a8a47ab20db4046ebf74a3bd6969 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 21 May 2024 16:15:05 -0500 Subject: [PATCH 06/95] Fixed some references to rvvi. --- src/wally/rvvisynth.sv | 106 +++++++++++++++++---------------- src/wally/wallypipelinedsoc.sv | 2 +- 2 files changed, 55 insertions(+), 53 deletions(-) diff --git a/src/wally/rvvisynth.sv b/src/wally/rvvisynth.sv index a8c3a608c..27a1fe6d3 100644 --- a/src/wally/rvvisynth.sv +++ b/src/wally/rvvisynth.sv @@ -31,7 +31,7 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, parameter integer MAX_CSRS)( input logic clk, reset, output logic valid, - output logic [199+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi + output logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi ); localparam TOTAL_CSRS = 36; @@ -59,67 +59,67 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, logic [11:0] CSRCount; logic [177+P.XLEN-1:0] Required; logic [10+2*P.XLEN-1:0] Registers; - logic [12+MAX_CSRS*(P.XLEN+12)-1:0] CSRs; + logic [MAX_CSRS*(P.XLEN+12)-1:0] CSRs; // get signals from the core. - assign StallE = testbench.dut.core.StallE; - assign StallM = testbench.dut.core.StallM; - assign StallW = testbench.dut.core.StallW; - assign FlushE = testbench.dut.core.FlushE; - assign FlushM = testbench.dut.core.FlushM; - assign FlushW = testbench.dut.core.FlushW; - assign InstrValidM = testbench.dut.core.ieu.InstrValidM; - assign InstrRawD = testbench.dut.core.ifu.InstrRawD; - assign PCM = testbench.dut.core.ifu.PCM; - assign Mcycle = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; - assign Minstret = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; - assign TrapM = testbench.dut.core.TrapM; - assign PrivilegeModeW = testbench.dut.core.priv.priv.privmode.PrivilegeModeW; - assign GPRAddr = testbench.dut.core.ieu.dp.regf.a3; - assign GPRWen = testbench.dut.core.ieu.dp.regf.we3; - assign GPRValue = testbench.dut.core.ieu.dp.regf.wd3; - assign FPRAddr = testbench.dut.core.fpu.fpu.fregfile.a4; - assign FPRWen = testbench.dut.core.fpu.fpu.fregfile.we4; - assign FPRValue = testbench.dut.core.fpu.fpu.fregfile.wd4; + assign StallE = dut.core.StallE; + assign StallM = dut.core.StallM; + assign StallW = dut.core.StallW; + assign FlushE = dut.core.FlushE; + assign FlushM = dut.core.FlushM; + assign FlushW = dut.core.FlushW; + assign InstrValidM = dut.core.ieu.InstrValidM; + assign InstrRawD = dut.core.ifu.InstrRawD; + assign PCM = dut.core.ifu.PCM; + assign Mcycle = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; + assign Minstret = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; + assign TrapM = dut.core.TrapM; + assign PrivilegeModeW = dut.core.priv.priv.privmode.PrivilegeModeW; + assign GPRAddr = dut.core.ieu.dp.regf.a3; + assign GPRWen = dut.core.ieu.dp.regf.we3; + assign GPRValue = dut.core.ieu.dp.regf.wd3; + assign FPRAddr = dut.core.fpu.fpu.fregfile.a4; + assign FPRWen = dut.core.fpu.fpu.fregfile.we4; + assign FPRValue = dut.core.fpu.fpu.fregfile.wd4; - assign CSRArray[0] = testbench.dut.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 - assign CSRArray[1] = testbench.dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 - assign CSRArray[2] = testbench.dut.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 - assign CSRArray[3] = testbench.dut.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 - assign CSRArray[4] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 - assign CSRArray[5] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 - assign CSRArray[6] = testbench.dut.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 - assign CSRArray[7] = testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 - assign CSRArray[8] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 - assign CSRArray[9] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 - assign CSRArray[10] = testbench.dut.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 - assign CSRArray[11] = testbench.dut.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A - assign CSRArray[12] = testbench.dut.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 - assign CSRArray[13] = testbench.dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 - assign CSRArray[14] = testbench.dut.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 - assign CSRArray[15] = testbench.dut.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 + assign CSRArray[0] = dut.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 + assign CSRArray[1] = dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 + assign CSRArray[2] = dut.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 + assign CSRArray[3] = dut.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 + assign CSRArray[4] = dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 + assign CSRArray[5] = dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 + assign CSRArray[6] = dut.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 + assign CSRArray[7] = dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 + assign CSRArray[8] = dut.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 + assign CSRArray[9] = dut.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 + assign CSRArray[10] = dut.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 + assign CSRArray[11] = dut.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A + assign CSRArray[12] = dut.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 + assign CSRArray[13] = dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 + assign CSRArray[14] = dut.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 + assign CSRArray[15] = dut.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 assign CSRArray[16] = 0; // 12'hF11 assign CSRArray[17] = 0; // 12'hF12 assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 assign CSRArray[19] = 0; // 12'hF15 assign CSRArray[20] = 0; // 12'h34A // supervisor CSRs - assign CSRArray[21] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 - assign CSRArray[22] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 - assign CSRArray[23] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 - assign CSRArray[24] = testbench.dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 - assign CSRArray[25] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 - assign CSRArray[26] = testbench.dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A - assign CSRArray[27] = testbench.dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 - assign CSRArray[28] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 - assign CSRArray[29] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 - assign CSRArray[30] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 - assign CSRArray[31] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 - assign CSRArray[32] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D + assign CSRArray[21] = dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 + assign CSRArray[22] = dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 + assign CSRArray[23] = dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 + assign CSRArray[24] = dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 + assign CSRArray[25] = dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 + assign CSRArray[26] = dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A + assign CSRArray[27] = dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 + assign CSRArray[28] = dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 + assign CSRArray[29] = dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 + assign CSRArray[30] = dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 + assign CSRArray[31] = dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 + assign CSRArray[32] = dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D // user CSRs - assign CSRArray[33] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 - assign CSRArray[34] = testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 - assign CSRArray[35] = {testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 + assign CSRArray[33] = dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 + assign CSRArray[34] = dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 + assign CSRArray[35] = {dut.core.priv.priv.csr.csru.csru.FRM_REGW, dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 // assign XLENZeros = '0; @@ -163,5 +163,7 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, assign EnabledCSRs[index] = |CSRWenShort; end assign CSRCount = +EnabledCSRs; + assign rvvi = {CSRs, Registers, Required}; + endmodule diff --git a/src/wally/wallypipelinedsoc.sv b/src/wally/wallypipelinedsoc.sv index 1d4680e30..a5dbe0a87 100644 --- a/src/wally/wallypipelinedsoc.sv +++ b/src/wally/wallypipelinedsoc.sv @@ -93,7 +93,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( localparam MAX_CSRS = 3; logic valid; - logic [199+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; + logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .rvvi); endmodule From d1141237eee01f8eadbf0cd7e5892b7021dfa9bf Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 21 May 2024 16:20:53 -0500 Subject: [PATCH 07/95] Removed prefix from rvvi hierarchy so it works without testbench. --- src/wally/rvvisynth.sv | 100 ++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/src/wally/rvvisynth.sv b/src/wally/rvvisynth.sv index 27a1fe6d3..e5801cf09 100644 --- a/src/wally/rvvisynth.sv +++ b/src/wally/rvvisynth.sv @@ -62,64 +62,64 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, logic [MAX_CSRS*(P.XLEN+12)-1:0] CSRs; // get signals from the core. - assign StallE = dut.core.StallE; - assign StallM = dut.core.StallM; - assign StallW = dut.core.StallW; - assign FlushE = dut.core.FlushE; - assign FlushM = dut.core.FlushM; - assign FlushW = dut.core.FlushW; - assign InstrValidM = dut.core.ieu.InstrValidM; - assign InstrRawD = dut.core.ifu.InstrRawD; - assign PCM = dut.core.ifu.PCM; - assign Mcycle = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; - assign Minstret = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; - assign TrapM = dut.core.TrapM; - assign PrivilegeModeW = dut.core.priv.priv.privmode.PrivilegeModeW; - assign GPRAddr = dut.core.ieu.dp.regf.a3; - assign GPRWen = dut.core.ieu.dp.regf.we3; - assign GPRValue = dut.core.ieu.dp.regf.wd3; - assign FPRAddr = dut.core.fpu.fpu.fregfile.a4; - assign FPRWen = dut.core.fpu.fpu.fregfile.we4; - assign FPRValue = dut.core.fpu.fpu.fregfile.wd4; + assign StallE = core.StallE; + assign StallM = core.StallM; + assign StallW = core.StallW; + assign FlushE = core.FlushE; + assign FlushM = core.FlushM; + assign FlushW = core.FlushW; + assign InstrValidM = core.ieu.InstrValidM; + assign InstrRawD = core.ifu.InstrRawD; + assign PCM = core.ifu.PCM; + assign Mcycle = core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; + assign Minstret = core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; + assign TrapM = core.TrapM; + assign PrivilegeModeW = core.priv.priv.privmode.PrivilegeModeW; + assign GPRAddr = core.ieu.dp.regf.a3; + assign GPRWen = core.ieu.dp.regf.we3; + assign GPRValue = core.ieu.dp.regf.wd3; + assign FPRAddr = core.fpu.fpu.fregfile.a4; + assign FPRWen = core.fpu.fpu.fregfile.we4; + assign FPRValue = core.fpu.fpu.fregfile.wd4; - assign CSRArray[0] = dut.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 - assign CSRArray[1] = dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 - assign CSRArray[2] = dut.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 - assign CSRArray[3] = dut.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 - assign CSRArray[4] = dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 - assign CSRArray[5] = dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 - assign CSRArray[6] = dut.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 - assign CSRArray[7] = dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 - assign CSRArray[8] = dut.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 - assign CSRArray[9] = dut.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 - assign CSRArray[10] = dut.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 - assign CSRArray[11] = dut.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A - assign CSRArray[12] = dut.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 - assign CSRArray[13] = dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 - assign CSRArray[14] = dut.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 - assign CSRArray[15] = dut.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 + assign CSRArray[0] = core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 + assign CSRArray[1] = core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 + assign CSRArray[2] = core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 + assign CSRArray[3] = core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 + assign CSRArray[4] = core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 + assign CSRArray[5] = core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 + assign CSRArray[6] = core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 + assign CSRArray[7] = core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 + assign CSRArray[8] = core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 + assign CSRArray[9] = core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 + assign CSRArray[10] = core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 + assign CSRArray[11] = core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A + assign CSRArray[12] = core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 + assign CSRArray[13] = core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 + assign CSRArray[14] = core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 + assign CSRArray[15] = core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 assign CSRArray[16] = 0; // 12'hF11 assign CSRArray[17] = 0; // 12'hF12 assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 assign CSRArray[19] = 0; // 12'hF15 assign CSRArray[20] = 0; // 12'h34A // supervisor CSRs - assign CSRArray[21] = dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 - assign CSRArray[22] = dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 - assign CSRArray[23] = dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 - assign CSRArray[24] = dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 - assign CSRArray[25] = dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 - assign CSRArray[26] = dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A - assign CSRArray[27] = dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 - assign CSRArray[28] = dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 - assign CSRArray[29] = dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 - assign CSRArray[30] = dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 - assign CSRArray[31] = dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 - assign CSRArray[32] = dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D + assign CSRArray[21] = core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 + assign CSRArray[22] = core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 + assign CSRArray[23] = core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 + assign CSRArray[24] = core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 + assign CSRArray[25] = core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 + assign CSRArray[26] = core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A + assign CSRArray[27] = core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 + assign CSRArray[28] = core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 + assign CSRArray[29] = core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 + assign CSRArray[30] = core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 + assign CSRArray[31] = core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 + assign CSRArray[32] = core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D // user CSRs - assign CSRArray[33] = dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 - assign CSRArray[34] = dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 - assign CSRArray[35] = {dut.core.priv.priv.csr.csru.csru.FRM_REGW, dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 + assign CSRArray[33] = core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 + assign CSRArray[34] = core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 + assign CSRArray[35] = {core.priv.priv.csr.csru.csru.FRM_REGW, core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 // assign XLENZeros = '0; From b116c0c9024059390ce75f97df8584a2911f7ae3 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 21 May 2024 18:23:42 -0500 Subject: [PATCH 08/95] Lots of progress on the rvvisynth to ethernet packetizer. Almost producing axi4 commands. --- src/wally/packetizer.sv | 153 +++++++++++++++++++++++++++++++++ src/wally/wallypipelinedsoc.sv | 51 +++++++++++ 2 files changed, 204 insertions(+) create mode 100644 src/wally/packetizer.sv diff --git a/src/wally/packetizer.sv b/src/wally/packetizer.sv new file mode 100644 index 000000000..8df53c1bf --- /dev/null +++ b/src/wally/packetizer.sv @@ -0,0 +1,153 @@ +/////////////////////////////////////////// +// packetizer.sv +// +// Written: Rose Thompson ross1728@gmail.com +// Created: 21 May 2024 +// Modified: 21 May 2024 +// +// Purpose: Converts the compressed RVVI format into AXI 4 burst write transactions. +// +// Documentation: +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module packetizer import cvw::*; #(parameter cvw_t P, + parameter integer MAX_CSRS)( + input logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi, + input logic valid, + input logic m_axi_aclk, m_axi_aresetn, + output logic RVVIStall, + // axi 4 write address channel + output logic [3:0] m_axi_awid, + output logic [12:0] m_axi_awaddr, + output logic [7:0] m_axi_awlen, + output logic [2:0] m_axi_awsize, + output logic [1:0] m_axi_awburst, + output logic [3:0] m_axi_awcache, + output logic m_axi_awvalid, + input logic m_axi_awready, + // axi 4 write data channel + output logic [31:0] m_axi_wdata, + output logic [3:0] m_axi_wstrb, + output logic m_axi_wlast, + output logic m_axi_wvalid, + input logic m_axi_wready, + // axi 4 write response channel + input logic [3:0] m_axi_bid, + input logic [1:0] m_axi_bresp, + input logic m_axi_bvalid, + output logic m_axi_bready, + // axi 4 read address channel + output logic [3:0] m_axi_arid, + output logic [12:0] m_axi_araddr, + output logic [7:0] m_axi_arlen, + output logic [2:0] m_axi_arsize, + output logic [1:0] m_axi_arburst, + output logic [3:0] m_axi_arcache, + output logic m_axi_arvalid, + input logic m_axi_arready, + // axi 4 read data channel + input logic [3:0] m_axi_rid, + input logic [31:0] m_axi_rdata, + input logic [1:0] m_axi_rresp, + input logic m_axi_rlast, + input logic m_axi_rvalid, + output logic m_axi_rready + ); + + localparam TotalFrameLengthBits = 2*48+32+16+187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12); + localparam TotalFrameLengthBytes = TotalFrameLengthBits / 8; + + logic [9:0] WordCount; + logic [11:0] BytesInFrame; + logic TransReady; + logic BurstDone; + logic WordCountReset; + logic WordCountEnable; + logic [47:0] SrcMac, DstMac; + logic [31:0] Tag; + logic [15:0] Length; + logic [TotalFrameLengthBits-1:0] TotalFrame; + logic [31:0] TotalFrameWords [TotalFrameLengthBytes/4-1:0]; + + typedef enum {STATE_RDY, STATE_WAIT, STATE_TRANS, STATE_TRANS_DONE} statetype; + statetype CurrState, NextState; + + always_ff @(posedge m_axi_aclk) begin + if(~m_axi_aresetn) CurrState <= STATE_RDY; + else CurrState <= NextState; + end + + always_comb begin + case(CurrState) + STATE_RDY: if (TransReady & valid) NextState = STATE_TRANS; + else if(~TransReady & valid) NextState = STATE_WAIT; + STATE_WAIT: if(TransReady) NextState = STATE_TRANS; + else NextState = STATE_WAIT; + STATE_TRANS: if(BurstDone) NextState = STATE_RDY; + else NextState = STATE_TRANS; + default: NextState = STATE_RDY; + endcase + end + + assign RVVIStall = CurrState != STATE_RDY; + assign TransReady = m_axi_awready & m_axi_wready; + assign WordCountEnable = (CurrState == STATE_RDY & valid) | (CurrState == STATE_TRANS & TransReady); + assign WordCountReset = CurrState == STATE_RDY; + + + counter #(10) WordCounter(m_axi_aclk, WordCountReset, WordCountEnable, WordCount); + // *** BUG BytesInFrame will eventually depend on the length of the data stored into the ethernet frame + // for now this will be exactly 608 bits (76 bytes, 19 words) + assign BytesInFrame = 12'd76; + assign BurstDone = WordCount == BytesInFrame[11:2]; + + assign m_axi_awid = '0; + assign m_axi_awaddr = '0; // *** bug update to be based on the correct address during each beat. + assign m_axi_awlen = BytesInFrame[11:2]; + assign m_axi_awsize = 3'b010; // 4 bytes + assign m_axi_awburst = 2'b01; // increment + assign m_axi_awcache = '0; + assign m_axi_awvalid = (CurrState == STATE_RDY & valid) | CurrState == STATE_TRANS; + genvar index; + for (index = 0; index < TotalFrameLengthBytes/4; index++) begin + assign TotalFrameWords[index] = TotalFrame[(index*32)+32-1 : (index*32)]; + end + + assign TotalFrame = {rvvi, Length, Tag, DstMac, SrcMac}; + + // *** fix me later + assign SrcMac = '0; + assign DstMac = '0; + assign Tag = '0; + assign Length = BytesInFrame + 16'd6 + 16'd6 + 16'd4 + 16'd2; + + assign m_axi_wdata = TotalFrameWords[WordCount]; + assign m_axi_wstrb = '1; + assign m_axi_wlast = BurstDone; + assign m_axi_wvalid = (CurrState == STATE_RDY & valid) | (CurrState == STATE_TRANS); + + + assign m_axi_bready = 1'b1; // *** probably wrong. + + // we aren't using the read channels. This ethernet device isn't going to read anything for now + assign {m_axi_arid, m_axi_araddr, m_axi_arlen, m_axi_arsize, m_axi_arburst, m_axi_arcache, m_axi_arvalid, m_axi_rready} = '0; + +endmodule + diff --git a/src/wally/wallypipelinedsoc.sv b/src/wally/wallypipelinedsoc.sv index a5dbe0a87..d2cf7226e 100644 --- a/src/wally/wallypipelinedsoc.sv +++ b/src/wally/wallypipelinedsoc.sv @@ -95,5 +95,56 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( logic valid; logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .rvvi); + + logic [3:0] m_axi_awid; + logic [12:0] m_axi_awaddr; + logic [7:0] m_axi_awlen; + logic [2:0] m_axi_awsize; + logic [1:0] m_axi_awburst; + logic [3:0] m_axi_awcache; + logic m_axi_awvalid; + logic m_axi_awready; + // axi 4 write data channel + logic [31:0] m_axi_wdata; + logic [3:0] m_axi_wstrb; + logic m_axi_wlast; + logic m_axi_wvalid; + logic m_axi_wready; + // axi 4 write response channel + logic [3:0] m_axi_bid; + logic [1:0] m_axi_bresp; + logic m_axi_bvalid; + logic m_axi_bready; + // axi 4 read address channel + logic [3:0] m_axi_arid; + logic [12:0] m_axi_araddr; + logic [7:0] m_axi_arlen; + logic [2:0] m_axi_arsize; + logic [1:0] m_axi_arburst; + logic [3:0] m_axi_arcache; + logic m_axi_arvalid; + logic m_axi_arready; + // axi 4 read data channel + logic [3:0] m_axi_rid; + logic [31:0] m_axi_rdata; + logic [1:0] m_axi_rresp; + logic m_axi_rlast; + logic m_axi_rvalid; + logic m_axi_rready; + + + + logic RVVIStall; + + packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, + .m_axi_awid, .m_axi_awaddr, .m_axi_awlen, .m_axi_awsize, .m_axi_awburst, .m_axi_awcache, .m_axi_awvalid, + .m_axi_awready, .m_axi_wdata, .m_axi_wstrb, .m_axi_wlast, .m_axi_wvalid, .m_axi_wready, .m_axi_bid, + .m_axi_bresp, .m_axi_bvalid, .m_axi_bready, .m_axi_arid, .m_axi_araddr, .m_axi_arlen, .m_axi_arsize, + .m_axi_arburst, .m_axi_arcache, .m_axi_arvalid, .m_axi_arready, .m_axi_rid, .m_axi_rdata, .m_axi_rresp, + .m_axi_rlast, .m_axi_rvalid, .m_axi_rready); + + // *** finally fake the axi4 interface + assign m_axi_awready = '1; + assign m_axi_wready = '1; endmodule From e5b8fd35b0d9007e60d260d25a7991feefe3dbc1 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Wed, 22 May 2024 09:56:12 -0500 Subject: [PATCH 09/95] Successfully added RVVIStall for back pressure to slow down the pipeline if the ethernet or host computer running imperasDV can't keep up. --- src/hazard/hazard.sv | 4 ++-- src/wally/packetizer.sv | 1 - src/wally/wallypipelinedcore.sv | 5 +++-- src/wally/wallypipelinedsoc.sv | 12 +++++++----- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index 5d2611dda..ed3b6da3a 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -31,7 +31,7 @@ module hazard import cvw::*; #(parameter cvw_t P) ( input logic BPWrongE, CSRWriteFenceM, RetM, TrapM, input logic StructuralStallD, input logic LSUStallM, IFUStallF, - input logic FPUStallD, + input logic FPUStallD, RVVIStall, input logic DivBusyE, FDivBusyE, input logic wfiM, IntPendingM, // Stall & flush outputs @@ -89,7 +89,7 @@ module hazard import cvw::*; #(parameter cvw_t P) ( // Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1. // assign StallWCause = ((IFUStallF & ~FlushDCause) | LSUStallM) & ~FlushWCause; // Because FlushWCause is a strict subset of FlushDCause, FlushWCause is factored out. - assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause); + assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause) | RVVIStall; // Stall each stage for cause or if the next stage is stalled // coverage off: StallFCause is always 0 diff --git a/src/wally/packetizer.sv b/src/wally/packetizer.sv index 8df53c1bf..4dc68dcab 100644 --- a/src/wally/packetizer.sv +++ b/src/wally/packetizer.sv @@ -143,7 +143,6 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign m_axi_wlast = BurstDone; assign m_axi_wvalid = (CurrState == STATE_RDY & valid) | (CurrState == STATE_TRANS); - assign m_axi_bready = 1'b1; // *** probably wrong. // we aren't using the read channels. This ethernet device isn't going to read anything for now diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 9cc6686fc..335f8cfb9 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -44,7 +44,8 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( output logic [2:0] HBURST, output logic [3:0] HPROT, output logic [1:0] HTRANS, - output logic HMASTLOCK + output logic HMASTLOCK, + input logic RVVIStall ); logic StallF, StallD, StallE, StallM, StallW; @@ -274,7 +275,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .BPWrongE, .CSRWriteFenceM, .RetM, .TrapM, .StructuralStallD, .LSUStallM, .IFUStallF, - .FPUStallD, + .FPUStallD, .RVVIStall, .DivBusyE, .FDivBusyE, .wfiM, .IntPendingM, // Stall & flush outputs diff --git a/src/wally/wallypipelinedsoc.sv b/src/wally/wallypipelinedsoc.sv index d2cf7226e..aaf52f550 100644 --- a/src/wally/wallypipelinedsoc.sv +++ b/src/wally/wallypipelinedsoc.sv @@ -68,6 +68,11 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( logic [63:0] MTIME_CLINT; // from CLINT to CSRs logic MExtInt,SExtInt; // from PLIC + localparam MAX_CSRS = 3; + logic valid; + logic RVVIStall; + logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; + // synchronize reset to SOC clock domain synchronizer resetsync(.clk, .d(reset_ext), .q(reset)); @@ -75,7 +80,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( wallypipelinedcore #(P) core(.clk, .reset, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, - .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK + .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .RVVIStall ); // instantiate uncore if a bus interface exists @@ -91,9 +96,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( end - localparam MAX_CSRS = 3; - logic valid; - logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; + rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .rvvi); logic [3:0] m_axi_awid; @@ -134,7 +137,6 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( - logic RVVIStall; packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, .m_axi_awid, .m_axi_awaddr, .m_axi_awlen, .m_axi_awsize, .m_axi_awburst, .m_axi_awcache, .m_axi_awvalid, From bf9f45d31974fc69dc88ff4c923d8547f843e519 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 24 May 2024 11:25:42 -0500 Subject: [PATCH 10/95] We have a simulation of the ethernet transmission working. This commit does not include the source files for the ethernet as it does not belong to cvw. I'll want to fork that repo and make it a submodule as I need to change the source a bit. --- sim/questa/wave.do | 62 +++++++++---------------------- src/{wally => rvvi}/packetizer.sv | 8 ++-- src/{wally => rvvi}/rvvisynth.sv | 0 src/wally/wallypipelinedsoc.sv | 34 +++++++++++++++-- 4 files changed, 53 insertions(+), 51 deletions(-) rename src/{wally => rvvi}/packetizer.sv (96%) rename src/{wally => rvvi}/rvvisynth.sv (100%) diff --git a/sim/questa/wave.do b/sim/questa/wave.do index d4d9f8f95..a1ae5fe8f 100644 --- a/sim/questa/wave.do +++ b/sim/questa/wave.do @@ -1,25 +1,5 @@ onerror {resume} quietly virtual signal -install /testbench/dut/core/ifu/bpred/bpred { /testbench/dut/core/ifu/bpred/bpred/PostSpillInstrRawF[11:7]} rd -quietly virtual function -install /testbench/dut/rvvisynth -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/rvvisynth/CSRs[11], /testbench/dut/rvvisynth/CSRs[10], /testbench/dut/rvvisynth/CSRs[9], /testbench/dut/rvvisynth/CSRs[8], /testbench/dut/rvvisynth/CSRs[7], /testbench/dut/rvvisynth/CSRs[6], /testbench/dut/rvvisynth/CSRs[5], /testbench/dut/rvvisynth/CSRs[4], /testbench/dut/rvvisynth/CSRs[3], /testbench/dut/rvvisynth/CSRs[2], /testbench/dut/rvvisynth/CSRs[1], /testbench/dut/rvvisynth/CSRs[0] }} NumCSRs -quietly virtual function -install /testbench/dut/rvvisynth -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/rvvisynth/CSRs[23], /testbench/dut/rvvisynth/CSRs[22], /testbench/dut/rvvisynth/CSRs[21], /testbench/dut/rvvisynth/CSRs[20], /testbench/dut/rvvisynth/CSRs[19], /testbench/dut/rvvisynth/CSRs[18], /testbench/dut/rvvisynth/CSRs[17], /testbench/dut/rvvisynth/CSRs[16], /testbench/dut/rvvisynth/CSRs[15], /testbench/dut/rvvisynth/CSRs[14], /testbench/dut/rvvisynth/CSRs[13], /testbench/dut/rvvisynth/CSRs[12] }} CSRAdr0 -quietly virtual function -install /testbench/dut/rvvisynth -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/rvvisynth/CSRs[87], /testbench/dut/rvvisynth/CSRs[86], /testbench/dut/rvvisynth/CSRs[85], /testbench/dut/rvvisynth/CSRs[84], /testbench/dut/rvvisynth/CSRs[83], /testbench/dut/rvvisynth/CSRs[82], /testbench/dut/rvvisynth/CSRs[81], /testbench/dut/rvvisynth/CSRs[80], /testbench/dut/rvvisynth/CSRs[79], /testbench/dut/rvvisynth/CSRs[78], /testbench/dut/rvvisynth/CSRs[77], /testbench/dut/rvvisynth/CSRs[76], /testbench/dut/rvvisynth/CSRs[75], /testbench/dut/rvvisynth/CSRs[74], /testbench/dut/rvvisynth/CSRs[73], /testbench/dut/rvvisynth/CSRs[72], /testbench/dut/rvvisynth/CSRs[71], /testbench/dut/rvvisynth/CSRs[70], /testbench/dut/rvvisynth/CSRs[69], /testbench/dut/rvvisynth/CSRs[68], /testbench/dut/rvvisynth/CSRs[67], /testbench/dut/rvvisynth/CSRs[66], /testbench/dut/rvvisynth/CSRs[65], /testbench/dut/rvvisynth/CSRs[64], /testbench/dut/rvvisynth/CSRs[63], /testbench/dut/rvvisynth/CSRs[62], /testbench/dut/rvvisynth/CSRs[61], /testbench/dut/rvvisynth/CSRs[60], /testbench/dut/rvvisynth/CSRs[59], /testbench/dut/rvvisynth/CSRs[58], /testbench/dut/rvvisynth/CSRs[57], /testbench/dut/rvvisynth/CSRs[56], /testbench/dut/rvvisynth/CSRs[55], /testbench/dut/rvvisynth/CSRs[54], /testbench/dut/rvvisynth/CSRs[53], /testbench/dut/rvvisynth/CSRs[52], /testbench/dut/rvvisynth/CSRs[51], /testbench/dut/rvvisynth/CSRs[50], /testbench/dut/rvvisynth/CSRs[49], /testbench/dut/rvvisynth/CSRs[48], /testbench/dut/rvvisynth/CSRs[47], /testbench/dut/rvvisynth/CSRs[46], /testbench/dut/rvvisynth/CSRs[45], /testbench/dut/rvvisynth/CSRs[44], /testbench/dut/rvvisynth/CSRs[43], /testbench/dut/rvvisynth/CSRs[42], /testbench/dut/rvvisynth/CSRs[41], /testbench/dut/rvvisynth/CSRs[40], /testbench/dut/rvvisynth/CSRs[39], /testbench/dut/rvvisynth/CSRs[38], /testbench/dut/rvvisynth/CSRs[37], /testbench/dut/rvvisynth/CSRs[36], /testbench/dut/rvvisynth/CSRs[35], /testbench/dut/rvvisynth/CSRs[34], /testbench/dut/rvvisynth/CSRs[33], /testbench/dut/rvvisynth/CSRs[32], /testbench/dut/rvvisynth/CSRs[31], /testbench/dut/rvvisynth/CSRs[30], /testbench/dut/rvvisynth/CSRs[29], /testbench/dut/rvvisynth/CSRs[28], /testbench/dut/rvvisynth/CSRs[27], /testbench/dut/rvvisynth/CSRs[26], /testbench/dut/rvvisynth/CSRs[25], /testbench/dut/rvvisynth/CSRs[24] }} CSRData0 -quietly virtual function -install /testbench/dut/rvvisynth -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/rvvisynth/CSRs[163], /testbench/dut/rvvisynth/CSRs[162], /testbench/dut/rvvisynth/CSRs[161], /testbench/dut/rvvisynth/CSRs[160], /testbench/dut/rvvisynth/CSRs[159], /testbench/dut/rvvisynth/CSRs[158], /testbench/dut/rvvisynth/CSRs[157], /testbench/dut/rvvisynth/CSRs[156], /testbench/dut/rvvisynth/CSRs[155], /testbench/dut/rvvisynth/CSRs[154], /testbench/dut/rvvisynth/CSRs[153], /testbench/dut/rvvisynth/CSRs[152], /testbench/dut/rvvisynth/CSRs[151], /testbench/dut/rvvisynth/CSRs[150], /testbench/dut/rvvisynth/CSRs[149], /testbench/dut/rvvisynth/CSRs[148], /testbench/dut/rvvisynth/CSRs[147], /testbench/dut/rvvisynth/CSRs[146], /testbench/dut/rvvisynth/CSRs[145], /testbench/dut/rvvisynth/CSRs[144], /testbench/dut/rvvisynth/CSRs[143], /testbench/dut/rvvisynth/CSRs[142], /testbench/dut/rvvisynth/CSRs[141], /testbench/dut/rvvisynth/CSRs[140], /testbench/dut/rvvisynth/CSRs[139], /testbench/dut/rvvisynth/CSRs[138], /testbench/dut/rvvisynth/CSRs[137], /testbench/dut/rvvisynth/CSRs[136], /testbench/dut/rvvisynth/CSRs[135], /testbench/dut/rvvisynth/CSRs[134], /testbench/dut/rvvisynth/CSRs[133], /testbench/dut/rvvisynth/CSRs[132], /testbench/dut/rvvisynth/CSRs[131], /testbench/dut/rvvisynth/CSRs[130], /testbench/dut/rvvisynth/CSRs[129], /testbench/dut/rvvisynth/CSRs[128], /testbench/dut/rvvisynth/CSRs[127], /testbench/dut/rvvisynth/CSRs[126], /testbench/dut/rvvisynth/CSRs[125], /testbench/dut/rvvisynth/CSRs[124], /testbench/dut/rvvisynth/CSRs[123], /testbench/dut/rvvisynth/CSRs[122], /testbench/dut/rvvisynth/CSRs[121], /testbench/dut/rvvisynth/CSRs[120], /testbench/dut/rvvisynth/CSRs[119], /testbench/dut/rvvisynth/CSRs[118], /testbench/dut/rvvisynth/CSRs[117], /testbench/dut/rvvisynth/CSRs[116], /testbench/dut/rvvisynth/CSRs[115], /testbench/dut/rvvisynth/CSRs[114], /testbench/dut/rvvisynth/CSRs[113], /testbench/dut/rvvisynth/CSRs[112], /testbench/dut/rvvisynth/CSRs[111], /testbench/dut/rvvisynth/CSRs[110], /testbench/dut/rvvisynth/CSRs[109], /testbench/dut/rvvisynth/CSRs[108], /testbench/dut/rvvisynth/CSRs[107], /testbench/dut/rvvisynth/CSRs[106], /testbench/dut/rvvisynth/CSRs[105], /testbench/dut/rvvisynth/CSRs[104], /testbench/dut/rvvisynth/CSRs[103], /testbench/dut/rvvisynth/CSRs[102], /testbench/dut/rvvisynth/CSRs[101], /testbench/dut/rvvisynth/CSRs[100] }} CSRData1 -quietly virtual function -install /testbench/dut/rvvisynth -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/rvvisynth/CSRs[175], /testbench/dut/rvvisynth/CSRs[174], /testbench/dut/rvvisynth/CSRs[173], /testbench/dut/rvvisynth/CSRs[172], /testbench/dut/rvvisynth/CSRs[171], /testbench/dut/rvvisynth/CSRs[170], /testbench/dut/rvvisynth/CSRs[169], /testbench/dut/rvvisynth/CSRs[168], /testbench/dut/rvvisynth/CSRs[167], /testbench/dut/rvvisynth/CSRs[166], /testbench/dut/rvvisynth/CSRs[165], /testbench/dut/rvvisynth/CSRs[164] }} CSRAdr2 -quietly virtual function -install /testbench/dut/rvvisynth -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/rvvisynth/CSRs[239], /testbench/dut/rvvisynth/CSRs[238], /testbench/dut/rvvisynth/CSRs[237], /testbench/dut/rvvisynth/CSRs[236], /testbench/dut/rvvisynth/CSRs[235], /testbench/dut/rvvisynth/CSRs[234], /testbench/dut/rvvisynth/CSRs[233], /testbench/dut/rvvisynth/CSRs[232], /testbench/dut/rvvisynth/CSRs[231], /testbench/dut/rvvisynth/CSRs[230], /testbench/dut/rvvisynth/CSRs[229], /testbench/dut/rvvisynth/CSRs[228], /testbench/dut/rvvisynth/CSRs[227], /testbench/dut/rvvisynth/CSRs[226], /testbench/dut/rvvisynth/CSRs[225], /testbench/dut/rvvisynth/CSRs[224], /testbench/dut/rvvisynth/CSRs[223], /testbench/dut/rvvisynth/CSRs[222], /testbench/dut/rvvisynth/CSRs[221], /testbench/dut/rvvisynth/CSRs[220], /testbench/dut/rvvisynth/CSRs[219], /testbench/dut/rvvisynth/CSRs[218], /testbench/dut/rvvisynth/CSRs[217], /testbench/dut/rvvisynth/CSRs[216], /testbench/dut/rvvisynth/CSRs[215], /testbench/dut/rvvisynth/CSRs[214], /testbench/dut/rvvisynth/CSRs[213], /testbench/dut/rvvisynth/CSRs[212], /testbench/dut/rvvisynth/CSRs[211], /testbench/dut/rvvisynth/CSRs[210], /testbench/dut/rvvisynth/CSRs[209], /testbench/dut/rvvisynth/CSRs[208], /testbench/dut/rvvisynth/CSRs[207], /testbench/dut/rvvisynth/CSRs[206], /testbench/dut/rvvisynth/CSRs[205], /testbench/dut/rvvisynth/CSRs[204], /testbench/dut/rvvisynth/CSRs[203], /testbench/dut/rvvisynth/CSRs[202], /testbench/dut/rvvisynth/CSRs[201], /testbench/dut/rvvisynth/CSRs[200], /testbench/dut/rvvisynth/CSRs[199], /testbench/dut/rvvisynth/CSRs[198], /testbench/dut/rvvisynth/CSRs[197], /testbench/dut/rvvisynth/CSRs[196], /testbench/dut/rvvisynth/CSRs[195], /testbench/dut/rvvisynth/CSRs[194], /testbench/dut/rvvisynth/CSRs[193], /testbench/dut/rvvisynth/CSRs[192], /testbench/dut/rvvisynth/CSRs[191], /testbench/dut/rvvisynth/CSRs[190], /testbench/dut/rvvisynth/CSRs[189], /testbench/dut/rvvisynth/CSRs[188], /testbench/dut/rvvisynth/CSRs[187], /testbench/dut/rvvisynth/CSRs[186], /testbench/dut/rvvisynth/CSRs[185], /testbench/dut/rvvisynth/CSRs[184], /testbench/dut/rvvisynth/CSRs[183], /testbench/dut/rvvisynth/CSRs[182], /testbench/dut/rvvisynth/CSRs[181], /testbench/dut/rvvisynth/CSRs[180], /testbench/dut/rvvisynth/CSRs[179], /testbench/dut/rvvisynth/CSRs[178], /testbench/dut/rvvisynth/CSRs[177], /testbench/dut/rvvisynth/CSRs[176] }} CSRData2 -quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Required[63], /testbench/dut/Required[62], /testbench/dut/Required[61], /testbench/dut/Required[60], /testbench/dut/Required[59], /testbench/dut/Required[58], /testbench/dut/Required[57], /testbench/dut/Required[56], /testbench/dut/Required[55], /testbench/dut/Required[54], /testbench/dut/Required[53], /testbench/dut/Required[52], /testbench/dut/Required[51], /testbench/dut/Required[50], /testbench/dut/Required[49], /testbench/dut/Required[48], /testbench/dut/Required[47], /testbench/dut/Required[46], /testbench/dut/Required[45], /testbench/dut/Required[44], /testbench/dut/Required[43], /testbench/dut/Required[42], /testbench/dut/Required[41], /testbench/dut/Required[40], /testbench/dut/Required[39], /testbench/dut/Required[38], /testbench/dut/Required[37], /testbench/dut/Required[36], /testbench/dut/Required[35], /testbench/dut/Required[34], /testbench/dut/Required[33], /testbench/dut/Required[32], /testbench/dut/Required[31], /testbench/dut/Required[30], /testbench/dut/Required[29], /testbench/dut/Required[28], /testbench/dut/Required[27], /testbench/dut/Required[26], /testbench/dut/Required[25], /testbench/dut/Required[24], /testbench/dut/Required[23], /testbench/dut/Required[22], /testbench/dut/Required[21], /testbench/dut/Required[20], /testbench/dut/Required[19], /testbench/dut/Required[18], /testbench/dut/Required[17], /testbench/dut/Required[16], /testbench/dut/Required[15], /testbench/dut/Required[14], /testbench/dut/Required[13], /testbench/dut/Required[12], /testbench/dut/Required[11], /testbench/dut/Required[10], /testbench/dut/Required[9], /testbench/dut/Required[8], /testbench/dut/Required[7], /testbench/dut/Required[6], /testbench/dut/Required[5], /testbench/dut/Required[4], /testbench/dut/Required[3], /testbench/dut/Required[2], /testbench/dut/Required[1], /testbench/dut/Required[0] }} PCW -quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Required[95], /testbench/dut/Required[94], /testbench/dut/Required[93], /testbench/dut/Required[92], /testbench/dut/Required[91], /testbench/dut/Required[90], /testbench/dut/Required[89], /testbench/dut/Required[88], /testbench/dut/Required[87], /testbench/dut/Required[86], /testbench/dut/Required[85], /testbench/dut/Required[84], /testbench/dut/Required[83], /testbench/dut/Required[82], /testbench/dut/Required[81], /testbench/dut/Required[80], /testbench/dut/Required[79], /testbench/dut/Required[78], /testbench/dut/Required[77], /testbench/dut/Required[76], /testbench/dut/Required[75], /testbench/dut/Required[74], /testbench/dut/Required[73], /testbench/dut/Required[72], /testbench/dut/Required[71], /testbench/dut/Required[70], /testbench/dut/Required[69], /testbench/dut/Required[68], /testbench/dut/Required[67], /testbench/dut/Required[66], /testbench/dut/Required[65], /testbench/dut/Required[64] }} InstrW -quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Required[159], /testbench/dut/Required[158], /testbench/dut/Required[157], /testbench/dut/Required[156], /testbench/dut/Required[155], /testbench/dut/Required[154], /testbench/dut/Required[153], /testbench/dut/Required[152], /testbench/dut/Required[151], /testbench/dut/Required[150], /testbench/dut/Required[149], /testbench/dut/Required[148], /testbench/dut/Required[147], /testbench/dut/Required[146], /testbench/dut/Required[145], /testbench/dut/Required[144], /testbench/dut/Required[143], /testbench/dut/Required[142], /testbench/dut/Required[141], /testbench/dut/Required[140], /testbench/dut/Required[139], /testbench/dut/Required[138], /testbench/dut/Required[137], /testbench/dut/Required[136], /testbench/dut/Required[135], /testbench/dut/Required[134], /testbench/dut/Required[133], /testbench/dut/Required[132], /testbench/dut/Required[131], /testbench/dut/Required[130], /testbench/dut/Required[129], /testbench/dut/Required[128], /testbench/dut/Required[127], /testbench/dut/Required[126], /testbench/dut/Required[125], /testbench/dut/Required[124], /testbench/dut/Required[123], /testbench/dut/Required[122], /testbench/dut/Required[121], /testbench/dut/Required[120], /testbench/dut/Required[119], /testbench/dut/Required[118], /testbench/dut/Required[117], /testbench/dut/Required[116], /testbench/dut/Required[115], /testbench/dut/Required[114], /testbench/dut/Required[113], /testbench/dut/Required[112], /testbench/dut/Required[111], /testbench/dut/Required[110], /testbench/dut/Required[109], /testbench/dut/Required[108], /testbench/dut/Required[107], /testbench/dut/Required[106], /testbench/dut/Required[105], /testbench/dut/Required[104], /testbench/dut/Required[103], /testbench/dut/Required[102], /testbench/dut/Required[101], /testbench/dut/Required[100], /testbench/dut/Required[99], /testbench/dut/Required[98], /testbench/dut/Required[97], /testbench/dut/Required[96] }} Mcycle -quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Required[223], /testbench/dut/Required[222], /testbench/dut/Required[221], /testbench/dut/Required[220], /testbench/dut/Required[219], /testbench/dut/Required[218], /testbench/dut/Required[217], /testbench/dut/Required[216], /testbench/dut/Required[215], /testbench/dut/Required[214], /testbench/dut/Required[213], /testbench/dut/Required[212], /testbench/dut/Required[211], /testbench/dut/Required[210], /testbench/dut/Required[209], /testbench/dut/Required[208], /testbench/dut/Required[207], /testbench/dut/Required[206], /testbench/dut/Required[205], /testbench/dut/Required[204], /testbench/dut/Required[203], /testbench/dut/Required[202], /testbench/dut/Required[201], /testbench/dut/Required[200], /testbench/dut/Required[199], /testbench/dut/Required[198], /testbench/dut/Required[197], /testbench/dut/Required[196], /testbench/dut/Required[195], /testbench/dut/Required[194], /testbench/dut/Required[193], /testbench/dut/Required[192], /testbench/dut/Required[191], /testbench/dut/Required[190], /testbench/dut/Required[189], /testbench/dut/Required[188], /testbench/dut/Required[187], /testbench/dut/Required[186], /testbench/dut/Required[185], /testbench/dut/Required[184], /testbench/dut/Required[183], /testbench/dut/Required[182], /testbench/dut/Required[181], /testbench/dut/Required[180], /testbench/dut/Required[179], /testbench/dut/Required[178], /testbench/dut/Required[177], /testbench/dut/Required[176], /testbench/dut/Required[175], /testbench/dut/Required[174], /testbench/dut/Required[173], /testbench/dut/Required[172], /testbench/dut/Required[171], /testbench/dut/Required[170], /testbench/dut/Required[169], /testbench/dut/Required[168], /testbench/dut/Required[167], /testbench/dut/Required[166], /testbench/dut/Required[165], /testbench/dut/Required[164], /testbench/dut/Required[163], /testbench/dut/Required[162], /testbench/dut/Required[161], /testbench/dut/Required[160] }} Minstret -quietly virtual signal -install /testbench/dut {/testbench/dut/Required[224] } TrapW -quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Required[226], /testbench/dut/Required[225] }} PrivilegeModeW -quietly virtual signal -install /testbench/dut {/testbench/dut/Registers[0] } GPRWen -quietly virtual signal -install /testbench/dut {/testbench/dut/Registers[1] } FPRWen -quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Registers[6], /testbench/dut/Registers[5], /testbench/dut/Registers[4], /testbench/dut/Registers[3], /testbench/dut/Registers[2] }} GPRAdr -quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Registers[71], /testbench/dut/Registers[70], /testbench/dut/Registers[69], /testbench/dut/Registers[68], /testbench/dut/Registers[67], /testbench/dut/Registers[66], /testbench/dut/Registers[65], /testbench/dut/Registers[64], /testbench/dut/Registers[63], /testbench/dut/Registers[62], /testbench/dut/Registers[61], /testbench/dut/Registers[60], /testbench/dut/Registers[59], /testbench/dut/Registers[58], /testbench/dut/Registers[57], /testbench/dut/Registers[56], /testbench/dut/Registers[55], /testbench/dut/Registers[54], /testbench/dut/Registers[53], /testbench/dut/Registers[52], /testbench/dut/Registers[51], /testbench/dut/Registers[50], /testbench/dut/Registers[49], /testbench/dut/Registers[48], /testbench/dut/Registers[47], /testbench/dut/Registers[46], /testbench/dut/Registers[45], /testbench/dut/Registers[44], /testbench/dut/Registers[43], /testbench/dut/Registers[42], /testbench/dut/Registers[41], /testbench/dut/Registers[40], /testbench/dut/Registers[39], /testbench/dut/Registers[38], /testbench/dut/Registers[37], /testbench/dut/Registers[36], /testbench/dut/Registers[35], /testbench/dut/Registers[34], /testbench/dut/Registers[33], /testbench/dut/Registers[32], /testbench/dut/Registers[31], /testbench/dut/Registers[30], /testbench/dut/Registers[29], /testbench/dut/Registers[28], /testbench/dut/Registers[27], /testbench/dut/Registers[26], /testbench/dut/Registers[25], /testbench/dut/Registers[24], /testbench/dut/Registers[23], /testbench/dut/Registers[22], /testbench/dut/Registers[21], /testbench/dut/Registers[20], /testbench/dut/Registers[19], /testbench/dut/Registers[18], /testbench/dut/Registers[17], /testbench/dut/Registers[16], /testbench/dut/Registers[15], /testbench/dut/Registers[14], /testbench/dut/Registers[13], /testbench/dut/Registers[12], /testbench/dut/Registers[11], /testbench/dut/Registers[10], /testbench/dut/Registers[9], /testbench/dut/Registers[8], /testbench/dut/Registers[7] }} GPRValue -quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Registers[76], /testbench/dut/Registers[75], /testbench/dut/Registers[74], /testbench/dut/Registers[73], /testbench/dut/Registers[72], /testbench/dut/Registers[71] }} GPRAdr001 -quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Registers[139], /testbench/dut/Registers[138], /testbench/dut/Registers[137], /testbench/dut/Registers[136], /testbench/dut/Registers[135], /testbench/dut/Registers[134], /testbench/dut/Registers[133], /testbench/dut/Registers[132], /testbench/dut/Registers[131], /testbench/dut/Registers[130], /testbench/dut/Registers[129], /testbench/dut/Registers[128], /testbench/dut/Registers[127], /testbench/dut/Registers[126], /testbench/dut/Registers[125], /testbench/dut/Registers[124], /testbench/dut/Registers[123], /testbench/dut/Registers[122], /testbench/dut/Registers[121], /testbench/dut/Registers[120], /testbench/dut/Registers[119], /testbench/dut/Registers[118], /testbench/dut/Registers[117], /testbench/dut/Registers[116], /testbench/dut/Registers[115], /testbench/dut/Registers[114], /testbench/dut/Registers[113], /testbench/dut/Registers[112], /testbench/dut/Registers[111], /testbench/dut/Registers[110], /testbench/dut/Registers[109], /testbench/dut/Registers[108], /testbench/dut/Registers[107], /testbench/dut/Registers[106], /testbench/dut/Registers[105], /testbench/dut/Registers[104], /testbench/dut/Registers[103], /testbench/dut/Registers[102], /testbench/dut/Registers[101], /testbench/dut/Registers[100], /testbench/dut/Registers[99], /testbench/dut/Registers[98], /testbench/dut/Registers[97], /testbench/dut/Registers[96], /testbench/dut/Registers[95], /testbench/dut/Registers[94], /testbench/dut/Registers[93], /testbench/dut/Registers[92], /testbench/dut/Registers[91], /testbench/dut/Registers[90], /testbench/dut/Registers[89], /testbench/dut/Registers[88], /testbench/dut/Registers[87], /testbench/dut/Registers[86], /testbench/dut/Registers[85], /testbench/dut/Registers[84], /testbench/dut/Registers[83], /testbench/dut/Registers[82], /testbench/dut/Registers[81], /testbench/dut/Registers[80], /testbench/dut/Registers[79], /testbench/dut/Registers[78], /testbench/dut/Registers[77], /testbench/dut/Registers[76] }} FPRValue -quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Registers[70], /testbench/dut/Registers[69], /testbench/dut/Registers[68], /testbench/dut/Registers[67], /testbench/dut/Registers[66], /testbench/dut/Registers[65], /testbench/dut/Registers[64], /testbench/dut/Registers[63], /testbench/dut/Registers[62], /testbench/dut/Registers[61], /testbench/dut/Registers[60], /testbench/dut/Registers[59], /testbench/dut/Registers[58], /testbench/dut/Registers[57], /testbench/dut/Registers[56], /testbench/dut/Registers[55], /testbench/dut/Registers[54], /testbench/dut/Registers[53], /testbench/dut/Registers[52], /testbench/dut/Registers[51], /testbench/dut/Registers[50], /testbench/dut/Registers[49], /testbench/dut/Registers[48], /testbench/dut/Registers[47], /testbench/dut/Registers[46], /testbench/dut/Registers[45], /testbench/dut/Registers[44], /testbench/dut/Registers[43], /testbench/dut/Registers[42], /testbench/dut/Registers[41], /testbench/dut/Registers[40], /testbench/dut/Registers[39], /testbench/dut/Registers[38], /testbench/dut/Registers[37], /testbench/dut/Registers[36], /testbench/dut/Registers[35], /testbench/dut/Registers[34], /testbench/dut/Registers[33], /testbench/dut/Registers[32], /testbench/dut/Registers[31], /testbench/dut/Registers[30], /testbench/dut/Registers[29], /testbench/dut/Registers[28], /testbench/dut/Registers[27], /testbench/dut/Registers[26], /testbench/dut/Registers[25], /testbench/dut/Registers[24], /testbench/dut/Registers[23], /testbench/dut/Registers[22], /testbench/dut/Registers[21], /testbench/dut/Registers[20], /testbench/dut/Registers[19], /testbench/dut/Registers[18], /testbench/dut/Registers[17], /testbench/dut/Registers[16], /testbench/dut/Registers[15], /testbench/dut/Registers[14], /testbench/dut/Registers[13], /testbench/dut/Registers[12], /testbench/dut/Registers[11], /testbench/dut/Registers[10], /testbench/dut/Registers[9], /testbench/dut/Registers[8], /testbench/dut/Registers[7] }} GPRValue001 -quietly virtual function -install /testbench/dut -env /testbench/genblk3/#ALWAYS#441,293,397 { &{/testbench/dut/Registers[75], /testbench/dut/Registers[74], /testbench/dut/Registers[73], /testbench/dut/Registers[72], /testbench/dut/Registers[71] }} FPRAdr quietly WaveActivateNextPane {} 0 add wave -noupdate /testbench/clk add wave -noupdate /testbench/reset @@ -680,31 +660,25 @@ add wave -noupdate -group wfi /testbench/dut/core/priv/priv/pmd/WFITimeoutM add wave -noupdate -expand -group testbench /testbench/DCacheFlushStart add wave -noupdate /testbench/dut/core/lsu/hptw/hptw/HPTWLoadPageFault add wave -noupdate /testbench/dut/core/lsu/hptw/hptw/HPTWLoadPageFaultDelay -add wave -noupdate /testbench/dut/GPRWen -add wave -noupdate /testbench/dut/FPRWen -add wave -noupdate /testbench/dut/GPRAdr -add wave -noupdate /testbench/dut/FPRValue -add wave -noupdate /testbench/dut/GPRValue001 -add wave -noupdate /testbench/dut/FPRAdr -add wave -noupdate /testbench/dut/Registers -add wave -noupdate /testbench/dut/PCW -add wave -noupdate /testbench/dut/InstrW -add wave -noupdate /testbench/dut/Mcycle -add wave -noupdate /testbench/dut/Minstret -add wave -noupdate /testbench/dut/TrapW -add wave -noupdate /testbench/dut/PrivilegeModeW -add wave -noupdate /testbench/dut/Required -add wave -noupdate /testbench/dut/rvvisynth/NumCSRs -add wave -noupdate /testbench/dut/rvvisynth/CSRAdr0 -add wave -noupdate /testbench/dut/rvvisynth/CSRData0 -add wave -noupdate /testbench/dut/rvvisynth/CSRData1 -add wave -noupdate /testbench/dut/rvvisynth/CSRAdr2 -add wave -noupdate /testbench/dut/rvvisynth/CSRData2 add wave -noupdate /testbench/dut/rvvisynth/CSRs -add wave -noupdate /testbench/dut/rvvisynth/valid +add wave -noupdate -expand -group rvvi /testbench/dut/rvvisynth/clk +add wave -noupdate -expand -group rvvi /testbench/dut/rvvisynth/rvvi +add wave -noupdate -expand -group rvvi /testbench/dut/rvvisynth/valid +add wave -noupdate -expand -group packetizer -color Gold /testbench/dut/packetizer/CurrState +add wave -noupdate -expand -group packetizer -radix unsigned /testbench/dut/packetizer/WordCount +add wave -noupdate -expand -group packetizer /testbench/dut/packetizer/RVVIStall +add wave -noupdate -expand -group packetizer -expand -group axi-write-interface /testbench/dut/packetizer/m_axi_wdata +add wave -noupdate -expand -group packetizer -expand -group axi-write-interface /testbench/dut/packetizer/m_axi_wlast +add wave -noupdate -expand -group packetizer -expand -group axi-write-interface /testbench/dut/packetizer/m_axi_wstrb +add wave -noupdate -expand -group packetizer -expand -group axi-write-interface /testbench/dut/packetizer/m_axi_wvalid +add wave -noupdate -expand -group packetizer -expand -group axi-write-interface /testbench/dut/packetizer/m_axi_wready +add wave -noupdate -expand -group eth /testbench/dut/ethernet/mii_tx_clk +add wave -noupdate -expand -group eth /testbench/dut/ethernet/mii_txd +add wave -noupdate -expand -group eth /testbench/dut/ethernet/mii_tx_en +add wave -noupdate -expand -group eth /testbench/dut/ethernet/mii_tx_er TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 4} {6586 ns} 1} {{Cursor 4} {2112952 ns} 0} {{Cursor 3} {403021 ns} 1} -quietly wave cursor active 2 +WaveRestoreCursors {{Cursor 4} {650 ns} 1} {{Cursor 4} {2090 ns} 1} {{Cursor 3} {364 ns} 0} +quietly wave cursor active 3 configure wave -namecolwidth 250 configure wave -valuecolwidth 194 configure wave -justifyvalue left @@ -719,4 +693,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {2039338 ns} {2323972 ns} +WaveRestoreZoom {266 ns} {618 ns} diff --git a/src/wally/packetizer.sv b/src/rvvi/packetizer.sv similarity index 96% rename from src/wally/packetizer.sv rename to src/rvvi/packetizer.sv index 4dc68dcab..00f394ab5 100644 --- a/src/wally/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -116,7 +116,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, // *** BUG BytesInFrame will eventually depend on the length of the data stored into the ethernet frame // for now this will be exactly 608 bits (76 bytes, 19 words) assign BytesInFrame = 12'd76; - assign BurstDone = WordCount == BytesInFrame[11:2]; + assign BurstDone = WordCount == (BytesInFrame[11:2] - 1'b1); assign m_axi_awid = '0; assign m_axi_awaddr = '0; // *** bug update to be based on the correct address during each beat. @@ -133,15 +133,15 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign TotalFrame = {rvvi, Length, Tag, DstMac, SrcMac}; // *** fix me later - assign SrcMac = '0; - assign DstMac = '0; + assign SrcMac = 48'h8F54_0000_1654; // made something up + assign DstMac = 48'h4502_1111_6843; assign Tag = '0; assign Length = BytesInFrame + 16'd6 + 16'd6 + 16'd4 + 16'd2; assign m_axi_wdata = TotalFrameWords[WordCount]; assign m_axi_wstrb = '1; assign m_axi_wlast = BurstDone; - assign m_axi_wvalid = (CurrState == STATE_RDY & valid) | (CurrState == STATE_TRANS); + assign m_axi_wvalid = (CurrState == STATE_TRANS); assign m_axi_bready = 1'b1; // *** probably wrong. diff --git a/src/wally/rvvisynth.sv b/src/rvvi/rvvisynth.sv similarity index 100% rename from src/wally/rvvisynth.sv rename to src/rvvi/rvvisynth.sv diff --git a/src/wally/wallypipelinedsoc.sv b/src/wally/wallypipelinedsoc.sv index aaf52f550..bb9516435 100644 --- a/src/wally/wallypipelinedsoc.sv +++ b/src/wally/wallypipelinedsoc.sv @@ -135,8 +135,13 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( logic m_axi_rvalid; logic m_axi_rready; - - + logic [3:0] mii_txd; + logic mii_tx_en, mii_tx_er; + + logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; + logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; + + packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, .m_axi_awid, .m_axi_awaddr, .m_axi_awlen, .m_axi_awsize, .m_axi_awburst, .m_axi_awcache, .m_axi_awvalid, @@ -145,8 +150,31 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( .m_axi_arburst, .m_axi_arcache, .m_axi_arvalid, .m_axi_arready, .m_axi_rid, .m_axi_rdata, .m_axi_rresp, .m_axi_rlast, .m_axi_rvalid, .m_axi_rready); + eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(reset), .logic_clk(clk), .logic_rst(reset), + .tx_axis_tdata(m_axi_wdata), .tx_axis_tkeep(m_axi_wstrb), .tx_axis_tvalid(m_axi_wvalid), .tx_axis_tready(m_axi_wready), + .tx_axis_tlast(m_axi_wlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), + .rx_axis_tlast(), .rx_axis_tuser(), + + // *** update these + .mii_rx_clk(clk), // *** need to be the mii clock + .mii_rxd('0), + .mii_rx_dv('0), + .mii_rx_er('0), + .mii_tx_clk(clk), // *** needs to be the mii clock + .mii_txd, + .mii_tx_en, + .mii_tx_er, + + // status + .tx_error_underflow, .tx_fifo_overflow, .tx_fifo_bad_frame, .tx_fifo_good_frame, .rx_error_bad_frame, + .rx_error_bad_fcs, .rx_fifo_overflow, .rx_fifo_bad_frame, .rx_fifo_good_frame, + .cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1) + ); + + + // *** finally fake the axi4 interface assign m_axi_awready = '1; - assign m_axi_wready = '1; + //assign m_axi_wready = '1; endmodule From d341974c5bb3cda8fe7d4f1869b0f50280c97323 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 24 May 2024 15:52:13 -0500 Subject: [PATCH 11/95] Have rvvi to ethernet working. Now it is time to move the hardware to the FPGA. Ideally I don't want Wally to actually have any of this code since it's entirely debug code so it will move to the fpga/src directory. Then we'll need to add additional logic to the mmcm to generate the correct clocks. Finally we'll update the I/O to add ethernet. --- src/rvvi/packetizer.sv | 6 +++++- src/wally/wallypipelinedsoc.sv | 10 ++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 00f394ab5..3cf465268 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -85,6 +85,8 @@ module packetizer import cvw::*; #(parameter cvw_t P, logic [15:0] Length; logic [TotalFrameLengthBits-1:0] TotalFrame; logic [31:0] TotalFrameWords [TotalFrameLengthBytes/4-1:0]; + + logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvviDelay; typedef enum {STATE_RDY, STATE_WAIT, STATE_TRANS, STATE_TRANS_DONE} statetype; statetype CurrState, NextState; @@ -111,6 +113,8 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign WordCountEnable = (CurrState == STATE_RDY & valid) | (CurrState == STATE_TRANS & TransReady); assign WordCountReset = CurrState == STATE_RDY; + flopenr #(187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)) rvvireg(m_axi_aclk, ~m_axi_aresetn, valid, rvvi, rvviDelay); + counter #(10) WordCounter(m_axi_aclk, WordCountReset, WordCountEnable, WordCount); // *** BUG BytesInFrame will eventually depend on the length of the data stored into the ethernet frame @@ -130,7 +134,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign TotalFrameWords[index] = TotalFrame[(index*32)+32-1 : (index*32)]; end - assign TotalFrame = {rvvi, Length, Tag, DstMac, SrcMac}; + assign TotalFrame = {rvviDelay, Length, Tag, DstMac, SrcMac}; // *** fix me later assign SrcMac = 48'h8F54_0000_1654; // made something up diff --git a/src/wally/wallypipelinedsoc.sv b/src/wally/wallypipelinedsoc.sv index bb9516435..75265ab29 100644 --- a/src/wally/wallypipelinedsoc.sv +++ b/src/wally/wallypipelinedsoc.sv @@ -99,6 +99,10 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .rvvi); + // a bunch of these signals would be needed for the xilinx ethernet IP + // but I switched to using https://github.com/alexforencich/verilog-ethernet + // so most arn't needed anymore. *** remove once I've confirmed this + // works in synthesis. logic [3:0] m_axi_awid; logic [12:0] m_axi_awaddr; logic [7:0] m_axi_awlen; @@ -140,8 +144,6 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; - - packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, .m_axi_awid, .m_axi_awaddr, .m_axi_awlen, .m_axi_awsize, .m_axi_awburst, .m_axi_awcache, .m_axi_awvalid, @@ -171,10 +173,6 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( .cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1) ); - - - // *** finally fake the axi4 interface assign m_axi_awready = '1; - //assign m_axi_wready = '1; endmodule From 1f7d732dca3d56f1d4943cb324d49259ef40903c Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 24 May 2024 16:10:58 -0500 Subject: [PATCH 12/95] Moved the rvvisynth code to testbench since I only want this for simulation and fpga. --- sim/questa/wave.do | 38 ++++++------- src/rvvi/rvvisynth.sv | 100 ++++++++++++++++----------------- src/wally/wallypipelinedsoc.sv | 88 +---------------------------- testbench/testbench.sv | 92 +++++++++++++++++++++++++++++- testbench/wallywrapper.sv | 5 +- 5 files changed, 166 insertions(+), 157 deletions(-) diff --git a/sim/questa/wave.do b/sim/questa/wave.do index a1ae5fe8f..ec8dd82b3 100644 --- a/sim/questa/wave.do +++ b/sim/questa/wave.do @@ -660,25 +660,25 @@ add wave -noupdate -group wfi /testbench/dut/core/priv/priv/pmd/WFITimeoutM add wave -noupdate -expand -group testbench /testbench/DCacheFlushStart add wave -noupdate /testbench/dut/core/lsu/hptw/hptw/HPTWLoadPageFault add wave -noupdate /testbench/dut/core/lsu/hptw/hptw/HPTWLoadPageFaultDelay -add wave -noupdate /testbench/dut/rvvisynth/CSRs -add wave -noupdate -expand -group rvvi /testbench/dut/rvvisynth/clk -add wave -noupdate -expand -group rvvi /testbench/dut/rvvisynth/rvvi -add wave -noupdate -expand -group rvvi /testbench/dut/rvvisynth/valid -add wave -noupdate -expand -group packetizer -color Gold /testbench/dut/packetizer/CurrState -add wave -noupdate -expand -group packetizer -radix unsigned /testbench/dut/packetizer/WordCount -add wave -noupdate -expand -group packetizer /testbench/dut/packetizer/RVVIStall -add wave -noupdate -expand -group packetizer -expand -group axi-write-interface /testbench/dut/packetizer/m_axi_wdata -add wave -noupdate -expand -group packetizer -expand -group axi-write-interface /testbench/dut/packetizer/m_axi_wlast -add wave -noupdate -expand -group packetizer -expand -group axi-write-interface /testbench/dut/packetizer/m_axi_wstrb -add wave -noupdate -expand -group packetizer -expand -group axi-write-interface /testbench/dut/packetizer/m_axi_wvalid -add wave -noupdate -expand -group packetizer -expand -group axi-write-interface /testbench/dut/packetizer/m_axi_wready -add wave -noupdate -expand -group eth /testbench/dut/ethernet/mii_tx_clk -add wave -noupdate -expand -group eth /testbench/dut/ethernet/mii_txd -add wave -noupdate -expand -group eth /testbench/dut/ethernet/mii_tx_en -add wave -noupdate -expand -group eth /testbench/dut/ethernet/mii_tx_er +add wave -noupdate -expand -group rvvi /testbench/rvvi_synth/rvvisynth/clk +add wave -noupdate -expand -group rvvi /testbench/rvvi_synth/rvvisynth/rvvi +add wave -noupdate -expand -group rvvi /testbench/rvvi_synth/rvvisynth/valid +add wave -noupdate -group packetizer -color Gold /testbench/rvvi_synth/packetizer/CurrState +add wave -noupdate -group packetizer -radix unsigned /testbench/rvvi_synth/packetizer/WordCount +add wave -noupdate -group packetizer /testbench/rvvi_synth/packetizer/RVVIStall +add wave -noupdate -group packetizer /testbench/rvvi_synth/packetizer/rvviDelay +add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/m_axi_wdata +add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/m_axi_wlast +add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/m_axi_wstrb +add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/m_axi_wvalid +add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/m_axi_wready +add wave -noupdate -expand -group eth /testbench/rvvi_synth/ethernet/mii_tx_clk +add wave -noupdate -expand -group eth /testbench/rvvi_synth/ethernet/mii_txd +add wave -noupdate -expand -group eth /testbench/rvvi_synth/ethernet/mii_tx_en +add wave -noupdate -expand -group eth /testbench/rvvi_synth/ethernet/mii_tx_er TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 4} {650 ns} 1} {{Cursor 4} {2090 ns} 1} {{Cursor 3} {364 ns} 0} -quietly wave cursor active 3 +WaveRestoreCursors {{Cursor 4} {640 ns} 1} {{Cursor 4} {2400 ns} 1} {{Cursor 3} {554 ns} 0} {{Cursor 4} {120089 ns} 0} +quietly wave cursor active 4 configure wave -namecolwidth 250 configure wave -valuecolwidth 194 configure wave -justifyvalue left @@ -693,4 +693,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {266 ns} {618 ns} +WaveRestoreZoom {0 ns} {1033211 ns} diff --git a/src/rvvi/rvvisynth.sv b/src/rvvi/rvvisynth.sv index e5801cf09..27a1fe6d3 100644 --- a/src/rvvi/rvvisynth.sv +++ b/src/rvvi/rvvisynth.sv @@ -62,64 +62,64 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, logic [MAX_CSRS*(P.XLEN+12)-1:0] CSRs; // get signals from the core. - assign StallE = core.StallE; - assign StallM = core.StallM; - assign StallW = core.StallW; - assign FlushE = core.FlushE; - assign FlushM = core.FlushM; - assign FlushW = core.FlushW; - assign InstrValidM = core.ieu.InstrValidM; - assign InstrRawD = core.ifu.InstrRawD; - assign PCM = core.ifu.PCM; - assign Mcycle = core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; - assign Minstret = core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; - assign TrapM = core.TrapM; - assign PrivilegeModeW = core.priv.priv.privmode.PrivilegeModeW; - assign GPRAddr = core.ieu.dp.regf.a3; - assign GPRWen = core.ieu.dp.regf.we3; - assign GPRValue = core.ieu.dp.regf.wd3; - assign FPRAddr = core.fpu.fpu.fregfile.a4; - assign FPRWen = core.fpu.fpu.fregfile.we4; - assign FPRValue = core.fpu.fpu.fregfile.wd4; + assign StallE = dut.core.StallE; + assign StallM = dut.core.StallM; + assign StallW = dut.core.StallW; + assign FlushE = dut.core.FlushE; + assign FlushM = dut.core.FlushM; + assign FlushW = dut.core.FlushW; + assign InstrValidM = dut.core.ieu.InstrValidM; + assign InstrRawD = dut.core.ifu.InstrRawD; + assign PCM = dut.core.ifu.PCM; + assign Mcycle = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; + assign Minstret = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; + assign TrapM = dut.core.TrapM; + assign PrivilegeModeW = dut.core.priv.priv.privmode.PrivilegeModeW; + assign GPRAddr = dut.core.ieu.dp.regf.a3; + assign GPRWen = dut.core.ieu.dp.regf.we3; + assign GPRValue = dut.core.ieu.dp.regf.wd3; + assign FPRAddr = dut.core.fpu.fpu.fregfile.a4; + assign FPRWen = dut.core.fpu.fpu.fregfile.we4; + assign FPRValue = dut.core.fpu.fpu.fregfile.wd4; - assign CSRArray[0] = core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 - assign CSRArray[1] = core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 - assign CSRArray[2] = core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 - assign CSRArray[3] = core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 - assign CSRArray[4] = core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 - assign CSRArray[5] = core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 - assign CSRArray[6] = core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 - assign CSRArray[7] = core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 - assign CSRArray[8] = core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 - assign CSRArray[9] = core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 - assign CSRArray[10] = core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 - assign CSRArray[11] = core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A - assign CSRArray[12] = core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 - assign CSRArray[13] = core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 - assign CSRArray[14] = core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 - assign CSRArray[15] = core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 + assign CSRArray[0] = dut.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 + assign CSRArray[1] = dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 + assign CSRArray[2] = dut.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 + assign CSRArray[3] = dut.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 + assign CSRArray[4] = dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 + assign CSRArray[5] = dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 + assign CSRArray[6] = dut.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 + assign CSRArray[7] = dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 + assign CSRArray[8] = dut.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 + assign CSRArray[9] = dut.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 + assign CSRArray[10] = dut.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 + assign CSRArray[11] = dut.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A + assign CSRArray[12] = dut.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 + assign CSRArray[13] = dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 + assign CSRArray[14] = dut.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 + assign CSRArray[15] = dut.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 assign CSRArray[16] = 0; // 12'hF11 assign CSRArray[17] = 0; // 12'hF12 assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 assign CSRArray[19] = 0; // 12'hF15 assign CSRArray[20] = 0; // 12'h34A // supervisor CSRs - assign CSRArray[21] = core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 - assign CSRArray[22] = core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 - assign CSRArray[23] = core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 - assign CSRArray[24] = core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 - assign CSRArray[25] = core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 - assign CSRArray[26] = core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A - assign CSRArray[27] = core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 - assign CSRArray[28] = core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 - assign CSRArray[29] = core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 - assign CSRArray[30] = core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 - assign CSRArray[31] = core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 - assign CSRArray[32] = core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D + assign CSRArray[21] = dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 + assign CSRArray[22] = dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 + assign CSRArray[23] = dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 + assign CSRArray[24] = dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 + assign CSRArray[25] = dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 + assign CSRArray[26] = dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A + assign CSRArray[27] = dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 + assign CSRArray[28] = dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 + assign CSRArray[29] = dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 + assign CSRArray[30] = dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 + assign CSRArray[31] = dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 + assign CSRArray[32] = dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D // user CSRs - assign CSRArray[33] = core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 - assign CSRArray[34] = core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 - assign CSRArray[35] = {core.priv.priv.csr.csru.csru.FRM_REGW, core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 + assign CSRArray[33] = dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 + assign CSRArray[34] = dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 + assign CSRArray[35] = {dut.core.priv.priv.csr.csru.csru.FRM_REGW, dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 // assign XLENZeros = '0; diff --git a/src/wally/wallypipelinedsoc.sv b/src/wally/wallypipelinedsoc.sv index 75265ab29..236a653fb 100644 --- a/src/wally/wallypipelinedsoc.sv +++ b/src/wally/wallypipelinedsoc.sv @@ -32,10 +32,12 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( input logic reset_ext, // external asynchronous reset pin output logic reset, // reset synchronized to clk to prevent races on release // AHB Interface - input logic [P.AHBW-1:0] HRDATAEXT, + input logic [P.AHBW-1:0] HRDATAEXT, input logic HREADYEXT, HRESPEXT, output logic HSELEXT, output logic HSELEXTSDC, + // fpga debug signals + input logic RVVIStall, // outputs to external memory, shared with uncore memory output logic HCLK, HRESETn, output logic [P.PA_BITS-1:0] HADDR, @@ -68,11 +70,6 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( logic [63:0] MTIME_CLINT; // from CLINT to CSRs logic MExtInt,SExtInt; // from PLIC - localparam MAX_CSRS = 3; - logic valid; - logic RVVIStall; - logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; - // synchronize reset to SOC clock domain synchronizer resetsync(.clk, .d(reset_ext), .q(reset)); @@ -95,84 +92,5 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( MTIME_CLINT, GPIOOUT, GPIOEN, UARTSout, SPIOut, SPICS} = '0; end - - - rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .rvvi); - - // a bunch of these signals would be needed for the xilinx ethernet IP - // but I switched to using https://github.com/alexforencich/verilog-ethernet - // so most arn't needed anymore. *** remove once I've confirmed this - // works in synthesis. - logic [3:0] m_axi_awid; - logic [12:0] m_axi_awaddr; - logic [7:0] m_axi_awlen; - logic [2:0] m_axi_awsize; - logic [1:0] m_axi_awburst; - logic [3:0] m_axi_awcache; - logic m_axi_awvalid; - logic m_axi_awready; - // axi 4 write data channel - logic [31:0] m_axi_wdata; - logic [3:0] m_axi_wstrb; - logic m_axi_wlast; - logic m_axi_wvalid; - logic m_axi_wready; - // axi 4 write response channel - logic [3:0] m_axi_bid; - logic [1:0] m_axi_bresp; - logic m_axi_bvalid; - logic m_axi_bready; - // axi 4 read address channel - logic [3:0] m_axi_arid; - logic [12:0] m_axi_araddr; - logic [7:0] m_axi_arlen; - logic [2:0] m_axi_arsize; - logic [1:0] m_axi_arburst; - logic [3:0] m_axi_arcache; - logic m_axi_arvalid; - logic m_axi_arready; - // axi 4 read data channel - logic [3:0] m_axi_rid; - logic [31:0] m_axi_rdata; - logic [1:0] m_axi_rresp; - logic m_axi_rlast; - logic m_axi_rvalid; - logic m_axi_rready; - - logic [3:0] mii_txd; - logic mii_tx_en, mii_tx_er; - - logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; - logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; - - packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, - .m_axi_awid, .m_axi_awaddr, .m_axi_awlen, .m_axi_awsize, .m_axi_awburst, .m_axi_awcache, .m_axi_awvalid, - .m_axi_awready, .m_axi_wdata, .m_axi_wstrb, .m_axi_wlast, .m_axi_wvalid, .m_axi_wready, .m_axi_bid, - .m_axi_bresp, .m_axi_bvalid, .m_axi_bready, .m_axi_arid, .m_axi_araddr, .m_axi_arlen, .m_axi_arsize, - .m_axi_arburst, .m_axi_arcache, .m_axi_arvalid, .m_axi_arready, .m_axi_rid, .m_axi_rdata, .m_axi_rresp, - .m_axi_rlast, .m_axi_rvalid, .m_axi_rready); - - eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(reset), .logic_clk(clk), .logic_rst(reset), - .tx_axis_tdata(m_axi_wdata), .tx_axis_tkeep(m_axi_wstrb), .tx_axis_tvalid(m_axi_wvalid), .tx_axis_tready(m_axi_wready), - .tx_axis_tlast(m_axi_wlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), - .rx_axis_tlast(), .rx_axis_tuser(), - - // *** update these - .mii_rx_clk(clk), // *** need to be the mii clock - .mii_rxd('0), - .mii_rx_dv('0), - .mii_rx_er('0), - .mii_tx_clk(clk), // *** needs to be the mii clock - .mii_txd, - .mii_tx_en, - .mii_tx_er, - - // status - .tx_error_underflow, .tx_fifo_overflow, .tx_fifo_bad_frame, .tx_fifo_good_frame, .rx_error_bad_frame, - .rx_error_bad_fcs, .rx_fifo_overflow, .rx_fifo_bad_frame, .rx_fifo_good_frame, - .cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1) - ); - - assign m_axi_awready = '1; endmodule diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 71aaa8126..ed511da68 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -33,6 +33,8 @@ `include "idv/idv.svh" `endif +// *** bug replace with config? +`define RVVI_SYNTH_SUPPORTED 1 import cvw::*; @@ -110,6 +112,7 @@ module testbench; logic Validate; logic SelectTest; logic TestComplete; + logic RVVIStall; initial begin // look for arguments passed to simulation, or use defaults @@ -577,7 +580,7 @@ module testbench; assign SDCIntr = 1'b0; end - wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC, + wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .RVVIStall, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN, .UARTSin, .UARTSout, .SDCIntr, .SPIIn, .SPIOut, .SPICS); @@ -587,6 +590,93 @@ module testbench; clk = 1'b1; # 5; clk = 1'b0; # 5; end + if(`RVVI_SYNTH_SUPPORTED) begin : rvvi_synth + localparam MAX_CSRS = 3; + logic valid; + logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; + + rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .rvvi); + + // a bunch of these signals would be needed for the xilinx ethernet IP + // but I switched to using https://github.com/alexforencich/verilog-ethernet + // so most arn't needed anymore. *** remove once I've confirmed this + // works in synthesis. + logic [3:0] m_axi_awid; + logic [12:0] m_axi_awaddr; + logic [7:0] m_axi_awlen; + logic [2:0] m_axi_awsize; + logic [1:0] m_axi_awburst; + logic [3:0] m_axi_awcache; + logic m_axi_awvalid; + logic m_axi_awready; + // axi 4 write data channel + logic [31:0] m_axi_wdata; + logic [3:0] m_axi_wstrb; + logic m_axi_wlast; + logic m_axi_wvalid; + logic m_axi_wready; + // axi 4 write response channel + logic [3:0] m_axi_bid; + logic [1:0] m_axi_bresp; + logic m_axi_bvalid; + logic m_axi_bready; + // axi 4 read address channel + logic [3:0] m_axi_arid; + logic [12:0] m_axi_araddr; + logic [7:0] m_axi_arlen; + logic [2:0] m_axi_arsize; + logic [1:0] m_axi_arburst; + logic [3:0] m_axi_arcache; + logic m_axi_arvalid; + logic m_axi_arready; + // axi 4 read data channel + logic [3:0] m_axi_rid; + logic [31:0] m_axi_rdata; + logic [1:0] m_axi_rresp; + logic m_axi_rlast; + logic m_axi_rvalid; + logic m_axi_rready; + + logic [3:0] mii_txd; + logic mii_tx_en, mii_tx_er; + + logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; + logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; + + packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, + .m_axi_awid, .m_axi_awaddr, .m_axi_awlen, .m_axi_awsize, .m_axi_awburst, .m_axi_awcache, .m_axi_awvalid, + .m_axi_awready, .m_axi_wdata, .m_axi_wstrb, .m_axi_wlast, .m_axi_wvalid, .m_axi_wready, .m_axi_bid, + .m_axi_bresp, .m_axi_bvalid, .m_axi_bready, .m_axi_arid, .m_axi_araddr, .m_axi_arlen, .m_axi_arsize, + .m_axi_arburst, .m_axi_arcache, .m_axi_arvalid, .m_axi_arready, .m_axi_rid, .m_axi_rdata, .m_axi_rresp, + .m_axi_rlast, .m_axi_rvalid, .m_axi_rready); + + eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(reset), .logic_clk(clk), .logic_rst(reset), + .tx_axis_tdata(m_axi_wdata), .tx_axis_tkeep(m_axi_wstrb), .tx_axis_tvalid(m_axi_wvalid), .tx_axis_tready(m_axi_wready), + .tx_axis_tlast(m_axi_wlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), + .rx_axis_tlast(), .rx_axis_tuser(), + + // *** update these + .mii_rx_clk(clk), // *** need to be the mii clock + .mii_rxd('0), + .mii_rx_dv('0), + .mii_rx_er('0), + .mii_tx_clk(clk), // *** needs to be the mii clock + .mii_txd, + .mii_tx_en, + .mii_tx_er, + + // status + .tx_error_underflow, .tx_fifo_overflow, .tx_fifo_bad_frame, .tx_fifo_good_frame, .rx_error_bad_frame, + .rx_error_bad_fcs, .rx_fifo_overflow, .rx_fifo_bad_frame, .rx_fifo_good_frame, + .cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1) + ); + + assign m_axi_awready = '1; + end else begin + assign RVVIStall = '0; + end + + /* // Print key info each cycle for debugging always @(posedge clk) begin diff --git a/testbench/wallywrapper.sv b/testbench/wallywrapper.sv index 990ebfe74..234a11fdf 100644 --- a/testbench/wallywrapper.sv +++ b/testbench/wallywrapper.sv @@ -57,7 +57,7 @@ module wallywrapper; logic HREADY; logic HSELEXT; logic HSELEXTSDC; - + logic RVVIStall; // instantiate device to be tested assign GPIOIN = 0; @@ -67,8 +67,9 @@ module wallywrapper; assign HRESPEXT = 0; assign HRDATAEXT = 0; + assign RVVIStall = '0; - wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, .HSELEXTSDC, + wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .RVVIStall, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, .HSELEXTSDC, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN, .UARTSin, .UARTSout, .SPIIn, .SPIOut, .SPICS, .SDCIntr); From 263be861191456bc0e6db474276005ab52c480ce Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 24 May 2024 16:27:09 -0500 Subject: [PATCH 13/95] Packetizer cleanup. --- src/rvvi/packetizer.sv | 14 -------------- testbench/testbench.sv | 8 -------- 2 files changed, 22 deletions(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 3cf465268..8067ba412 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -34,13 +34,6 @@ module packetizer import cvw::*; #(parameter cvw_t P, input logic m_axi_aclk, m_axi_aresetn, output logic RVVIStall, // axi 4 write address channel - output logic [3:0] m_axi_awid, - output logic [12:0] m_axi_awaddr, - output logic [7:0] m_axi_awlen, - output logic [2:0] m_axi_awsize, - output logic [1:0] m_axi_awburst, - output logic [3:0] m_axi_awcache, - output logic m_axi_awvalid, input logic m_axi_awready, // axi 4 write data channel output logic [31:0] m_axi_wdata, @@ -122,13 +115,6 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign BytesInFrame = 12'd76; assign BurstDone = WordCount == (BytesInFrame[11:2] - 1'b1); - assign m_axi_awid = '0; - assign m_axi_awaddr = '0; // *** bug update to be based on the correct address during each beat. - assign m_axi_awlen = BytesInFrame[11:2]; - assign m_axi_awsize = 3'b010; // 4 bytes - assign m_axi_awburst = 2'b01; // increment - assign m_axi_awcache = '0; - assign m_axi_awvalid = (CurrState == STATE_RDY & valid) | CurrState == STATE_TRANS; genvar index; for (index = 0; index < TotalFrameLengthBytes/4; index++) begin assign TotalFrameWords[index] = TotalFrame[(index*32)+32-1 : (index*32)]; diff --git a/testbench/testbench.sv b/testbench/testbench.sv index ed511da68..2bcabbfa4 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -601,13 +601,6 @@ module testbench; // but I switched to using https://github.com/alexforencich/verilog-ethernet // so most arn't needed anymore. *** remove once I've confirmed this // works in synthesis. - logic [3:0] m_axi_awid; - logic [12:0] m_axi_awaddr; - logic [7:0] m_axi_awlen; - logic [2:0] m_axi_awsize; - logic [1:0] m_axi_awburst; - logic [3:0] m_axi_awcache; - logic m_axi_awvalid; logic m_axi_awready; // axi 4 write data channel logic [31:0] m_axi_wdata; @@ -644,7 +637,6 @@ module testbench; logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, - .m_axi_awid, .m_axi_awaddr, .m_axi_awlen, .m_axi_awsize, .m_axi_awburst, .m_axi_awcache, .m_axi_awvalid, .m_axi_awready, .m_axi_wdata, .m_axi_wstrb, .m_axi_wlast, .m_axi_wvalid, .m_axi_wready, .m_axi_bid, .m_axi_bresp, .m_axi_bvalid, .m_axi_bready, .m_axi_arid, .m_axi_araddr, .m_axi_arlen, .m_axi_arsize, .m_axi_arburst, .m_axi_arcache, .m_axi_arvalid, .m_axi_arready, .m_axi_rid, .m_axi_rdata, .m_axi_rresp, From bd2ec879d2e1f40a573d2469a644f66d1db5f621 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 24 May 2024 16:31:27 -0500 Subject: [PATCH 14/95] Removed unused axi signals from packetizer. --- src/rvvi/packetizer.sv | 28 +--------------------------- testbench/testbench.sv | 30 +----------------------------- 2 files changed, 2 insertions(+), 56 deletions(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 8067ba412..49828ab38 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -40,28 +40,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, output logic [3:0] m_axi_wstrb, output logic m_axi_wlast, output logic m_axi_wvalid, - input logic m_axi_wready, - // axi 4 write response channel - input logic [3:0] m_axi_bid, - input logic [1:0] m_axi_bresp, - input logic m_axi_bvalid, - output logic m_axi_bready, - // axi 4 read address channel - output logic [3:0] m_axi_arid, - output logic [12:0] m_axi_araddr, - output logic [7:0] m_axi_arlen, - output logic [2:0] m_axi_arsize, - output logic [1:0] m_axi_arburst, - output logic [3:0] m_axi_arcache, - output logic m_axi_arvalid, - input logic m_axi_arready, - // axi 4 read data channel - input logic [3:0] m_axi_rid, - input logic [31:0] m_axi_rdata, - input logic [1:0] m_axi_rresp, - input logic m_axi_rlast, - input logic m_axi_rvalid, - output logic m_axi_rready + input logic m_axi_wready ); localparam TotalFrameLengthBits = 2*48+32+16+187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12); @@ -133,10 +112,5 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign m_axi_wlast = BurstDone; assign m_axi_wvalid = (CurrState == STATE_TRANS); - assign m_axi_bready = 1'b1; // *** probably wrong. - - // we aren't using the read channels. This ethernet device isn't going to read anything for now - assign {m_axi_arid, m_axi_araddr, m_axi_arlen, m_axi_arsize, m_axi_arburst, m_axi_arcache, m_axi_arvalid, m_axi_rready} = '0; - endmodule diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 2bcabbfa4..5bc47b1ba 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -597,10 +597,6 @@ module testbench; rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .rvvi); - // a bunch of these signals would be needed for the xilinx ethernet IP - // but I switched to using https://github.com/alexforencich/verilog-ethernet - // so most arn't needed anymore. *** remove once I've confirmed this - // works in synthesis. logic m_axi_awready; // axi 4 write data channel logic [31:0] m_axi_wdata; @@ -608,27 +604,6 @@ module testbench; logic m_axi_wlast; logic m_axi_wvalid; logic m_axi_wready; - // axi 4 write response channel - logic [3:0] m_axi_bid; - logic [1:0] m_axi_bresp; - logic m_axi_bvalid; - logic m_axi_bready; - // axi 4 read address channel - logic [3:0] m_axi_arid; - logic [12:0] m_axi_araddr; - logic [7:0] m_axi_arlen; - logic [2:0] m_axi_arsize; - logic [1:0] m_axi_arburst; - logic [3:0] m_axi_arcache; - logic m_axi_arvalid; - logic m_axi_arready; - // axi 4 read data channel - logic [3:0] m_axi_rid; - logic [31:0] m_axi_rdata; - logic [1:0] m_axi_rresp; - logic m_axi_rlast; - logic m_axi_rvalid; - logic m_axi_rready; logic [3:0] mii_txd; logic mii_tx_en, mii_tx_er; @@ -637,10 +612,7 @@ module testbench; logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, - .m_axi_awready, .m_axi_wdata, .m_axi_wstrb, .m_axi_wlast, .m_axi_wvalid, .m_axi_wready, .m_axi_bid, - .m_axi_bresp, .m_axi_bvalid, .m_axi_bready, .m_axi_arid, .m_axi_araddr, .m_axi_arlen, .m_axi_arsize, - .m_axi_arburst, .m_axi_arcache, .m_axi_arvalid, .m_axi_arready, .m_axi_rid, .m_axi_rdata, .m_axi_rresp, - .m_axi_rlast, .m_axi_rvalid, .m_axi_rready); + .m_axi_awready, .m_axi_wdata, .m_axi_wstrb, .m_axi_wlast, .m_axi_wvalid, .m_axi_wready); eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(reset), .logic_clk(clk), .logic_rst(reset), .tx_axis_tdata(m_axi_wdata), .tx_axis_tkeep(m_axi_wstrb), .tx_axis_tvalid(m_axi_wvalid), .tx_axis_tready(m_axi_wready), From 73261e7f89ca3c2109c75dadc39d8647cc01ccd1 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 24 May 2024 16:34:33 -0500 Subject: [PATCH 15/95] More cleanup. Close to the simpliest it can be. --- src/rvvi/packetizer.sv | 3 +-- testbench/testbench.sv | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 49828ab38..b5a2cb695 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -34,7 +34,6 @@ module packetizer import cvw::*; #(parameter cvw_t P, input logic m_axi_aclk, m_axi_aresetn, output logic RVVIStall, // axi 4 write address channel - input logic m_axi_awready, // axi 4 write data channel output logic [31:0] m_axi_wdata, output logic [3:0] m_axi_wstrb, @@ -81,7 +80,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, end assign RVVIStall = CurrState != STATE_RDY; - assign TransReady = m_axi_awready & m_axi_wready; + assign TransReady = m_axi_wready; assign WordCountEnable = (CurrState == STATE_RDY & valid) | (CurrState == STATE_TRANS & TransReady); assign WordCountReset = CurrState == STATE_RDY; diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 5bc47b1ba..3895a157a 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -597,7 +597,6 @@ module testbench; rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .rvvi); - logic m_axi_awready; // axi 4 write data channel logic [31:0] m_axi_wdata; logic [3:0] m_axi_wstrb; @@ -612,7 +611,7 @@ module testbench; logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, - .m_axi_awready, .m_axi_wdata, .m_axi_wstrb, .m_axi_wlast, .m_axi_wvalid, .m_axi_wready); + .m_axi_wdata, .m_axi_wstrb, .m_axi_wlast, .m_axi_wvalid, .m_axi_wready); eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(reset), .logic_clk(clk), .logic_rst(reset), .tx_axis_tdata(m_axi_wdata), .tx_axis_tkeep(m_axi_wstrb), .tx_axis_tvalid(m_axi_wvalid), .tx_axis_tready(m_axi_wready), @@ -635,7 +634,6 @@ module testbench; .cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1) ); - assign m_axi_awready = '1; end else begin assign RVVIStall = '0; end From dc09e1c0c5f9ef0c64e458b7e2d36c9ebce76046 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 24 May 2024 16:38:47 -0500 Subject: [PATCH 16/95] Modified names so they don't conflict with FPGA's axi signals. --- sim/questa/wave.do | 10 +++++----- src/rvvi/packetizer.sv | 20 ++++++++++---------- testbench/testbench.sv | 16 ++++++++-------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/sim/questa/wave.do b/sim/questa/wave.do index ec8dd82b3..8ce781d18 100644 --- a/sim/questa/wave.do +++ b/sim/questa/wave.do @@ -667,11 +667,11 @@ add wave -noupdate -group packetizer -color Gold /testbench/rvvi_synth/packetize add wave -noupdate -group packetizer -radix unsigned /testbench/rvvi_synth/packetizer/WordCount add wave -noupdate -group packetizer /testbench/rvvi_synth/packetizer/RVVIStall add wave -noupdate -group packetizer /testbench/rvvi_synth/packetizer/rvviDelay -add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/m_axi_wdata -add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/m_axi_wlast -add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/m_axi_wstrb -add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/m_axi_wvalid -add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/m_axi_wready +add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/RvviAxiWdata +add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/RvviAxiWlast +add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/RvviAxiWstrb +add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/RvviAxiWvalid +add wave -noupdate -group packetizer -expand -group axi-write-interface /testbench/rvvi_synth/packetizer/RvviAxiWready add wave -noupdate -expand -group eth /testbench/rvvi_synth/ethernet/mii_tx_clk add wave -noupdate -expand -group eth /testbench/rvvi_synth/ethernet/mii_txd add wave -noupdate -expand -group eth /testbench/rvvi_synth/ethernet/mii_tx_en diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index b5a2cb695..93390d03b 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -35,11 +35,11 @@ module packetizer import cvw::*; #(parameter cvw_t P, output logic RVVIStall, // axi 4 write address channel // axi 4 write data channel - output logic [31:0] m_axi_wdata, - output logic [3:0] m_axi_wstrb, - output logic m_axi_wlast, - output logic m_axi_wvalid, - input logic m_axi_wready + output logic [31:0] RvviAxiWdata, + output logic [3:0] RvviAxiWstrb, + output logic RvviAxiWlast, + output logic RvviAxiWvalid, + input logic RvviAxiWready ); localparam TotalFrameLengthBits = 2*48+32+16+187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12); @@ -80,7 +80,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, end assign RVVIStall = CurrState != STATE_RDY; - assign TransReady = m_axi_wready; + assign TransReady = RvviAxiWready; assign WordCountEnable = (CurrState == STATE_RDY & valid) | (CurrState == STATE_TRANS & TransReady); assign WordCountReset = CurrState == STATE_RDY; @@ -106,10 +106,10 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign Tag = '0; assign Length = BytesInFrame + 16'd6 + 16'd6 + 16'd4 + 16'd2; - assign m_axi_wdata = TotalFrameWords[WordCount]; - assign m_axi_wstrb = '1; - assign m_axi_wlast = BurstDone; - assign m_axi_wvalid = (CurrState == STATE_TRANS); + assign RvviAxiWdata = TotalFrameWords[WordCount]; + assign RvviAxiWstrb = '1; + assign RvviAxiWlast = BurstDone; + assign RvviAxiWvalid = (CurrState == STATE_TRANS); endmodule diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 3895a157a..6020088e6 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -598,11 +598,11 @@ module testbench; rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .rvvi); // axi 4 write data channel - logic [31:0] m_axi_wdata; - logic [3:0] m_axi_wstrb; - logic m_axi_wlast; - logic m_axi_wvalid; - logic m_axi_wready; + logic [31:0] RvviAxiWdata; + logic [3:0] RvviAxiWstrb; + logic RvviAxiWlast; + logic RvviAxiWvalid; + logic RvviAxiWready; logic [3:0] mii_txd; logic mii_tx_en, mii_tx_er; @@ -611,11 +611,11 @@ module testbench; logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, - .m_axi_wdata, .m_axi_wstrb, .m_axi_wlast, .m_axi_wvalid, .m_axi_wready); + .RvviAxiWdata, .RvviAxiWstrb, .RvviAxiWlast, .RvviAxiWvalid, .RvviAxiWready); eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(reset), .logic_clk(clk), .logic_rst(reset), - .tx_axis_tdata(m_axi_wdata), .tx_axis_tkeep(m_axi_wstrb), .tx_axis_tvalid(m_axi_wvalid), .tx_axis_tready(m_axi_wready), - .tx_axis_tlast(m_axi_wlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), + .tx_axis_tdata(RvviAxiWdata), .tx_axis_tkeep(RvviAxiWstrb), .tx_axis_tvalid(RvviAxiWvalid), .tx_axis_tready(RvviAxiWready), + .tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), .rx_axis_tlast(), .rx_axis_tuser(), // *** update these From 970305575803f13932c91ce069c71be644c3c3f5 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 30 May 2024 15:37:17 -0500 Subject: [PATCH 17/95] The FPGA is synthesizing with the rvvi and ethernet hardware. --- fpga/constraints/constraints-ArtyA7.xdc | 26 ++++++ fpga/generator/xlnx_mmcm.tcl | 3 +- fpga/src/fpgaTopArtyA7.sv | 62 ++++++++++++++- src/rvvi/rvvisynth.sv | 100 ++++++++++++------------ 4 files changed, 138 insertions(+), 53 deletions(-) diff --git a/fpga/constraints/constraints-ArtyA7.xdc b/fpga/constraints/constraints-ArtyA7.xdc index 6fc660e8d..556c75c43 100644 --- a/fpga/constraints/constraints-ArtyA7.xdc +++ b/fpga/constraints/constraints-ArtyA7.xdc @@ -9,6 +9,32 @@ set_property PACKAGE_PIN E3 [get_ports {default_100mhz_clk}] set_property IOSTANDARD LVCMOS33 [get_ports {default_100mhz_clk}] +##### RVVI Ethernet #### +# taken from https://github.com/alexforencich/verilog-ethernet/blob/master/example/Arty/fpga/fpga.xdc +set_property -dict {LOC F15 IOSTANDARD LVCMOS33} [get_ports phy_rx_clk] +set_property -dict {LOC D18 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[0]}] +set_property -dict {LOC E17 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[1]}] +set_property -dict {LOC E18 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[2]}] +set_property -dict {LOC G17 IOSTANDARD LVCMOS33} [get_ports {phy_rxd[3]}] +set_property -dict {LOC G16 IOSTANDARD LVCMOS33} [get_ports phy_rx_dv] +set_property -dict {LOC C17 IOSTANDARD LVCMOS33} [get_ports phy_rx_er] +set_property -dict {LOC H16 IOSTANDARD LVCMOS33} [get_ports phy_tx_clk] +set_property -dict {LOC H14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[0]}] +set_property -dict {LOC J14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[1]}] +set_property -dict {LOC J13 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[2]}] +set_property -dict {LOC H17 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports {phy_txd[3]}] +set_property -dict {LOC H15 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 12} [get_ports phy_tx_en] +set_property -dict {LOC D17 IOSTANDARD LVCMOS33} [get_ports phy_col] +set_property -dict {LOC G14 IOSTANDARD LVCMOS33} [get_ports phy_crs] +set_property -dict {LOC G18 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_ref_clk] +set_property -dict {LOC C16 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports phy_reset_n] + +create_clock -period 40.000 -name phy_rx_clk [get_ports phy_rx_clk] +create_clock -period 40.000 -name phy_tx_clk [get_ports phy_tx_clk] + +set_false_path -to [get_ports {phy_ref_clk phy_reset_n}] +set_output_delay 0 [get_ports {phy_ref_clk phy_reset_n}] + ##### GPI #### set_property PACKAGE_PIN A8 [get_ports {GPI[0]}] set_property PACKAGE_PIN C9 [get_ports {GPI[1]}] diff --git a/fpga/generator/xlnx_mmcm.tcl b/fpga/generator/xlnx_mmcm.tcl index 2f003e7a5..8335c397a 100644 --- a/fpga/generator/xlnx_mmcm.tcl +++ b/fpga/generator/xlnx_mmcm.tcl @@ -12,10 +12,11 @@ set_property -dict [list CONFIG.PRIM_IN_FREQ {100.000} \ CONFIG.NUM_OUT_CLKS {3} \ CONFIG.CLKOUT2_USED {true} \ CONFIG.CLKOUT3_USED {true} \ - CONFIG.CLKOUT4_USED {false} \ + CONFIG.CLKOUT4_USED {true} \ CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {166.66667} \ CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {200} \ CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {20} \ + CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {25} \ CONFIG.CLKIN1_JITTER_PS {10.0} \ ] [get_ips $ipName] diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index 20e8adb81..295c62c38 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -44,6 +44,21 @@ module fpgaTop inout SDCCmd, input SDCCD, + /* + * Ethernet: 100BASE-T MII + */ + output phy_ref_clk, + input phy_rx_clk, + input [3:0] phy_rxd, + input phy_rx_dv, + input phy_rx_er, + input phy_tx_clk, + output [3:0] phy_txd, + output phy_tx_en, + input phy_col, // nc + input phy_crs, // nc + output phy_reset_n, + inout [15:0] ddr3_dq, inout [1:0] ddr3_dqs_n, inout [1:0] ddr3_dqs_p, @@ -428,7 +443,8 @@ module fpgaTop wire mmcm_locked; wire [11:0] device_temp; wire mmcm1_locked; - + + logic RVVIStall; assign GPIOIN = {28'b0, GPI}; assign GPO = GPIOOUT[4:0]; @@ -446,6 +462,7 @@ module fpgaTop xlnx_mmcm xln_mmcm(.clk_out1(clk167), .clk_out2(clk200), .clk_out3(CPUCLK), + .clk_out4(phy_ref_clk), .reset(1'b0), .locked(mmcm1_locked), .clk_in1(default_100mhz_clk)); @@ -496,7 +513,7 @@ module fpgaTop .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN, - .UARTSin, .UARTSout, .SDCIntr); + .UARTSin, .UARTSout, .SDCIntr, .RVVIStall); // ahb lite to axi bridge @@ -1098,6 +1115,47 @@ module fpgaTop .init_calib_complete(c0_init_calib_complete), .device_temp(device_temp)); + localparam MAX_CSRS = 3; + logic valid; + logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; + + rvvisynth #(P, MAX_CSRS) rvvisynth(.clk(CPUCLK), .reset(bus_struct_reset), .valid, .rvvi); + + // axi 4 write data channel + logic [31:0] RvviAxiWdata; + logic [3:0] RvviAxiWstrb; + logic RvviAxiWlast; + logic RvviAxiWvalid; + logic RvviAxiWready; + + logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; + logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; + + packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(CPUCLK), .m_axi_aresetn(~bus_struct_reset), .RVVIStall, + .RvviAxiWdata, .RvviAxiWstrb, .RvviAxiWlast, .RvviAxiWvalid, .RvviAxiWready); + + eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(reset), .logic_clk(CPUCLK), .logic_rst(bus_struct_reset), + .tx_axis_tdata(RvviAxiWdata), .tx_axis_tkeep(RvviAxiWstrb), .tx_axis_tvalid(RvviAxiWvalid), .tx_axis_tready(RvviAxiWready), + .tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), + .rx_axis_tlast(), .rx_axis_tuser(), + + // *** update these + .mii_rx_clk(phy_rx_clk), + .mii_rxd(phy_rxd), + .mii_rx_dv(phy_rx_dv), + .mii_rx_er(phy_rx_er), + .mii_tx_clk(phy_tx_clk), + .mii_txd(phy_txd), + .mii_tx_en(phy_tx_en), + .mii_tx_er(), + + // status + .tx_error_underflow, .tx_fifo_overflow, .tx_fifo_bad_frame, .tx_fifo_good_frame, .rx_error_bad_frame, + .rx_error_bad_fcs, .rx_fifo_overflow, .rx_fifo_bad_frame, .rx_fifo_good_frame, + .cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1) + ); + + assign phy_reset_n = ~bus_struct_reset; endmodule diff --git a/src/rvvi/rvvisynth.sv b/src/rvvi/rvvisynth.sv index 27a1fe6d3..df96ba446 100644 --- a/src/rvvi/rvvisynth.sv +++ b/src/rvvi/rvvisynth.sv @@ -62,64 +62,64 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, logic [MAX_CSRS*(P.XLEN+12)-1:0] CSRs; // get signals from the core. - assign StallE = dut.core.StallE; - assign StallM = dut.core.StallM; - assign StallW = dut.core.StallW; - assign FlushE = dut.core.FlushE; - assign FlushM = dut.core.FlushM; - assign FlushW = dut.core.FlushW; - assign InstrValidM = dut.core.ieu.InstrValidM; - assign InstrRawD = dut.core.ifu.InstrRawD; - assign PCM = dut.core.ifu.PCM; - assign Mcycle = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; - assign Minstret = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; - assign TrapM = dut.core.TrapM; - assign PrivilegeModeW = dut.core.priv.priv.privmode.PrivilegeModeW; - assign GPRAddr = dut.core.ieu.dp.regf.a3; - assign GPRWen = dut.core.ieu.dp.regf.we3; - assign GPRValue = dut.core.ieu.dp.regf.wd3; - assign FPRAddr = dut.core.fpu.fpu.fregfile.a4; - assign FPRWen = dut.core.fpu.fpu.fregfile.we4; - assign FPRValue = dut.core.fpu.fpu.fregfile.wd4; + assign StallE = fpgaTop.wallypipelinedsoc.core.StallE; + assign StallM = fpgaTop.wallypipelinedsoc.core.StallM; + assign StallW = fpgaTop.wallypipelinedsoc.core.StallW; + assign FlushE = fpgaTop.wallypipelinedsoc.core.FlushE; + assign FlushM = fpgaTop.wallypipelinedsoc.core.FlushM; + assign FlushW = fpgaTop.wallypipelinedsoc.core.FlushW; + assign InstrValidM = fpgaTop.wallypipelinedsoc.core.ieu.InstrValidM; + assign InstrRawD = fpgaTop.wallypipelinedsoc.core.ifu.InstrRawD; + assign PCM = fpgaTop.wallypipelinedsoc.core.ifu.PCM; + assign Mcycle = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; + assign Minstret = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; + assign TrapM = fpgaTop.wallypipelinedsoc.core.TrapM; + assign PrivilegeModeW = fpgaTop.wallypipelinedsoc.core.priv.priv.privmode.PrivilegeModeW; + assign GPRAddr = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.a3; + assign GPRWen = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.we3; + assign GPRValue = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.wd3; + assign FPRAddr = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.a4; + assign FPRWen = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.we4; + assign FPRValue = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.wd4; - assign CSRArray[0] = dut.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 - assign CSRArray[1] = dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 - assign CSRArray[2] = dut.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 - assign CSRArray[3] = dut.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 - assign CSRArray[4] = dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 - assign CSRArray[5] = dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 - assign CSRArray[6] = dut.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 - assign CSRArray[7] = dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 - assign CSRArray[8] = dut.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 - assign CSRArray[9] = dut.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 - assign CSRArray[10] = dut.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 - assign CSRArray[11] = dut.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A - assign CSRArray[12] = dut.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 - assign CSRArray[13] = dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 - assign CSRArray[14] = dut.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 - assign CSRArray[15] = dut.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 + assign CSRArray[0] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 + assign CSRArray[1] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 + assign CSRArray[2] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 + assign CSRArray[3] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 + assign CSRArray[4] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 + assign CSRArray[5] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 + assign CSRArray[6] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 + assign CSRArray[7] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 + assign CSRArray[8] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 + assign CSRArray[9] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 + assign CSRArray[10] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 + assign CSRArray[11] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A + assign CSRArray[12] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 + assign CSRArray[13] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 + assign CSRArray[14] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 + assign CSRArray[15] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 assign CSRArray[16] = 0; // 12'hF11 assign CSRArray[17] = 0; // 12'hF12 assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 assign CSRArray[19] = 0; // 12'hF15 assign CSRArray[20] = 0; // 12'h34A // supervisor CSRs - assign CSRArray[21] = dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 - assign CSRArray[22] = dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 - assign CSRArray[23] = dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 - assign CSRArray[24] = dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 - assign CSRArray[25] = dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 - assign CSRArray[26] = dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A - assign CSRArray[27] = dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 - assign CSRArray[28] = dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 - assign CSRArray[29] = dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 - assign CSRArray[30] = dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 - assign CSRArray[31] = dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 - assign CSRArray[32] = dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D + assign CSRArray[21] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 + assign CSRArray[22] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 + assign CSRArray[23] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 + assign CSRArray[24] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 + assign CSRArray[25] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 + assign CSRArray[26] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A + assign CSRArray[27] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 + assign CSRArray[28] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 + assign CSRArray[29] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 + assign CSRArray[30] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 + assign CSRArray[31] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 + assign CSRArray[32] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D // user CSRs - assign CSRArray[33] = dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 - assign CSRArray[34] = dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 - assign CSRArray[35] = {dut.core.priv.priv.csr.csru.csru.FRM_REGW, dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 + assign CSRArray[33] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 + assign CSRArray[34] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 + assign CSRArray[35] = {fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW, fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 // assign XLENZeros = '0; From 38ddbf860e610ba20cd78df8d5b35fb2d0d3e92b Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 30 May 2024 16:19:28 -0500 Subject: [PATCH 18/95] Fixed bug with mmcm not generating the 4th clock. --- fpga/generator/xlnx_mmcm.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fpga/generator/xlnx_mmcm.tcl b/fpga/generator/xlnx_mmcm.tcl index 8335c397a..146a9cf41 100644 --- a/fpga/generator/xlnx_mmcm.tcl +++ b/fpga/generator/xlnx_mmcm.tcl @@ -16,7 +16,7 @@ set_property -dict [list CONFIG.PRIM_IN_FREQ {100.000} \ CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {166.66667} \ CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {200} \ CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {20} \ - CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {25} \ + CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {25} \ CONFIG.CLKIN1_JITTER_PS {10.0} \ ] [get_ips $ipName] From ca90c6ba48a8c60f6d8ca99606345872f5111012 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 30 May 2024 16:33:49 -0500 Subject: [PATCH 19/95] Added the ethernet files. These are part of another repo. We should remove before mainlining this. --- src/rvvi/axis_adapter.sv | 324 ++++++++++ src/rvvi/axis_async_fifo.sv | 909 ++++++++++++++++++++++++++++ src/rvvi/axis_async_fifo_adapter.sv | 377 ++++++++++++ src/rvvi/axis_gmii_rx.sv | 357 +++++++++++ src/rvvi/axis_gmii_tx.sv | 457 ++++++++++++++ src/rvvi/eth_axis_tx.sv | 408 +++++++++++++ src/rvvi/eth_mac_1g.sv | 643 ++++++++++++++++++++ src/rvvi/eth_mac_mii.sv | 175 ++++++ src/rvvi/eth_mac_mii_fifo.sv | 339 +++++++++++ src/rvvi/lfsr.sv | 446 ++++++++++++++ src/rvvi/mac_ctrl_rx.sv | 447 ++++++++++++++ src/rvvi/mac_ctrl_tx.sv | 420 +++++++++++++ src/rvvi/mac_pause_ctrl_rx.sv | 220 +++++++ src/rvvi/mac_pause_ctrl_tx.sv | 312 ++++++++++ src/rvvi/mii_phy_if.sv | 140 +++++ src/rvvi/ssio_ddr_in.sv | 150 +++++ src/rvvi/ssio_sdr_in.sv | 166 +++++ 17 files changed, 6290 insertions(+) create mode 100644 src/rvvi/axis_adapter.sv create mode 100644 src/rvvi/axis_async_fifo.sv create mode 100644 src/rvvi/axis_async_fifo_adapter.sv create mode 100644 src/rvvi/axis_gmii_rx.sv create mode 100644 src/rvvi/axis_gmii_tx.sv create mode 100644 src/rvvi/eth_axis_tx.sv create mode 100644 src/rvvi/eth_mac_1g.sv create mode 100644 src/rvvi/eth_mac_mii.sv create mode 100644 src/rvvi/eth_mac_mii_fifo.sv create mode 100644 src/rvvi/lfsr.sv create mode 100644 src/rvvi/mac_ctrl_rx.sv create mode 100644 src/rvvi/mac_ctrl_tx.sv create mode 100644 src/rvvi/mac_pause_ctrl_rx.sv create mode 100644 src/rvvi/mac_pause_ctrl_tx.sv create mode 100644 src/rvvi/mii_phy_if.sv create mode 100644 src/rvvi/ssio_ddr_in.sv create mode 100644 src/rvvi/ssio_sdr_in.sv diff --git a/src/rvvi/axis_adapter.sv b/src/rvvi/axis_adapter.sv new file mode 100644 index 000000000..8807a03b7 --- /dev/null +++ b/src/rvvi/axis_adapter.sv @@ -0,0 +1,324 @@ +/* + +Copyright (c) 2014-2023 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * AXI4-Stream bus width adapter + */ +module axis_adapter # +( + // Width of input AXI stream interface in bits + parameter S_DATA_WIDTH = 8, + // Propagate tkeep signal on input interface + // If disabled, tkeep assumed to be 1'b1 + parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8), + // tkeep signal width (words per cycle) on input interface + parameter S_KEEP_WIDTH = ((S_DATA_WIDTH+7)/8), + // Width of output AXI stream interface in bits + parameter M_DATA_WIDTH = 8, + // Propagate tkeep signal on output interface + // If disabled, tkeep assumed to be 1'b1 + parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8), + // tkeep signal width (words per cycle) on output interface + parameter M_KEEP_WIDTH = ((M_DATA_WIDTH+7)/8), + // Propagate tid signal + parameter ID_ENABLE = 0, + // tid signal width + parameter ID_WIDTH = 8, + // Propagate tdest signal + parameter DEST_ENABLE = 0, + // tdest signal width + parameter DEST_WIDTH = 8, + // Propagate tuser signal + parameter USER_ENABLE = 1, + // tuser signal width + parameter USER_WIDTH = 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [S_DATA_WIDTH-1:0] s_axis_tdata, + input wire [S_KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI output + */ + output wire [M_DATA_WIDTH-1:0] m_axis_tdata, + output wire [M_KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser +); + +// force keep width to 1 when disabled +localparam S_BYTE_LANES = S_KEEP_ENABLE ? S_KEEP_WIDTH : 1; +localparam M_BYTE_LANES = M_KEEP_ENABLE ? M_KEEP_WIDTH : 1; + +// bus byte sizes (must be identical) +localparam S_BYTE_SIZE = S_DATA_WIDTH / S_BYTE_LANES; +localparam M_BYTE_SIZE = M_DATA_WIDTH / M_BYTE_LANES; + +// bus width assertions +initial begin + if (S_BYTE_SIZE * S_BYTE_LANES != S_DATA_WIDTH) begin + $error("Error: input data width not evenly divisible (instance %m)"); + $finish; + end + + if (M_BYTE_SIZE * M_BYTE_LANES != M_DATA_WIDTH) begin + $error("Error: output data width not evenly divisible (instance %m)"); + $finish; + end + + if (S_BYTE_SIZE != M_BYTE_SIZE) begin + $error("Error: byte size mismatch (instance %m)"); + $finish; + end +end + +generate + +if (M_BYTE_LANES == S_BYTE_LANES) begin : bypass + // same width; bypass + + assign s_axis_tready = m_axis_tready; + + assign m_axis_tdata = s_axis_tdata; + assign m_axis_tkeep = M_KEEP_ENABLE ? s_axis_tkeep : {M_KEEP_WIDTH{1'b1}}; + assign m_axis_tvalid = s_axis_tvalid; + assign m_axis_tlast = s_axis_tlast; + assign m_axis_tid = ID_ENABLE ? s_axis_tid : {ID_WIDTH{1'b0}}; + assign m_axis_tdest = DEST_ENABLE ? s_axis_tdest : {DEST_WIDTH{1'b0}}; + assign m_axis_tuser = USER_ENABLE ? s_axis_tuser : {USER_WIDTH{1'b0}}; + +end else if (M_BYTE_LANES > S_BYTE_LANES) begin : upsize + // output is wider; upsize + + // required number of segments in wider bus + localparam SEG_COUNT = M_BYTE_LANES / S_BYTE_LANES; + // data width and keep width per segment + localparam SEG_DATA_WIDTH = M_DATA_WIDTH / SEG_COUNT; + localparam SEG_KEEP_WIDTH = M_BYTE_LANES / SEG_COUNT; + + reg [$clog2(SEG_COUNT)-1:0] seg_reg = 0; + + reg [S_DATA_WIDTH-1:0] s_axis_tdata_reg = {S_DATA_WIDTH{1'b0}}; + reg [S_KEEP_WIDTH-1:0] s_axis_tkeep_reg = {S_KEEP_WIDTH{1'b0}}; + reg s_axis_tvalid_reg = 1'b0; + reg s_axis_tlast_reg = 1'b0; + reg [ID_WIDTH-1:0] s_axis_tid_reg = {ID_WIDTH{1'b0}}; + reg [DEST_WIDTH-1:0] s_axis_tdest_reg = {DEST_WIDTH{1'b0}}; + reg [USER_WIDTH-1:0] s_axis_tuser_reg = {USER_WIDTH{1'b0}}; + + reg [M_DATA_WIDTH-1:0] m_axis_tdata_reg = {M_DATA_WIDTH{1'b0}}; + reg [M_KEEP_WIDTH-1:0] m_axis_tkeep_reg = {M_KEEP_WIDTH{1'b0}}; + reg m_axis_tvalid_reg = 1'b0; + reg m_axis_tlast_reg = 1'b0; + reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; + reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; + reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + + assign s_axis_tready = !s_axis_tvalid_reg; + + assign m_axis_tdata = m_axis_tdata_reg; + assign m_axis_tkeep = M_KEEP_ENABLE ? m_axis_tkeep_reg : {M_KEEP_WIDTH{1'b1}}; + assign m_axis_tvalid = m_axis_tvalid_reg; + assign m_axis_tlast = m_axis_tlast_reg; + assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; + assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; + assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; + + always @(posedge clk) begin + m_axis_tvalid_reg <= m_axis_tvalid_reg && !m_axis_tready; + + if (!m_axis_tvalid_reg || m_axis_tready) begin + // output register empty + + if (seg_reg == 0) begin + m_axis_tdata_reg[seg_reg*SEG_DATA_WIDTH +: SEG_DATA_WIDTH] <= s_axis_tvalid_reg ? s_axis_tdata_reg : s_axis_tdata; + m_axis_tkeep_reg <= s_axis_tvalid_reg ? s_axis_tkeep_reg : s_axis_tkeep; + end else begin + m_axis_tdata_reg[seg_reg*SEG_DATA_WIDTH +: SEG_DATA_WIDTH] <= s_axis_tdata; + m_axis_tkeep_reg[seg_reg*SEG_KEEP_WIDTH +: SEG_KEEP_WIDTH] <= s_axis_tkeep; + end + m_axis_tlast_reg <= s_axis_tvalid_reg ? s_axis_tlast_reg : s_axis_tlast; + m_axis_tid_reg <= s_axis_tvalid_reg ? s_axis_tid_reg : s_axis_tid; + m_axis_tdest_reg <= s_axis_tvalid_reg ? s_axis_tdest_reg : s_axis_tdest; + m_axis_tuser_reg <= s_axis_tvalid_reg ? s_axis_tuser_reg : s_axis_tuser; + + if (s_axis_tvalid_reg) begin + // consume data from buffer + s_axis_tvalid_reg <= 1'b0; + + if (s_axis_tlast_reg || seg_reg == SEG_COUNT-1) begin + seg_reg <= 0; + m_axis_tvalid_reg <= 1'b1; + end else begin + seg_reg <= seg_reg + 1; + end + end else if (s_axis_tvalid) begin + // data direct from input + if (s_axis_tlast || seg_reg == SEG_COUNT-1) begin + seg_reg <= 0; + m_axis_tvalid_reg <= 1'b1; + end else begin + seg_reg <= seg_reg + 1; + end + end + end else if (s_axis_tvalid && s_axis_tready) begin + // store input data in skid buffer + s_axis_tdata_reg <= s_axis_tdata; + s_axis_tkeep_reg <= s_axis_tkeep; + s_axis_tvalid_reg <= 1'b1; + s_axis_tlast_reg <= s_axis_tlast; + s_axis_tid_reg <= s_axis_tid; + s_axis_tdest_reg <= s_axis_tdest; + s_axis_tuser_reg <= s_axis_tuser; + end + + if (rst) begin + seg_reg <= 0; + s_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + end + end + +end else begin : downsize + // output is narrower; downsize + + // required number of segments in wider bus + localparam SEG_COUNT = S_BYTE_LANES / M_BYTE_LANES; + // data width and keep width per segment + localparam SEG_DATA_WIDTH = S_DATA_WIDTH / SEG_COUNT; + localparam SEG_KEEP_WIDTH = S_BYTE_LANES / SEG_COUNT; + + reg [S_DATA_WIDTH-1:0] s_axis_tdata_reg = {S_DATA_WIDTH{1'b0}}; + reg [S_KEEP_WIDTH-1:0] s_axis_tkeep_reg = {S_KEEP_WIDTH{1'b0}}; + reg s_axis_tvalid_reg = 1'b0; + reg s_axis_tlast_reg = 1'b0; + reg [ID_WIDTH-1:0] s_axis_tid_reg = {ID_WIDTH{1'b0}}; + reg [DEST_WIDTH-1:0] s_axis_tdest_reg = {DEST_WIDTH{1'b0}}; + reg [USER_WIDTH-1:0] s_axis_tuser_reg = {USER_WIDTH{1'b0}}; + + reg [M_DATA_WIDTH-1:0] m_axis_tdata_reg = {M_DATA_WIDTH{1'b0}}; + reg [M_KEEP_WIDTH-1:0] m_axis_tkeep_reg = {M_KEEP_WIDTH{1'b0}}; + reg m_axis_tvalid_reg = 1'b0; + reg m_axis_tlast_reg = 1'b0; + reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; + reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; + reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + + assign s_axis_tready = !s_axis_tvalid_reg; + + assign m_axis_tdata = m_axis_tdata_reg; + assign m_axis_tkeep = M_KEEP_ENABLE ? m_axis_tkeep_reg : {M_KEEP_WIDTH{1'b1}}; + assign m_axis_tvalid = m_axis_tvalid_reg; + assign m_axis_tlast = m_axis_tlast_reg; + assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; + assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; + assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; + + always @(posedge clk) begin + m_axis_tvalid_reg <= m_axis_tvalid_reg && !m_axis_tready; + + if (!m_axis_tvalid_reg || m_axis_tready) begin + // output register empty + + m_axis_tdata_reg <= s_axis_tvalid_reg ? s_axis_tdata_reg : s_axis_tdata; + m_axis_tkeep_reg <= s_axis_tvalid_reg ? s_axis_tkeep_reg : s_axis_tkeep; + m_axis_tlast_reg <= 1'b0; + m_axis_tid_reg <= s_axis_tvalid_reg ? s_axis_tid_reg : s_axis_tid; + m_axis_tdest_reg <= s_axis_tvalid_reg ? s_axis_tdest_reg : s_axis_tdest; + m_axis_tuser_reg <= s_axis_tvalid_reg ? s_axis_tuser_reg : s_axis_tuser; + + if (s_axis_tvalid_reg) begin + // buffer has data; shift out from buffer + s_axis_tdata_reg <= s_axis_tdata_reg >> SEG_DATA_WIDTH; + s_axis_tkeep_reg <= s_axis_tkeep_reg >> SEG_KEEP_WIDTH; + + m_axis_tvalid_reg <= 1'b1; + + if ((s_axis_tkeep_reg >> SEG_KEEP_WIDTH) == 0) begin + s_axis_tvalid_reg <= 1'b0; + m_axis_tlast_reg <= s_axis_tlast_reg; + end + end else if (s_axis_tvalid && s_axis_tready) begin + // buffer is empty; store from input + s_axis_tdata_reg <= s_axis_tdata >> SEG_DATA_WIDTH; + s_axis_tkeep_reg <= s_axis_tkeep >> SEG_KEEP_WIDTH; + s_axis_tlast_reg <= s_axis_tlast; + s_axis_tid_reg <= s_axis_tid; + s_axis_tdest_reg <= s_axis_tdest; + s_axis_tuser_reg <= s_axis_tuser; + + m_axis_tvalid_reg <= 1'b1; + + if ((s_axis_tkeep >> SEG_KEEP_WIDTH) == 0) begin + s_axis_tvalid_reg <= 1'b0; + m_axis_tlast_reg <= s_axis_tlast; + end else begin + s_axis_tvalid_reg <= 1'b1; + end + end + end else if (s_axis_tvalid && s_axis_tready) begin + // store input data + s_axis_tdata_reg <= s_axis_tdata; + s_axis_tkeep_reg <= s_axis_tkeep; + s_axis_tvalid_reg <= 1'b1; + s_axis_tlast_reg <= s_axis_tlast; + s_axis_tid_reg <= s_axis_tid; + s_axis_tdest_reg <= s_axis_tdest; + s_axis_tuser_reg <= s_axis_tuser; + end + + if (rst) begin + s_axis_tvalid_reg <= 1'b0; + m_axis_tvalid_reg <= 1'b0; + end + end + +end + +endgenerate + +endmodule + +`resetall diff --git a/src/rvvi/axis_async_fifo.sv b/src/rvvi/axis_async_fifo.sv new file mode 100644 index 000000000..1d8b6244f --- /dev/null +++ b/src/rvvi/axis_async_fifo.sv @@ -0,0 +1,909 @@ +/* + +Copyright (c) 2014-2023 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * AXI4-Stream asynchronous FIFO + */ +module axis_async_fifo # +( + // FIFO depth in words + // KEEP_WIDTH words per cycle if KEEP_ENABLE set + // Rounded up to nearest power of 2 cycles + parameter DEPTH = 4096, + // Width of AXI stream interfaces in bits + parameter DATA_WIDTH = 8, + // Propagate tkeep signal + // If disabled, tkeep assumed to be 1'b1 + parameter KEEP_ENABLE = (DATA_WIDTH>8), + // tkeep signal width (words per cycle) + parameter KEEP_WIDTH = ((DATA_WIDTH+7)/8), + // Propagate tlast signal + parameter LAST_ENABLE = 1, + // Propagate tid signal + parameter ID_ENABLE = 0, + // tid signal width + parameter ID_WIDTH = 8, + // Propagate tdest signal + parameter DEST_ENABLE = 0, + // tdest signal width + parameter DEST_WIDTH = 8, + // Propagate tuser signal + parameter USER_ENABLE = 1, + // tuser signal width + parameter USER_WIDTH = 1, + // number of RAM pipeline registers + parameter RAM_PIPELINE = 1, + // use output FIFO + // When set, the RAM read enable and pipeline clock enables are removed + parameter OUTPUT_FIFO_ENABLE = 0, + // Frame FIFO mode - operate on frames instead of cycles + // When set, m_axis_tvalid will not be deasserted within a frame + // Requires LAST_ENABLE set + parameter FRAME_FIFO = 0, + // tuser value for bad frame marker + parameter USER_BAD_FRAME_VALUE = 1'b1, + // tuser mask for bad frame marker + parameter USER_BAD_FRAME_MASK = 1'b1, + // Drop frames larger than FIFO + // Requires FRAME_FIFO set + parameter DROP_OVERSIZE_FRAME = FRAME_FIFO, + // Drop frames marked bad + // Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set + parameter DROP_BAD_FRAME = 0, + // Drop incoming frames when full + // When set, s_axis_tready is always asserted + // Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set + parameter DROP_WHEN_FULL = 0, + // Mark incoming frames as bad frames when full + // When set, s_axis_tready is always asserted + // Requires FRAME_FIFO to be clear + parameter MARK_WHEN_FULL = 0, + // Enable pause request input + parameter PAUSE_ENABLE = 0, + // Pause between frames + parameter FRAME_PAUSE = FRAME_FIFO +) +( + /* + * AXI input + */ + input wire s_clk, + input wire s_rst, + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI output + */ + input wire m_clk, + input wire m_rst, + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * Pause + */ + input wire s_pause_req, + output wire s_pause_ack, + input wire m_pause_req, + output wire m_pause_ack, + + /* + * Status + */ + output wire [$clog2(DEPTH):0] s_status_depth, + output wire [$clog2(DEPTH):0] s_status_depth_commit, + output wire s_status_overflow, + output wire s_status_bad_frame, + output wire s_status_good_frame, + output wire [$clog2(DEPTH):0] m_status_depth, + output wire [$clog2(DEPTH):0] m_status_depth_commit, + output wire m_status_overflow, + output wire m_status_bad_frame, + output wire m_status_good_frame +); + +parameter ADDR_WIDTH = (KEEP_ENABLE && KEEP_WIDTH > 1) ? $clog2(DEPTH/KEEP_WIDTH) : $clog2(DEPTH); + +parameter OUTPUT_FIFO_ADDR_WIDTH = RAM_PIPELINE < 2 ? 3 : $clog2(RAM_PIPELINE*2+7); + +// check configuration +initial begin + if (FRAME_FIFO && !LAST_ENABLE) begin + $error("Error: FRAME_FIFO set requires LAST_ENABLE set (instance %m)"); + $finish; + end + + if (DROP_OVERSIZE_FRAME && !FRAME_FIFO) begin + $error("Error: DROP_OVERSIZE_FRAME set requires FRAME_FIFO set (instance %m)"); + $finish; + end + + if (DROP_BAD_FRAME && !(FRAME_FIFO && DROP_OVERSIZE_FRAME)) begin + $error("Error: DROP_BAD_FRAME set requires FRAME_FIFO and DROP_OVERSIZE_FRAME set (instance %m)"); + $finish; + end + + if (DROP_WHEN_FULL && !(FRAME_FIFO && DROP_OVERSIZE_FRAME)) begin + $error("Error: DROP_WHEN_FULL set requires FRAME_FIFO and DROP_OVERSIZE_FRAME set (instance %m)"); + $finish; + end + + if ((DROP_BAD_FRAME || MARK_WHEN_FULL) && (USER_BAD_FRAME_MASK & {USER_WIDTH{1'b1}}) == 0) begin + $error("Error: Invalid USER_BAD_FRAME_MASK value (instance %m)"); + $finish; + end + + if (MARK_WHEN_FULL && FRAME_FIFO) begin + $error("Error: MARK_WHEN_FULL is not compatible with FRAME_FIFO (instance %m)"); + $finish; + end + + if (MARK_WHEN_FULL && !LAST_ENABLE) begin + $error("Error: MARK_WHEN_FULL set requires LAST_ENABLE set (instance %m)"); + $finish; + end +end + +localparam KEEP_OFFSET = DATA_WIDTH; +localparam LAST_OFFSET = KEEP_OFFSET + (KEEP_ENABLE ? KEEP_WIDTH : 0); +localparam ID_OFFSET = LAST_OFFSET + (LAST_ENABLE ? 1 : 0); +localparam DEST_OFFSET = ID_OFFSET + (ID_ENABLE ? ID_WIDTH : 0); +localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0); +localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); + +function [ADDR_WIDTH:0] bin2gray(input [ADDR_WIDTH:0] b); + bin2gray = b ^ (b >> 1); +endfunction + +function [ADDR_WIDTH:0] gray2bin(input [ADDR_WIDTH:0] g); + integer i; + for (i = 0; i <= ADDR_WIDTH; i = i + 1) begin + gray2bin[i] = ^(g >> i); + end +endfunction + +reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_commit_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_sync_commit_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] wr_ptr_conv_reg = {ADDR_WIDTH+1{1'b0}}; +reg [ADDR_WIDTH:0] rd_ptr_conv_reg = {ADDR_WIDTH+1{1'b0}}; + +reg [ADDR_WIDTH:0] wr_ptr_temp; +reg [ADDR_WIDTH:0] rd_ptr_temp; + +(* SHREG_EXTRACT = "NO" *) +reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; +(* SHREG_EXTRACT = "NO" *) +reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; +(* SHREG_EXTRACT = "NO" *) +reg [ADDR_WIDTH:0] wr_ptr_commit_sync_reg = {ADDR_WIDTH+1{1'b0}}; +(* SHREG_EXTRACT = "NO" *) +reg [ADDR_WIDTH:0] rd_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; +(* SHREG_EXTRACT = "NO" *) +reg [ADDR_WIDTH:0] rd_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; + +reg wr_ptr_update_valid_reg = 1'b0; +reg wr_ptr_update_reg = 1'b0; +(* SHREG_EXTRACT = "NO" *) +reg wr_ptr_update_sync1_reg = 1'b0; +(* SHREG_EXTRACT = "NO" *) +reg wr_ptr_update_sync2_reg = 1'b0; +(* SHREG_EXTRACT = "NO" *) +reg wr_ptr_update_sync3_reg = 1'b0; +(* SHREG_EXTRACT = "NO" *) +reg wr_ptr_update_ack_sync1_reg = 1'b0; +(* SHREG_EXTRACT = "NO" *) +reg wr_ptr_update_ack_sync2_reg = 1'b0; + +(* SHREG_EXTRACT = "NO" *) +reg s_rst_sync1_reg = 1'b1; +(* SHREG_EXTRACT = "NO" *) +reg s_rst_sync2_reg = 1'b1; +(* SHREG_EXTRACT = "NO" *) +reg s_rst_sync3_reg = 1'b1; +(* SHREG_EXTRACT = "NO" *) +reg m_rst_sync1_reg = 1'b1; +(* SHREG_EXTRACT = "NO" *) +reg m_rst_sync2_reg = 1'b1; +(* SHREG_EXTRACT = "NO" *) +reg m_rst_sync3_reg = 1'b1; + +(* ramstyle = "no_rw_check" *) +reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0]; +reg mem_read_data_valid_reg = 1'b0; + +(* shreg_extract = "no" *) +reg [WIDTH-1:0] m_axis_pipe_reg[RAM_PIPELINE+1-1:0]; +reg [RAM_PIPELINE+1-1:0] m_axis_tvalid_pipe_reg = 0; + +// full when first TWO MSBs do NOT match, but rest matches +// (gray code equivalent of first MSB different but rest same) +wire full = wr_ptr_gray_reg == (rd_ptr_gray_sync2_reg ^ {2'b11, {ADDR_WIDTH-1{1'b0}}}); +// empty when pointers match exactly +wire empty = FRAME_FIFO ? (rd_ptr_reg == wr_ptr_commit_sync_reg) : (rd_ptr_gray_reg == wr_ptr_gray_sync2_reg); +// overflow within packet +wire full_wr = wr_ptr_reg == (wr_ptr_commit_reg ^ {1'b1, {ADDR_WIDTH{1'b0}}}); + +// control signals +reg write; +reg read; +reg store_output; + +reg s_frame_reg = 1'b0; +reg m_frame_reg = 1'b0; + +reg drop_frame_reg = 1'b0; +reg mark_frame_reg = 1'b0; +reg send_frame_reg = 1'b0; +reg overflow_reg = 1'b0; +reg bad_frame_reg = 1'b0; +reg good_frame_reg = 1'b0; + +reg m_drop_frame_reg = 1'b0; +reg m_terminate_frame_reg = 1'b0; + +reg [ADDR_WIDTH:0] s_depth_reg = 0; +reg [ADDR_WIDTH:0] s_depth_commit_reg = 0; +reg [ADDR_WIDTH:0] m_depth_reg = 0; +reg [ADDR_WIDTH:0] m_depth_commit_reg = 0; + +reg overflow_sync1_reg = 1'b0; +reg overflow_sync2_reg = 1'b0; +reg overflow_sync3_reg = 1'b0; +reg overflow_sync4_reg = 1'b0; +reg bad_frame_sync1_reg = 1'b0; +reg bad_frame_sync2_reg = 1'b0; +reg bad_frame_sync3_reg = 1'b0; +reg bad_frame_sync4_reg = 1'b0; +reg good_frame_sync1_reg = 1'b0; +reg good_frame_sync2_reg = 1'b0; +reg good_frame_sync3_reg = 1'b0; +reg good_frame_sync4_reg = 1'b0; + +assign s_axis_tready = (FRAME_FIFO ? (!full || (full_wr && DROP_OVERSIZE_FRAME) || DROP_WHEN_FULL) : (!full || MARK_WHEN_FULL)) && !s_rst_sync3_reg; + +wire [WIDTH-1:0] s_axis; + +generate + assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata; + if (KEEP_ENABLE) assign s_axis[KEEP_OFFSET +: KEEP_WIDTH] = s_axis_tkeep; + if (LAST_ENABLE) assign s_axis[LAST_OFFSET] = s_axis_tlast | mark_frame_reg; + if (ID_ENABLE) assign s_axis[ID_OFFSET +: ID_WIDTH] = s_axis_tid; + if (DEST_ENABLE) assign s_axis[DEST_OFFSET +: DEST_WIDTH] = s_axis_tdest; + if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = mark_frame_reg ? USER_BAD_FRAME_VALUE : s_axis_tuser; +endgenerate + +wire [WIDTH-1:0] m_axis = m_axis_pipe_reg[RAM_PIPELINE+1-1]; + +wire m_axis_tready_pipe; +wire m_axis_tvalid_pipe = m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1]; + +wire [DATA_WIDTH-1:0] m_axis_tdata_pipe = m_axis[DATA_WIDTH-1:0]; +wire [KEEP_WIDTH-1:0] m_axis_tkeep_pipe = KEEP_ENABLE ? m_axis[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; +wire m_axis_tlast_pipe = LAST_ENABLE ? m_axis[LAST_OFFSET] | m_terminate_frame_reg : 1'b1; +wire [ID_WIDTH-1:0] m_axis_tid_pipe = ID_ENABLE ? m_axis[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; +wire [DEST_WIDTH-1:0] m_axis_tdest_pipe = DEST_ENABLE ? m_axis[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; +wire [USER_WIDTH-1:0] m_axis_tuser_pipe = USER_ENABLE ? (m_terminate_frame_reg ? USER_BAD_FRAME_VALUE : m_axis[USER_OFFSET +: USER_WIDTH]) : {USER_WIDTH{1'b0}}; + +wire m_axis_tready_out; +wire m_axis_tvalid_out; + +wire [DATA_WIDTH-1:0] m_axis_tdata_out; +wire [KEEP_WIDTH-1:0] m_axis_tkeep_out; +wire m_axis_tlast_out; +wire [ID_WIDTH-1:0] m_axis_tid_out; +wire [DEST_WIDTH-1:0] m_axis_tdest_out; +wire [USER_WIDTH-1:0] m_axis_tuser_out; + +wire pipe_ready; + +assign s_status_depth = (KEEP_ENABLE && KEEP_WIDTH > 1) ? {s_depth_reg, {$clog2(KEEP_WIDTH){1'b0}}} : s_depth_reg; +assign s_status_depth_commit = (KEEP_ENABLE && KEEP_WIDTH > 1) ? {s_depth_commit_reg, {$clog2(KEEP_WIDTH){1'b0}}} : s_depth_commit_reg; +assign s_status_overflow = overflow_reg; +assign s_status_bad_frame = bad_frame_reg; +assign s_status_good_frame = good_frame_reg; + +assign m_status_depth = (KEEP_ENABLE && KEEP_WIDTH > 1) ? {m_depth_reg, {$clog2(KEEP_WIDTH){1'b0}}} : m_depth_reg; +assign m_status_depth_commit = (KEEP_ENABLE && KEEP_WIDTH > 1) ? {m_depth_commit_reg, {$clog2(KEEP_WIDTH){1'b0}}} : m_depth_commit_reg; +assign m_status_overflow = overflow_sync3_reg ^ overflow_sync4_reg; +assign m_status_bad_frame = bad_frame_sync3_reg ^ bad_frame_sync4_reg; +assign m_status_good_frame = good_frame_sync3_reg ^ good_frame_sync4_reg; + +// reset synchronization +always @(posedge m_clk or posedge m_rst) begin + if (m_rst) begin + s_rst_sync1_reg <= 1'b1; + end else begin + s_rst_sync1_reg <= 1'b0; + end +end + +always @(posedge s_clk) begin + s_rst_sync2_reg <= s_rst_sync1_reg; + s_rst_sync3_reg <= s_rst_sync2_reg; +end + +always @(posedge s_clk or posedge s_rst) begin + if (s_rst) begin + m_rst_sync1_reg <= 1'b1; + end else begin + m_rst_sync1_reg <= 1'b0; + end +end + +always @(posedge m_clk) begin + m_rst_sync2_reg <= m_rst_sync1_reg; + m_rst_sync3_reg <= m_rst_sync2_reg; +end + +// Write logic +always @(posedge s_clk) begin + overflow_reg <= 1'b0; + bad_frame_reg <= 1'b0; + good_frame_reg <= 1'b0; + + if (FRAME_FIFO && wr_ptr_update_valid_reg) begin + // have updated pointer to sync + if (wr_ptr_update_reg == wr_ptr_update_ack_sync2_reg) begin + // no sync in progress; sync update + wr_ptr_update_valid_reg <= 1'b0; + wr_ptr_sync_commit_reg <= wr_ptr_commit_reg; + wr_ptr_update_reg <= !wr_ptr_update_ack_sync2_reg; + end + end + + if (s_axis_tready && s_axis_tvalid && LAST_ENABLE) begin + // track input frame status + s_frame_reg <= !s_axis_tlast; + end + + if (s_rst_sync3_reg && LAST_ENABLE) begin + // if sink side is reset during transfer, drop partial frame + if (s_frame_reg && !(s_axis_tready && s_axis_tvalid && s_axis_tlast)) begin + drop_frame_reg <= 1'b1; + end + if (s_axis_tready && s_axis_tvalid && !s_axis_tlast) begin + drop_frame_reg <= 1'b1; + end + end + + if (FRAME_FIFO) begin + // frame FIFO mode + if (s_axis_tready && s_axis_tvalid) begin + // transfer in + if ((full && DROP_WHEN_FULL) || (full_wr && DROP_OVERSIZE_FRAME) || drop_frame_reg) begin + // full, packet overflow, or currently dropping frame + // drop frame + drop_frame_reg <= 1'b1; + if (s_axis_tlast) begin + // end of frame, reset write pointer + wr_ptr_temp = wr_ptr_commit_reg; + wr_ptr_reg <= wr_ptr_temp; + wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); + drop_frame_reg <= 1'b0; + overflow_reg <= 1'b1; + end + end else begin + mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis; + wr_ptr_temp = wr_ptr_reg + 1; + wr_ptr_reg <= wr_ptr_temp; + wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); + if (s_axis_tlast || (!DROP_OVERSIZE_FRAME && (full_wr || send_frame_reg))) begin + // end of frame or send frame + send_frame_reg <= !s_axis_tlast; + if (s_axis_tlast && DROP_BAD_FRAME && USER_BAD_FRAME_MASK & ~(s_axis_tuser ^ USER_BAD_FRAME_VALUE)) begin + // bad packet, reset write pointer + wr_ptr_temp = wr_ptr_commit_reg; + wr_ptr_reg <= wr_ptr_temp; + wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); + bad_frame_reg <= 1'b1; + end else begin + // good packet or packet overflow, update write pointer + wr_ptr_temp = wr_ptr_reg + 1; + wr_ptr_reg <= wr_ptr_temp; + wr_ptr_commit_reg <= wr_ptr_temp; + wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); + + if (wr_ptr_update_reg == wr_ptr_update_ack_sync2_reg) begin + // no sync in progress; sync update + wr_ptr_update_valid_reg <= 1'b0; + wr_ptr_sync_commit_reg <= wr_ptr_temp; + wr_ptr_update_reg <= !wr_ptr_update_ack_sync2_reg; + end else begin + // sync in progress; flag it for later + wr_ptr_update_valid_reg <= 1'b1; + end + + good_frame_reg <= s_axis_tlast; + end + end + end + end else if (s_axis_tvalid && full_wr && FRAME_FIFO && !DROP_OVERSIZE_FRAME) begin + // data valid with packet overflow + // update write pointer + send_frame_reg <= 1'b1; + wr_ptr_temp = wr_ptr_reg; + wr_ptr_reg <= wr_ptr_temp; + wr_ptr_commit_reg <= wr_ptr_temp; + wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); + + if (wr_ptr_update_reg == wr_ptr_update_ack_sync2_reg) begin + // no sync in progress; sync update + wr_ptr_update_valid_reg <= 1'b0; + wr_ptr_sync_commit_reg <= wr_ptr_temp; + wr_ptr_update_reg <= !wr_ptr_update_ack_sync2_reg; + end else begin + // sync in progress; flag it for later + wr_ptr_update_valid_reg <= 1'b1; + end + end + end else begin + // normal FIFO mode + if (s_axis_tready && s_axis_tvalid) begin + if (drop_frame_reg && LAST_ENABLE) begin + // currently dropping frame + if (s_axis_tlast) begin + // end of frame + if (!full && mark_frame_reg && MARK_WHEN_FULL) begin + // terminate marked frame + mark_frame_reg <= 1'b0; + mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis; + wr_ptr_temp = wr_ptr_reg + 1; + wr_ptr_reg <= wr_ptr_temp; + wr_ptr_commit_reg <= wr_ptr_temp; + wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); + end + // end of frame, clear drop flag + drop_frame_reg <= 1'b0; + overflow_reg <= 1'b1; + end + end else if ((full || mark_frame_reg) && MARK_WHEN_FULL) begin + // full or marking frame + // drop frame; mark if this isn't the first cycle + drop_frame_reg <= 1'b1; + mark_frame_reg <= mark_frame_reg || s_frame_reg; + if (s_axis_tlast) begin + drop_frame_reg <= 1'b0; + overflow_reg <= 1'b1; + end + end else begin + // transfer in + mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis; + wr_ptr_temp = wr_ptr_reg + 1; + wr_ptr_reg <= wr_ptr_temp; + wr_ptr_commit_reg <= wr_ptr_temp; + wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); + end + end else if ((!full && !drop_frame_reg && mark_frame_reg) && MARK_WHEN_FULL) begin + // terminate marked frame + mark_frame_reg <= 1'b0; + mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis; + wr_ptr_temp = wr_ptr_reg + 1; + wr_ptr_reg <= wr_ptr_temp; + wr_ptr_commit_reg <= wr_ptr_temp; + wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); + end + end + + if (s_rst_sync3_reg) begin + wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_commit_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_sync_commit_reg <= {ADDR_WIDTH+1{1'b0}}; + + wr_ptr_update_valid_reg <= 1'b0; + wr_ptr_update_reg <= 1'b0; + end + + if (s_rst) begin + wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_commit_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_sync_commit_reg <= {ADDR_WIDTH+1{1'b0}}; + + wr_ptr_update_valid_reg <= 1'b0; + wr_ptr_update_reg <= 1'b0; + + s_frame_reg <= 1'b0; + + drop_frame_reg <= 1'b0; + mark_frame_reg <= 1'b0; + send_frame_reg <= 1'b0; + overflow_reg <= 1'b0; + bad_frame_reg <= 1'b0; + good_frame_reg <= 1'b0; + end +end + +// Write-side status +always @(posedge s_clk) begin + rd_ptr_conv_reg <= gray2bin(rd_ptr_gray_sync2_reg); + s_depth_reg <= wr_ptr_reg - rd_ptr_conv_reg; + s_depth_commit_reg <= wr_ptr_commit_reg - rd_ptr_conv_reg; +end + +// pointer synchronization +always @(posedge s_clk) begin + rd_ptr_gray_sync1_reg <= rd_ptr_gray_reg; + rd_ptr_gray_sync2_reg <= rd_ptr_gray_sync1_reg; + wr_ptr_update_ack_sync1_reg <= wr_ptr_update_sync3_reg; + wr_ptr_update_ack_sync2_reg <= wr_ptr_update_ack_sync1_reg; + + if (s_rst) begin + rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; + rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_update_ack_sync1_reg <= 1'b0; + wr_ptr_update_ack_sync2_reg <= 1'b0; + end +end + +always @(posedge m_clk) begin + wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg; + wr_ptr_gray_sync2_reg <= wr_ptr_gray_sync1_reg; + if (FRAME_FIFO && wr_ptr_update_sync2_reg ^ wr_ptr_update_sync3_reg) begin + wr_ptr_commit_sync_reg <= wr_ptr_sync_commit_reg; + end + wr_ptr_update_sync1_reg <= wr_ptr_update_reg; + wr_ptr_update_sync2_reg <= wr_ptr_update_sync1_reg; + wr_ptr_update_sync3_reg <= wr_ptr_update_sync2_reg; + + if (FRAME_FIFO && m_rst_sync3_reg) begin + wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; + end + + if (m_rst) begin + wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_commit_sync_reg <= {ADDR_WIDTH+1{1'b0}}; + wr_ptr_update_sync1_reg <= 1'b0; + wr_ptr_update_sync2_reg <= 1'b0; + wr_ptr_update_sync3_reg <= 1'b0; + end +end + +// status synchronization +always @(posedge s_clk) begin + overflow_sync1_reg <= overflow_sync1_reg ^ overflow_reg; + bad_frame_sync1_reg <= bad_frame_sync1_reg ^ bad_frame_reg; + good_frame_sync1_reg <= good_frame_sync1_reg ^ good_frame_reg; + + if (s_rst) begin + overflow_sync1_reg <= 1'b0; + bad_frame_sync1_reg <= 1'b0; + good_frame_sync1_reg <= 1'b0; + end +end + +always @(posedge m_clk) begin + overflow_sync2_reg <= overflow_sync1_reg; + overflow_sync3_reg <= overflow_sync2_reg; + overflow_sync4_reg <= overflow_sync3_reg; + bad_frame_sync2_reg <= bad_frame_sync1_reg; + bad_frame_sync3_reg <= bad_frame_sync2_reg; + bad_frame_sync4_reg <= bad_frame_sync3_reg; + good_frame_sync2_reg <= good_frame_sync1_reg; + good_frame_sync3_reg <= good_frame_sync2_reg; + good_frame_sync4_reg <= good_frame_sync3_reg; + + if (m_rst) begin + overflow_sync2_reg <= 1'b0; + overflow_sync3_reg <= 1'b0; + overflow_sync4_reg <= 1'b0; + bad_frame_sync2_reg <= 1'b0; + bad_frame_sync3_reg <= 1'b0; + bad_frame_sync4_reg <= 1'b0; + good_frame_sync2_reg <= 1'b0; + good_frame_sync3_reg <= 1'b0; + good_frame_sync4_reg <= 1'b0; + end +end + +// Read logic +integer j; + +always @(posedge m_clk) begin + if (m_axis_tready_pipe) begin + // output ready; invalidate stage + m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1] <= 1'b0; + m_terminate_frame_reg <= 1'b0; + end + + for (j = RAM_PIPELINE+1-1; j > 0; j = j - 1) begin + if (m_axis_tready_pipe || ((~m_axis_tvalid_pipe_reg) >> j)) begin + // output ready or bubble in pipeline; transfer down pipeline + m_axis_tvalid_pipe_reg[j] <= m_axis_tvalid_pipe_reg[j-1]; + m_axis_pipe_reg[j] <= m_axis_pipe_reg[j-1]; + m_axis_tvalid_pipe_reg[j-1] <= 1'b0; + end + end + + if (m_axis_tready_pipe || ~m_axis_tvalid_pipe_reg) begin + // output ready or bubble in pipeline; read new data from FIFO + m_axis_tvalid_pipe_reg[0] <= 1'b0; + m_axis_pipe_reg[0] <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; + if (!empty && !m_rst_sync3_reg && !m_drop_frame_reg && pipe_ready) begin + // not empty, increment pointer + m_axis_tvalid_pipe_reg[0] <= 1'b1; + rd_ptr_temp = rd_ptr_reg + 1; + rd_ptr_reg <= rd_ptr_temp; + rd_ptr_gray_reg <= rd_ptr_temp ^ (rd_ptr_temp >> 1); + end + end + + if (m_axis_tvalid_pipe && LAST_ENABLE) begin + // track output frame status + if (m_axis_tlast_pipe && m_axis_tready_pipe) begin + m_frame_reg <= 1'b0; + end else begin + m_frame_reg <= 1'b1; + end + end + + if (m_drop_frame_reg && (OUTPUT_FIFO_ENABLE ? pipe_ready : m_axis_tready_pipe || !m_axis_tvalid_pipe) && LAST_ENABLE) begin + // terminate frame + // (only for frame transfers interrupted by source reset) + m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1] <= 1'b1; + m_terminate_frame_reg <= 1'b1; + m_drop_frame_reg <= 1'b0; + end + + if (m_rst_sync3_reg && LAST_ENABLE) begin + // if source side is reset during transfer, drop partial frame + + // empty output pipeline, except for last stage + if (RAM_PIPELINE > 0) begin + m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-2:0] <= 0; + end + + if (m_frame_reg && (!m_axis_tvalid_pipe || (m_axis_tvalid_pipe && !m_axis_tlast_pipe)) && + !(m_drop_frame_reg || m_terminate_frame_reg)) begin + // terminate frame + m_drop_frame_reg <= 1'b1; + end + end + + if (m_rst_sync3_reg) begin + rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + end + + if (m_rst) begin + rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; + rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; + m_axis_tvalid_pipe_reg <= 0; + m_frame_reg <= 1'b0; + m_drop_frame_reg <= 1'b0; + m_terminate_frame_reg <= 1'b0; + end +end + +// Read-side status +always @(posedge m_clk) begin + wr_ptr_conv_reg <= gray2bin(wr_ptr_gray_sync2_reg); + m_depth_reg <= wr_ptr_conv_reg - rd_ptr_reg; + m_depth_commit_reg <= FRAME_FIFO ? wr_ptr_commit_sync_reg - rd_ptr_reg : wr_ptr_conv_reg - rd_ptr_reg; +end + +generate + +if (!OUTPUT_FIFO_ENABLE) begin + + assign pipe_ready = 1'b1; + + assign m_axis_tready_pipe = m_axis_tready_out; + assign m_axis_tvalid_out = m_axis_tvalid_pipe; + + assign m_axis_tdata_out = m_axis_tdata_pipe; + assign m_axis_tkeep_out = m_axis_tkeep_pipe; + assign m_axis_tlast_out = m_axis_tlast_pipe; + assign m_axis_tid_out = m_axis_tid_pipe; + assign m_axis_tdest_out = m_axis_tdest_pipe; + assign m_axis_tuser_out = m_axis_tuser_pipe; + +end else begin : output_fifo + + // output datapath logic + reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; + reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; + reg m_axis_tvalid_reg = 1'b0; + reg m_axis_tlast_reg = 1'b0; + reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; + reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; + reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + + reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_fifo_wr_ptr_reg = 0; + reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_fifo_rd_ptr_reg = 0; + reg out_fifo_half_full_reg = 1'b0; + + wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}}); + wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg; + + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) + reg [DATA_WIDTH-1:0] out_fifo_tdata[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) + reg [KEEP_WIDTH-1:0] out_fifo_tkeep[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) + reg out_fifo_tlast[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) + reg [ID_WIDTH-1:0] out_fifo_tid[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) + reg [DEST_WIDTH-1:0] out_fifo_tdest[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; + (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) + reg [USER_WIDTH-1:0] out_fifo_tuser[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; + + assign pipe_ready = !out_fifo_half_full_reg; + + assign m_axis_tready_pipe = 1'b1; + + assign m_axis_tdata_out = m_axis_tdata_reg; + assign m_axis_tkeep_out = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; + assign m_axis_tvalid_out = m_axis_tvalid_reg; + assign m_axis_tlast_out = LAST_ENABLE ? m_axis_tlast_reg : 1'b1; + assign m_axis_tid_out = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; + assign m_axis_tdest_out = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; + assign m_axis_tuser_out = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; + + always @(posedge m_clk) begin + m_axis_tvalid_reg <= m_axis_tvalid_reg && !m_axis_tready_out; + + out_fifo_half_full_reg <= $unsigned(out_fifo_wr_ptr_reg - out_fifo_rd_ptr_reg) >= 2**(OUTPUT_FIFO_ADDR_WIDTH-1); + + if (!out_fifo_full && m_axis_tvalid_pipe) begin + out_fifo_tdata[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tdata_pipe; + out_fifo_tkeep[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tkeep_pipe; + out_fifo_tlast[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tlast_pipe; + out_fifo_tid[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tid_pipe; + out_fifo_tdest[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tdest_pipe; + out_fifo_tuser[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tuser_pipe; + out_fifo_wr_ptr_reg <= out_fifo_wr_ptr_reg + 1; + end + + if (!out_fifo_empty && (!m_axis_tvalid_reg || m_axis_tready_out)) begin + m_axis_tdata_reg <= out_fifo_tdata[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + m_axis_tkeep_reg <= out_fifo_tkeep[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + m_axis_tvalid_reg <= 1'b1; + m_axis_tlast_reg <= out_fifo_tlast[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + m_axis_tid_reg <= out_fifo_tid[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + m_axis_tdest_reg <= out_fifo_tdest[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + m_axis_tuser_reg <= out_fifo_tuser[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; + out_fifo_rd_ptr_reg <= out_fifo_rd_ptr_reg + 1; + end + + if (m_rst) begin + out_fifo_wr_ptr_reg <= 0; + out_fifo_rd_ptr_reg <= 0; + m_axis_tvalid_reg <= 1'b0; + end + end + +end + +if (PAUSE_ENABLE) begin : pause + + // Pause logic + reg pause_reg = 1'b0; + reg pause_frame_reg = 1'b0; + + reg s_pause_req_sync1_reg; + reg s_pause_req_sync2_reg; + reg s_pause_req_sync3_reg; + reg s_pause_ack_sync1_reg; + reg s_pause_ack_sync2_reg; + reg s_pause_ack_sync3_reg; + + always @(posedge s_clk) begin + s_pause_req_sync1_reg <= s_pause_req; + s_pause_ack_sync2_reg <= s_pause_ack_sync1_reg; + s_pause_ack_sync3_reg <= s_pause_ack_sync2_reg; + end + + always @(posedge m_clk) begin + s_pause_req_sync2_reg <= s_pause_req_sync1_reg; + s_pause_req_sync3_reg <= s_pause_req_sync2_reg; + s_pause_ack_sync1_reg <= pause_reg; + end + + assign m_axis_tready_out = m_axis_tready && !pause_reg; + assign m_axis_tvalid = m_axis_tvalid_out && !pause_reg; + + assign m_axis_tdata = m_axis_tdata_out; + assign m_axis_tkeep = m_axis_tkeep_out; + assign m_axis_tlast = m_axis_tlast_out; + assign m_axis_tid = m_axis_tid_out; + assign m_axis_tdest = m_axis_tdest_out; + assign m_axis_tuser = m_axis_tuser_out; + + assign s_pause_ack = s_pause_ack_sync3_reg; + assign m_pause_ack = pause_reg; + + always @(posedge m_clk) begin + if (FRAME_PAUSE) begin + if (pause_reg) begin + // paused; update pause status + pause_reg <= m_pause_req || s_pause_req_sync3_reg; + end else if (m_axis_tvalid_out) begin + // frame transfer; set frame bit + pause_frame_reg <= 1'b1; + if (m_axis_tready && m_axis_tlast) begin + // end of frame; clear frame bit and update pause status + pause_frame_reg <= 1'b0; + pause_reg <= m_pause_req || s_pause_req_sync3_reg; + end + end else if (!pause_frame_reg) begin + // idle; update pause status + pause_reg <= m_pause_req || s_pause_req_sync3_reg; + end + end else begin + pause_reg <= m_pause_req || s_pause_req_sync3_reg; + end + + if (m_rst) begin + pause_frame_reg <= 1'b0; + pause_reg <= 1'b0; + end + end + +end else begin + + assign m_axis_tready_out = m_axis_tready; + assign m_axis_tvalid = m_axis_tvalid_out; + + assign m_axis_tdata = m_axis_tdata_out; + assign m_axis_tkeep = m_axis_tkeep_out; + assign m_axis_tlast = m_axis_tlast_out; + assign m_axis_tid = m_axis_tid_out; + assign m_axis_tdest = m_axis_tdest_out; + assign m_axis_tuser = m_axis_tuser_out; + + assign s_pause_ack = 1'b0; + assign m_pause_ack = 1'b0; + +end + +endgenerate + +endmodule + +`resetall diff --git a/src/rvvi/axis_async_fifo_adapter.sv b/src/rvvi/axis_async_fifo_adapter.sv new file mode 100644 index 000000000..d1e71b9fc --- /dev/null +++ b/src/rvvi/axis_async_fifo_adapter.sv @@ -0,0 +1,377 @@ +/* + +Copyright (c) 2019 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * AXI4-Stream asynchronous FIFO with width converter + */ +module axis_async_fifo_adapter # +( + // FIFO depth in words + // KEEP_WIDTH words per cycle if KEEP_ENABLE set + // Rounded up to nearest power of 2 cycles + parameter DEPTH = 4096, + // Width of input AXI stream interface in bits + parameter S_DATA_WIDTH = 8, + // Propagate tkeep signal on input interface + // If disabled, tkeep assumed to be 1'b1 + parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8), + // tkeep signal width (words per cycle) on input interface + parameter S_KEEP_WIDTH = ((S_DATA_WIDTH+7)/8), + // Width of output AXI stream interface in bits + parameter M_DATA_WIDTH = 8, + // Propagate tkeep signal on output interface + // If disabled, tkeep assumed to be 1'b1 + parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8), + // tkeep signal width (words per cycle) on output interface + parameter M_KEEP_WIDTH = ((M_DATA_WIDTH+7)/8), + // Propagate tid signal + parameter ID_ENABLE = 0, + // tid signal width + parameter ID_WIDTH = 8, + // Propagate tdest signal + parameter DEST_ENABLE = 0, + // tdest signal width + parameter DEST_WIDTH = 8, + // Propagate tuser signal + parameter USER_ENABLE = 1, + // tuser signal width + parameter USER_WIDTH = 1, + // number of RAM pipeline registers in FIFO + parameter RAM_PIPELINE = 1, + // use output FIFO + // When set, the RAM read enable and pipeline clock enables are removed + parameter OUTPUT_FIFO_ENABLE = 0, + // Frame FIFO mode - operate on frames instead of cycles + // When set, m_axis_tvalid will not be deasserted within a frame + // Requires LAST_ENABLE set + parameter FRAME_FIFO = 0, + // tuser value for bad frame marker + parameter USER_BAD_FRAME_VALUE = 1'b1, + // tuser mask for bad frame marker + parameter USER_BAD_FRAME_MASK = 1'b1, + // Drop frames larger than FIFO + // Requires FRAME_FIFO set + parameter DROP_OVERSIZE_FRAME = FRAME_FIFO, + // Drop frames marked bad + // Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set + parameter DROP_BAD_FRAME = 0, + // Drop incoming frames when full + // When set, s_axis_tready is always asserted + // Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set + parameter DROP_WHEN_FULL = 0, + // Mark incoming frames as bad frames when full + // When set, s_axis_tready is always asserted + // Requires FRAME_FIFO to be clear + parameter MARK_WHEN_FULL = 0, + // Enable pause request input + parameter PAUSE_ENABLE = 0, + // Pause between frames + parameter FRAME_PAUSE = FRAME_FIFO +) +( + /* + * AXI input + */ + input wire s_clk, + input wire s_rst, + input wire [S_DATA_WIDTH-1:0] s_axis_tdata, + input wire [S_KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI output + */ + input wire m_clk, + input wire m_rst, + output wire [M_DATA_WIDTH-1:0] m_axis_tdata, + output wire [M_KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * Pause + */ + input wire s_pause_req, + output wire s_pause_ack, + input wire m_pause_req, + output wire m_pause_ack, + + /* + * Status + */ + output wire [$clog2(DEPTH):0] s_status_depth, + output wire [$clog2(DEPTH):0] s_status_depth_commit, + output wire s_status_overflow, + output wire s_status_bad_frame, + output wire s_status_good_frame, + output wire [$clog2(DEPTH):0] m_status_depth, + output wire [$clog2(DEPTH):0] m_status_depth_commit, + output wire m_status_overflow, + output wire m_status_bad_frame, + output wire m_status_good_frame +); + +// force keep width to 1 when disabled +localparam S_BYTE_LANES = S_KEEP_ENABLE ? S_KEEP_WIDTH : 1; +localparam M_BYTE_LANES = M_KEEP_ENABLE ? M_KEEP_WIDTH : 1; + +// bus byte sizes (must be identical) +localparam S_BYTE_SIZE = S_DATA_WIDTH / S_BYTE_LANES; +localparam M_BYTE_SIZE = M_DATA_WIDTH / M_BYTE_LANES; +// output bus is wider +localparam EXPAND_BUS = M_BYTE_LANES > S_BYTE_LANES; +// total data and keep widths +localparam DATA_WIDTH = EXPAND_BUS ? M_DATA_WIDTH : S_DATA_WIDTH; +localparam KEEP_WIDTH = EXPAND_BUS ? M_BYTE_LANES : S_BYTE_LANES; + +// bus width assertions +initial begin + if (S_BYTE_SIZE * S_BYTE_LANES != S_DATA_WIDTH) begin + $error("Error: input data width not evenly divisible (instance %m)"); + $finish; + end + + if (M_BYTE_SIZE * M_BYTE_LANES != M_DATA_WIDTH) begin + $error("Error: output data width not evenly divisible (instance %m)"); + $finish; + end + + if (S_BYTE_SIZE != M_BYTE_SIZE) begin + $error("Error: byte size mismatch (instance %m)"); + $finish; + end +end + +wire [DATA_WIDTH-1:0] pre_fifo_axis_tdata; +wire [KEEP_WIDTH-1:0] pre_fifo_axis_tkeep; +wire pre_fifo_axis_tvalid; +wire pre_fifo_axis_tready; +wire pre_fifo_axis_tlast; +wire [ID_WIDTH-1:0] pre_fifo_axis_tid; +wire [DEST_WIDTH-1:0] pre_fifo_axis_tdest; +wire [USER_WIDTH-1:0] pre_fifo_axis_tuser; + +wire [DATA_WIDTH-1:0] post_fifo_axis_tdata; +wire [KEEP_WIDTH-1:0] post_fifo_axis_tkeep; +wire post_fifo_axis_tvalid; +wire post_fifo_axis_tready; +wire post_fifo_axis_tlast; +wire [ID_WIDTH-1:0] post_fifo_axis_tid; +wire [DEST_WIDTH-1:0] post_fifo_axis_tdest; +wire [USER_WIDTH-1:0] post_fifo_axis_tuser; + +generate + +if (M_BYTE_LANES > S_BYTE_LANES) begin : upsize_pre + + // output wider, adapt width before FIFO + + axis_adapter #( + .S_DATA_WIDTH(S_DATA_WIDTH), + .S_KEEP_ENABLE(S_KEEP_ENABLE), + .S_KEEP_WIDTH(S_KEEP_WIDTH), + .M_DATA_WIDTH(M_DATA_WIDTH), + .M_KEEP_ENABLE(M_KEEP_ENABLE), + .M_KEEP_WIDTH(M_KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) + ) + adapter_inst ( + .clk(s_clk), + .rst(s_rst), + // AXI input + .s_axis_tdata(s_axis_tdata), + .s_axis_tkeep(s_axis_tkeep), + .s_axis_tvalid(s_axis_tvalid), + .s_axis_tready(s_axis_tready), + .s_axis_tlast(s_axis_tlast), + .s_axis_tid(s_axis_tid), + .s_axis_tdest(s_axis_tdest), + .s_axis_tuser(s_axis_tuser), + // AXI output + .m_axis_tdata(pre_fifo_axis_tdata), + .m_axis_tkeep(pre_fifo_axis_tkeep), + .m_axis_tvalid(pre_fifo_axis_tvalid), + .m_axis_tready(pre_fifo_axis_tready), + .m_axis_tlast(pre_fifo_axis_tlast), + .m_axis_tid(pre_fifo_axis_tid), + .m_axis_tdest(pre_fifo_axis_tdest), + .m_axis_tuser(pre_fifo_axis_tuser) + ); + +end else begin : bypass_pre + + assign pre_fifo_axis_tdata = s_axis_tdata; + assign pre_fifo_axis_tkeep = s_axis_tkeep; + assign pre_fifo_axis_tvalid = s_axis_tvalid; + assign s_axis_tready = pre_fifo_axis_tready; + assign pre_fifo_axis_tlast = s_axis_tlast; + assign pre_fifo_axis_tid = s_axis_tid; + assign pre_fifo_axis_tdest = s_axis_tdest; + assign pre_fifo_axis_tuser = s_axis_tuser; + +end + +axis_async_fifo #( + .DEPTH(DEPTH), + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(EXPAND_BUS ? M_KEEP_ENABLE : S_KEEP_ENABLE), + .KEEP_WIDTH(KEEP_WIDTH), + .LAST_ENABLE(1), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH), + .RAM_PIPELINE(RAM_PIPELINE), + .OUTPUT_FIFO_ENABLE(OUTPUT_FIFO_ENABLE), + .FRAME_FIFO(FRAME_FIFO), + .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), + .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), + .DROP_OVERSIZE_FRAME(DROP_OVERSIZE_FRAME), + .DROP_BAD_FRAME(DROP_BAD_FRAME), + .DROP_WHEN_FULL(DROP_WHEN_FULL), + .MARK_WHEN_FULL(MARK_WHEN_FULL), + .PAUSE_ENABLE(PAUSE_ENABLE), + .FRAME_PAUSE(FRAME_PAUSE) +) +fifo_inst ( + // AXI input + .s_clk(s_clk), + .s_rst(s_rst), + .s_axis_tdata(pre_fifo_axis_tdata), + .s_axis_tkeep(pre_fifo_axis_tkeep), + .s_axis_tvalid(pre_fifo_axis_tvalid), + .s_axis_tready(pre_fifo_axis_tready), + .s_axis_tlast(pre_fifo_axis_tlast), + .s_axis_tid(pre_fifo_axis_tid), + .s_axis_tdest(pre_fifo_axis_tdest), + .s_axis_tuser(pre_fifo_axis_tuser), + // AXI output + .m_clk(m_clk), + .m_rst(m_rst), + .m_axis_tdata(post_fifo_axis_tdata), + .m_axis_tkeep(post_fifo_axis_tkeep), + .m_axis_tvalid(post_fifo_axis_tvalid), + .m_axis_tready(post_fifo_axis_tready), + .m_axis_tlast(post_fifo_axis_tlast), + .m_axis_tid(post_fifo_axis_tid), + .m_axis_tdest(post_fifo_axis_tdest), + .m_axis_tuser(post_fifo_axis_tuser), + // Pause + .s_pause_req(s_pause_req), + .s_pause_ack(s_pause_ack), + .m_pause_req(m_pause_req), + .m_pause_ack(m_pause_ack), + // Status + .s_status_depth(s_status_depth), + .s_status_depth_commit(s_status_depth_commit), + .s_status_overflow(s_status_overflow), + .s_status_bad_frame(s_status_bad_frame), + .s_status_good_frame(s_status_good_frame), + .m_status_depth(m_status_depth), + .m_status_depth_commit(m_status_depth_commit), + .m_status_overflow(m_status_overflow), + .m_status_bad_frame(m_status_bad_frame), + .m_status_good_frame(m_status_good_frame) +); + +if (M_BYTE_LANES < S_BYTE_LANES) begin : downsize_post + + // input wider, adapt width after FIFO + + axis_adapter #( + .S_DATA_WIDTH(S_DATA_WIDTH), + .S_KEEP_ENABLE(S_KEEP_ENABLE), + .S_KEEP_WIDTH(S_KEEP_WIDTH), + .M_DATA_WIDTH(M_DATA_WIDTH), + .M_KEEP_ENABLE(M_KEEP_ENABLE), + .M_KEEP_WIDTH(M_KEEP_WIDTH), + .ID_ENABLE(ID_ENABLE), + .ID_WIDTH(ID_WIDTH), + .DEST_ENABLE(DEST_ENABLE), + .DEST_WIDTH(DEST_WIDTH), + .USER_ENABLE(USER_ENABLE), + .USER_WIDTH(USER_WIDTH) + ) + adapter_inst ( + .clk(m_clk), + .rst(m_rst), + // AXI input + .s_axis_tdata(post_fifo_axis_tdata), + .s_axis_tkeep(post_fifo_axis_tkeep), + .s_axis_tvalid(post_fifo_axis_tvalid), + .s_axis_tready(post_fifo_axis_tready), + .s_axis_tlast(post_fifo_axis_tlast), + .s_axis_tid(post_fifo_axis_tid), + .s_axis_tdest(post_fifo_axis_tdest), + .s_axis_tuser(post_fifo_axis_tuser), + // AXI output + .m_axis_tdata(m_axis_tdata), + .m_axis_tkeep(m_axis_tkeep), + .m_axis_tvalid(m_axis_tvalid), + .m_axis_tready(m_axis_tready), + .m_axis_tlast(m_axis_tlast), + .m_axis_tid(m_axis_tid), + .m_axis_tdest(m_axis_tdest), + .m_axis_tuser(m_axis_tuser) + ); + +end else begin : bypass_post + + assign m_axis_tdata = post_fifo_axis_tdata; + assign m_axis_tkeep = post_fifo_axis_tkeep; + assign m_axis_tvalid = post_fifo_axis_tvalid; + assign post_fifo_axis_tready = m_axis_tready; + assign m_axis_tlast = post_fifo_axis_tlast; + assign m_axis_tid = post_fifo_axis_tid; + assign m_axis_tdest = post_fifo_axis_tdest; + assign m_axis_tuser = post_fifo_axis_tuser; + +end + +endgenerate + +endmodule + +`resetall diff --git a/src/rvvi/axis_gmii_rx.sv b/src/rvvi/axis_gmii_rx.sv new file mode 100644 index 000000000..037fce77a --- /dev/null +++ b/src/rvvi/axis_gmii_rx.sv @@ -0,0 +1,357 @@ +/* + +Copyright (c) 2015-2018 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * AXI4-Stream GMII frame receiver (GMII in, AXI out) + */ +module axis_gmii_rx # +( + parameter DATA_WIDTH = 8, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1 +) +( + input wire clk, + input wire rst, + + /* + * GMII input + */ + input wire [DATA_WIDTH-1:0] gmii_rxd, + input wire gmii_rx_dv, + input wire gmii_rx_er, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire m_axis_tvalid, + output wire m_axis_tlast, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, + + /* + * Control + */ + input wire clk_enable, + input wire mii_select, + + /* + * Configuration + */ + input wire cfg_rx_enable, + + /* + * Status + */ + output wire start_packet, + output wire error_bad_frame, + output wire error_bad_fcs +); + +// bus width assertions +initial begin + if (DATA_WIDTH != 8) begin + $error("Error: Interface width must be 8"); + $finish; + end +end + +localparam [7:0] + ETH_PRE = 8'h55, + ETH_SFD = 8'hD5; + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PAYLOAD = 3'd1, + STATE_WAIT_LAST = 3'd2; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg mii_odd = 1'b0; +reg in_frame = 1'b0; + +reg [DATA_WIDTH-1:0] gmii_rxd_d0 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] gmii_rxd_d1 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] gmii_rxd_d2 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] gmii_rxd_d3 = {DATA_WIDTH{1'b0}}; +reg [DATA_WIDTH-1:0] gmii_rxd_d4 = {DATA_WIDTH{1'b0}}; + +reg gmii_rx_dv_d0 = 1'b0; +reg gmii_rx_dv_d1 = 1'b0; +reg gmii_rx_dv_d2 = 1'b0; +reg gmii_rx_dv_d3 = 1'b0; +reg gmii_rx_dv_d4 = 1'b0; + +reg gmii_rx_er_d0 = 1'b0; +reg gmii_rx_er_d1 = 1'b0; +reg gmii_rx_er_d2 = 1'b0; +reg gmii_rx_er_d3 = 1'b0; +reg gmii_rx_er_d4 = 1'b0; + +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; +reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; + +reg start_packet_int_reg = 1'b0; +reg start_packet_reg = 1'b0; +reg error_bad_frame_reg = 1'b0, error_bad_frame_next; +reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; + +reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0; + +reg [31:0] crc_state = 32'hFFFFFFFF; +wire [31:0] crc_next; + +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg; + +assign start_packet = start_packet_reg; +assign error_bad_frame = error_bad_frame_reg; +assign error_bad_fcs = error_bad_fcs_reg; + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(8), + .STYLE("AUTO") +) +eth_crc_8 ( + .data_in(gmii_rxd_d4), + .state_in(crc_state), + .data_out(), + .state_out(crc_next) +); + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 1'b0; + update_crc = 1'b0; + + m_axis_tdata_next = {DATA_WIDTH{1'b0}}; + m_axis_tvalid_next = 1'b0; + m_axis_tlast_next = 1'b0; + m_axis_tuser_next = 1'b0; + + error_bad_frame_next = 1'b0; + error_bad_fcs_next = 1'b0; + + if (!clk_enable) begin + // clock disabled - hold state + state_next = state_reg; + end else if (mii_select && !mii_odd) begin + // MII even cycle - hold state + state_next = state_reg; + end else begin + case (state_reg) + STATE_IDLE: begin + // idle state - wait for packet + reset_crc = 1'b1; + + if (gmii_rx_dv_d4 && !gmii_rx_er_d4 && gmii_rxd_d4 == ETH_SFD && cfg_rx_enable) begin + state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_IDLE; + end + end + STATE_PAYLOAD: begin + // read payload + update_crc = 1'b1; + + m_axis_tdata_next = gmii_rxd_d4; + m_axis_tvalid_next = 1'b1; + + if (gmii_rx_dv_d4 && gmii_rx_er_d4) begin + // error + m_axis_tlast_next = 1'b1; + m_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + state_next = STATE_WAIT_LAST; + end else if (!gmii_rx_dv) begin + // end of packet + m_axis_tlast_next = 1'b1; + if (gmii_rx_er_d0 || gmii_rx_er_d1 || gmii_rx_er_d2 || gmii_rx_er_d3) begin + // error received in FCS bytes + m_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + end else if ({gmii_rxd_d0, gmii_rxd_d1, gmii_rxd_d2, gmii_rxd_d3} == ~crc_next) begin + // FCS good + m_axis_tuser_next = 1'b0; + end else begin + // FCS bad + m_axis_tuser_next = 1'b1; + error_bad_frame_next = 1'b1; + error_bad_fcs_next = 1'b1; + end + state_next = STATE_IDLE; + end else begin + state_next = STATE_PAYLOAD; + end + end + STATE_WAIT_LAST: begin + // wait for end of packet + + if (~gmii_rx_dv) begin + state_next = STATE_IDLE; + end else begin + state_next = STATE_WAIT_LAST; + end + end + endcase + end +end + +always @(posedge clk) begin + state_reg <= state_next; + + m_axis_tdata_reg <= m_axis_tdata_next; + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tlast_reg <= m_axis_tlast_next; + m_axis_tuser_reg <= m_axis_tuser_next; + + start_packet_int_reg <= 1'b0; + start_packet_reg <= 1'b0; + + if (start_packet_int_reg) begin + ptp_ts_reg <= ptp_ts; + start_packet_reg <= 1'b1; + end + + if (clk_enable) begin + if (mii_select) begin + mii_odd <= !mii_odd; + + if (in_frame) begin + in_frame <= gmii_rx_dv; + end else if (gmii_rx_dv && {gmii_rxd[3:0], gmii_rxd_d0[7:4]} == ETH_SFD) begin + in_frame <= 1'b1; + start_packet_int_reg <= 1'b1; + mii_odd <= 1'b1; + end + + gmii_rxd_d0 <= {gmii_rxd[3:0], gmii_rxd_d0[7:4]}; + + if (mii_odd) begin + gmii_rxd_d1 <= gmii_rxd_d0; + gmii_rxd_d2 <= gmii_rxd_d1; + gmii_rxd_d3 <= gmii_rxd_d2; + gmii_rxd_d4 <= gmii_rxd_d3; + + gmii_rx_dv_d0 <= gmii_rx_dv & gmii_rx_dv_d0; + gmii_rx_dv_d1 <= gmii_rx_dv_d0 & gmii_rx_dv; + gmii_rx_dv_d2 <= gmii_rx_dv_d1 & gmii_rx_dv; + gmii_rx_dv_d3 <= gmii_rx_dv_d2 & gmii_rx_dv; + gmii_rx_dv_d4 <= gmii_rx_dv_d3 & gmii_rx_dv; + + gmii_rx_er_d0 <= gmii_rx_er | gmii_rx_er_d0; + gmii_rx_er_d1 <= gmii_rx_er_d0; + gmii_rx_er_d2 <= gmii_rx_er_d1; + gmii_rx_er_d3 <= gmii_rx_er_d2; + gmii_rx_er_d4 <= gmii_rx_er_d3; + end else begin + gmii_rx_dv_d0 <= gmii_rx_dv; + gmii_rx_er_d0 <= gmii_rx_er; + end + end else begin + if (in_frame) begin + in_frame <= gmii_rx_dv; + end else if (gmii_rx_dv && gmii_rxd == ETH_SFD) begin + in_frame <= 1'b1; + start_packet_int_reg <= 1'b1; + end + + gmii_rxd_d0 <= gmii_rxd; + gmii_rxd_d1 <= gmii_rxd_d0; + gmii_rxd_d2 <= gmii_rxd_d1; + gmii_rxd_d3 <= gmii_rxd_d2; + gmii_rxd_d4 <= gmii_rxd_d3; + + gmii_rx_dv_d0 <= gmii_rx_dv; + gmii_rx_dv_d1 <= gmii_rx_dv_d0 & gmii_rx_dv; + gmii_rx_dv_d2 <= gmii_rx_dv_d1 & gmii_rx_dv; + gmii_rx_dv_d3 <= gmii_rx_dv_d2 & gmii_rx_dv; + gmii_rx_dv_d4 <= gmii_rx_dv_d3 & gmii_rx_dv; + + gmii_rx_er_d0 <= gmii_rx_er; + gmii_rx_er_d1 <= gmii_rx_er_d0; + gmii_rx_er_d2 <= gmii_rx_er_d1; + gmii_rx_er_d3 <= gmii_rx_er_d2; + gmii_rx_er_d4 <= gmii_rx_er_d3; + end + end + + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next; + end + + error_bad_frame_reg <= error_bad_frame_next; + error_bad_fcs_reg <= error_bad_fcs_next; + + if (rst) begin + state_reg <= STATE_IDLE; + + m_axis_tvalid_reg <= 1'b0; + + start_packet_int_reg <= 1'b0; + start_packet_reg <= 1'b0; + error_bad_frame_reg <= 1'b0; + error_bad_fcs_reg <= 1'b0; + + in_frame <= 1'b0; + mii_odd <= 1'b0; + + gmii_rx_dv_d0 <= 1'b0; + gmii_rx_dv_d1 <= 1'b0; + gmii_rx_dv_d2 <= 1'b0; + gmii_rx_dv_d3 <= 1'b0; + gmii_rx_dv_d4 <= 1'b0; + end +end + +endmodule + +`resetall diff --git a/src/rvvi/axis_gmii_tx.sv b/src/rvvi/axis_gmii_tx.sv new file mode 100644 index 000000000..f2936039f --- /dev/null +++ b/src/rvvi/axis_gmii_tx.sv @@ -0,0 +1,457 @@ +/* + +Copyright (c) 2015-2018 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * AXI4-Stream GMII frame transmitter (AXI in, GMII out) + */ +module axis_gmii_tx # +( + parameter DATA_WIDTH = 8, + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_WIDTH = 96, + parameter PTP_TS_CTRL_IN_TUSER = 0, + parameter PTP_TAG_ENABLE = PTP_TS_ENABLE, + parameter PTP_TAG_WIDTH = 16, + parameter USER_WIDTH = (PTP_TS_ENABLE ? (PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + (PTP_TS_CTRL_IN_TUSER ? 1 : 0) : 0) + 1 +) +( + input wire clk, + input wire rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [USER_WIDTH-1:0] s_axis_tuser, + + /* + * GMII output + */ + output wire [DATA_WIDTH-1:0] gmii_txd, + output wire gmii_tx_en, + output wire gmii_tx_er, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] ptp_ts, + output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts, + output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag, + output wire m_axis_ptp_ts_valid, + + /* + * Control + */ + input wire clk_enable, + input wire mii_select, + + /* + * Configuration + */ + input wire [7:0] cfg_ifg, + input wire cfg_tx_enable, + + /* + * Status + */ + output wire start_packet, + output wire error_underflow +); + +parameter MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-1+1); + +// bus width assertions +initial begin + if (DATA_WIDTH != 8) begin + $error("Error: Interface width must be 8"); + $finish; + end +end + +localparam [7:0] + ETH_PRE = 8'h55, + ETH_SFD = 8'hD5; + +localparam [2:0] + STATE_IDLE = 3'd0, + STATE_PREAMBLE = 3'd1, + STATE_PAYLOAD = 3'd2, + STATE_LAST = 3'd3, + STATE_PAD = 3'd4, + STATE_FCS = 3'd5, + STATE_IFG = 3'd6; + +reg [2:0] state_reg = STATE_IDLE, state_next; + +// datapath control signals +reg reset_crc; +reg update_crc; + +reg [7:0] s_tdata_reg = 8'd0, s_tdata_next; + +reg mii_odd_reg = 1'b0, mii_odd_next; +reg [3:0] mii_msn_reg = 4'b0, mii_msn_next; + +reg frame_reg = 1'b0, frame_next; +reg frame_error_reg = 1'b0, frame_error_next; +reg [7:0] frame_ptr_reg = 0, frame_ptr_next; +reg [MIN_LEN_WIDTH-1:0] frame_min_count_reg = 0, frame_min_count_next; + +reg [7:0] gmii_txd_reg = 8'd0, gmii_txd_next; +reg gmii_tx_en_reg = 1'b0, gmii_tx_en_next; +reg gmii_tx_er_reg = 1'b0, gmii_tx_er_next; + +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; + +reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next; +reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next; +reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next; + +reg start_packet_int_reg = 1'b0, start_packet_int_next; +reg start_packet_reg = 1'b0, start_packet_next; +reg error_underflow_reg = 1'b0, error_underflow_next; + +reg [31:0] crc_state = 32'hFFFFFFFF; +wire [31:0] crc_next; + +assign s_axis_tready = s_axis_tready_reg; + +assign gmii_txd = gmii_txd_reg; +assign gmii_tx_en = gmii_tx_en_reg; +assign gmii_tx_er = gmii_tx_er_reg; + +assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; +assign m_axis_ptp_ts_tag = PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; +assign m_axis_ptp_ts_valid = PTP_TS_ENABLE || PTP_TAG_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; + +assign start_packet = start_packet_reg; +assign error_underflow = error_underflow_reg; + +lfsr #( + .LFSR_WIDTH(32), + .LFSR_POLY(32'h4c11db7), + .LFSR_CONFIG("GALOIS"), + .LFSR_FEED_FORWARD(0), + .REVERSE(1), + .DATA_WIDTH(8), + .STYLE("AUTO") +) +eth_crc_8 ( + .data_in(s_tdata_reg), + .state_in(crc_state), + .data_out(), + .state_out(crc_next) +); + +always @* begin + state_next = STATE_IDLE; + + reset_crc = 1'b0; + update_crc = 1'b0; + + mii_odd_next = mii_odd_reg; + mii_msn_next = mii_msn_reg; + + frame_next = frame_reg; + frame_error_next = frame_error_reg; + frame_ptr_next = frame_ptr_reg; + frame_min_count_next = frame_min_count_reg; + + s_axis_tready_next = 1'b0; + + s_tdata_next = s_tdata_reg; + + m_axis_ptp_ts_next = m_axis_ptp_ts_reg; + m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg; + m_axis_ptp_ts_valid_next = 1'b0; + + if (start_packet_reg && PTP_TS_ENABLE) begin + m_axis_ptp_ts_next = ptp_ts; + if (PTP_TS_CTRL_IN_TUSER) begin + m_axis_ptp_ts_tag_next = s_axis_tuser >> 2; + m_axis_ptp_ts_valid_next = s_axis_tuser[1]; + end else begin + m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; + m_axis_ptp_ts_valid_next = 1'b1; + end + end + + gmii_txd_next = {DATA_WIDTH{1'b0}}; + gmii_tx_en_next = 1'b0; + gmii_tx_er_next = 1'b0; + + start_packet_int_next = start_packet_int_reg; + start_packet_next = 1'b0; + error_underflow_next = 1'b0; + + if (s_axis_tvalid && s_axis_tready) begin + frame_next = !s_axis_tlast; + end + + if (!clk_enable) begin + // clock disabled - hold state and outputs + gmii_txd_next = gmii_txd_reg; + gmii_tx_en_next = gmii_tx_en_reg; + gmii_tx_er_next = gmii_tx_er_reg; + state_next = state_reg; + end else if (mii_select && mii_odd_reg) begin + // MII odd cycle - hold state, output MSN + mii_odd_next = 1'b0; + gmii_txd_next = {4'd0, mii_msn_reg}; + gmii_tx_en_next = gmii_tx_en_reg; + gmii_tx_er_next = gmii_tx_er_reg; + state_next = state_reg; + if (start_packet_int_reg) begin + start_packet_int_next = 1'b0; + start_packet_next = 1'b1; + end + end else begin + case (state_reg) + STATE_IDLE: begin + // idle state - wait for packet + reset_crc = 1'b1; + + mii_odd_next = 1'b0; + frame_ptr_next = 1; + + frame_error_next = 1'b0; + frame_min_count_next = MIN_FRAME_LENGTH-4-1; + + if (s_axis_tvalid && cfg_tx_enable) begin + mii_odd_next = 1'b1; + gmii_txd_next = ETH_PRE; + gmii_tx_en_next = 1'b1; + state_next = STATE_PREAMBLE; + end else begin + state_next = STATE_IDLE; + end + end + STATE_PREAMBLE: begin + // send preamble + reset_crc = 1'b1; + + mii_odd_next = 1'b1; + frame_ptr_next = frame_ptr_reg + 1; + + gmii_txd_next = ETH_PRE; + gmii_tx_en_next = 1'b1; + + if (frame_ptr_reg == 6) begin + s_axis_tready_next = 1'b1; + s_tdata_next = s_axis_tdata; + state_next = STATE_PREAMBLE; + end else if (frame_ptr_reg == 7) begin + // end of preamble; start payload + frame_ptr_next = 0; + if (s_axis_tready_reg) begin + s_axis_tready_next = 1'b1; + s_tdata_next = s_axis_tdata; + end + gmii_txd_next = ETH_SFD; + if (mii_select) begin + start_packet_int_next = 1'b1; + end else begin + start_packet_next = 1'b1; + end + state_next = STATE_PAYLOAD; + end else begin + state_next = STATE_PREAMBLE; + end + end + STATE_PAYLOAD: begin + // send payload + + update_crc = 1'b1; + s_axis_tready_next = 1'b1; + + mii_odd_next = 1'b1; + + if (frame_min_count_reg) begin + frame_min_count_next = frame_min_count_reg - 1; + end + + gmii_txd_next = s_tdata_reg; + gmii_tx_en_next = 1'b1; + + s_tdata_next = s_axis_tdata; + + if (!s_axis_tvalid || s_axis_tlast) begin + s_axis_tready_next = frame_next; // drop frame + frame_error_next = !s_axis_tvalid || s_axis_tuser[0]; + error_underflow_next = !s_axis_tvalid; + + state_next = STATE_LAST; + end else begin + state_next = STATE_PAYLOAD; + end + end + STATE_LAST: begin + // last payload word + + update_crc = 1'b1; + s_axis_tready_next = 1'b0; + + mii_odd_next = 1'b1; + + gmii_txd_next = s_tdata_reg; + gmii_tx_en_next = 1'b1; + + if (ENABLE_PADDING && frame_min_count_reg) begin + frame_min_count_next = frame_min_count_reg - 1; + s_tdata_next = 8'd0; + state_next = STATE_PAD; + end else begin + frame_ptr_next = 0; + state_next = STATE_FCS; + end + end + STATE_PAD: begin + // send padding + s_axis_tready_next = frame_next; // drop frame + + update_crc = 1'b1; + mii_odd_next = 1'b1; + + gmii_txd_next = 8'd0; + gmii_tx_en_next = 1'b1; + + s_tdata_next = 8'd0; + + if (frame_min_count_reg) begin + frame_min_count_next = frame_min_count_reg - 1; + state_next = STATE_PAD; + end else begin + frame_ptr_next = 0; + state_next = STATE_FCS; + end + end + STATE_FCS: begin + // send FCS + s_axis_tready_next = frame_next; // drop frame + + mii_odd_next = 1'b1; + frame_ptr_next = frame_ptr_reg + 1; + + case (frame_ptr_reg) + 2'd0: gmii_txd_next = ~crc_state[7:0]; + 2'd1: gmii_txd_next = ~crc_state[15:8]; + 2'd2: gmii_txd_next = ~crc_state[23:16]; + 2'd3: gmii_txd_next = ~crc_state[31:24]; + endcase + gmii_tx_en_next = 1'b1; + gmii_tx_er_next = frame_error_reg; + + if (frame_ptr_reg < 3) begin + state_next = STATE_FCS; + end else begin + frame_ptr_next = 0; + state_next = STATE_IFG; + end + end + STATE_IFG: begin + // send IFG + s_axis_tready_next = frame_next; // drop frame + + mii_odd_next = 1'b1; + frame_ptr_next = frame_ptr_reg + 1; + + if (frame_ptr_reg < cfg_ifg-1 || frame_reg) begin + state_next = STATE_IFG; + end else begin + state_next = STATE_IDLE; + end + end + endcase + + if (mii_select) begin + mii_msn_next = gmii_txd_next[7:4]; + gmii_txd_next[7:4] = 4'd0; + end + end +end + +always @(posedge clk) begin + state_reg <= state_next; + + frame_reg <= frame_next; + frame_error_reg <= frame_error_next; + frame_ptr_reg <= frame_ptr_next; + frame_min_count_reg <= frame_min_count_next; + + m_axis_ptp_ts_reg <= m_axis_ptp_ts_next; + m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next; + m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next; + + mii_odd_reg <= mii_odd_next; + mii_msn_reg <= mii_msn_next; + + s_tdata_reg <= s_tdata_next; + + s_axis_tready_reg <= s_axis_tready_next; + + gmii_txd_reg <= gmii_txd_next; + gmii_tx_en_reg <= gmii_tx_en_next; + gmii_tx_er_reg <= gmii_tx_er_next; + + if (reset_crc) begin + crc_state <= 32'hFFFFFFFF; + end else if (update_crc) begin + crc_state <= crc_next; + end + + start_packet_int_reg <= start_packet_int_next; + start_packet_reg <= start_packet_next; + error_underflow_reg <= error_underflow_next; + + if (rst) begin + state_reg <= STATE_IDLE; + + frame_reg <= 1'b0; + + s_axis_tready_reg <= 1'b0; + + m_axis_ptp_ts_valid_reg <= 1'b0; + + gmii_tx_en_reg <= 1'b0; + gmii_tx_er_reg <= 1'b0; + + start_packet_int_reg <= 1'b0; + start_packet_reg <= 1'b0; + error_underflow_reg <= 1'b0; + end +end + +endmodule + +`resetall diff --git a/src/rvvi/eth_axis_tx.sv b/src/rvvi/eth_axis_tx.sv new file mode 100644 index 000000000..b4287b281 --- /dev/null +++ b/src/rvvi/eth_axis_tx.sv @@ -0,0 +1,408 @@ +/* + +Copyright (c) 2014-2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * AXI4-Stream ethernet frame transmitter (Ethernet frame in, AXI out) + */ +module eth_axis_tx # +( + // Width of AXI stream interfaces in bits + parameter DATA_WIDTH = 8, + // Propagate tkeep signal + // If disabled, tkeep assumed to be 1'b1 + parameter KEEP_ENABLE = (DATA_WIDTH>8), + // tkeep signal width (words per cycle) + parameter KEEP_WIDTH = (DATA_WIDTH/8) +) +( + input wire clk, + input wire rst, + + /* + * Ethernet frame input + */ + input wire s_eth_hdr_valid, + output wire s_eth_hdr_ready, + input wire [47:0] s_eth_dest_mac, + input wire [47:0] s_eth_src_mac, + input wire [15:0] s_eth_type, + input wire [DATA_WIDTH-1:0] s_eth_payload_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep, + input wire s_eth_payload_axis_tvalid, + output wire s_eth_payload_axis_tready, + input wire s_eth_payload_axis_tlast, + input wire s_eth_payload_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire m_axis_tuser, + + /* + * Status signals + */ + output wire busy +); + +parameter BYTE_LANES = KEEP_ENABLE ? KEEP_WIDTH : 1; + +parameter HDR_SIZE = 14; + +parameter CYCLE_COUNT = (HDR_SIZE+BYTE_LANES-1)/BYTE_LANES; + +parameter PTR_WIDTH = $clog2(CYCLE_COUNT); + +parameter OFFSET = HDR_SIZE % BYTE_LANES; + +// bus width assertions +initial begin + if (BYTE_LANES * 8 != DATA_WIDTH) begin + $error("Error: AXI stream interface requires byte (8-bit) granularity (instance %m)"); + $finish; + end +end + +/* + +Ethernet frame + + Field Length + Destination MAC address 6 octets + Source MAC address 6 octets + Ethertype 2 octets + +This module receives an Ethernet frame with header fields in parallel along +with the payload in an AXI stream, combines the header with the payload, and +transmits the complete Ethernet frame on the output AXI stream interface. + +*/ + +// datapath control signals +reg store_eth_hdr; + +reg send_eth_header_reg = 1'b0, send_eth_header_next; +reg send_eth_payload_reg = 1'b0, send_eth_payload_next; +reg [PTR_WIDTH-1:0] ptr_reg = 0, ptr_next; + +reg flush_save; +reg transfer_in_save; + +reg [47:0] eth_dest_mac_reg = 48'd0; +reg [47:0] eth_src_mac_reg = 48'd0; +reg [15:0] eth_type_reg = 16'd0; + +reg s_eth_hdr_ready_reg = 1'b0, s_eth_hdr_ready_next; +reg s_eth_payload_axis_tready_reg = 1'b0, s_eth_payload_axis_tready_next; + +reg busy_reg = 1'b0; + +reg [DATA_WIDTH-1:0] save_eth_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] save_eth_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg save_eth_payload_axis_tlast_reg = 1'b0; +reg save_eth_payload_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] shift_eth_payload_axis_tdata; +reg [KEEP_WIDTH-1:0] shift_eth_payload_axis_tkeep; +reg shift_eth_payload_axis_tvalid; +reg shift_eth_payload_axis_tlast; +reg shift_eth_payload_axis_tuser; +reg shift_eth_payload_axis_input_tready; +reg shift_eth_payload_axis_extra_cycle_reg = 1'b0; + +// internal datapath +reg [DATA_WIDTH-1:0] m_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg m_axis_tuser_int; +wire m_axis_tready_int_early; + +assign s_eth_hdr_ready = s_eth_hdr_ready_reg; +assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg; + +assign busy = busy_reg; + +always @* begin + if (OFFSET == 0) begin + // passthrough if no overlap + shift_eth_payload_axis_tdata = s_eth_payload_axis_tdata; + shift_eth_payload_axis_tkeep = s_eth_payload_axis_tkeep; + shift_eth_payload_axis_tvalid = s_eth_payload_axis_tvalid; + shift_eth_payload_axis_tlast = s_eth_payload_axis_tlast; + shift_eth_payload_axis_tuser = s_eth_payload_axis_tuser; + shift_eth_payload_axis_input_tready = 1'b1; + end else if (shift_eth_payload_axis_extra_cycle_reg) begin + shift_eth_payload_axis_tdata = {s_eth_payload_axis_tdata, save_eth_payload_axis_tdata_reg} >> ((KEEP_WIDTH-OFFSET)*8); + shift_eth_payload_axis_tkeep = {{KEEP_WIDTH{1'b0}}, save_eth_payload_axis_tkeep_reg} >> (KEEP_WIDTH-OFFSET); + shift_eth_payload_axis_tvalid = 1'b1; + shift_eth_payload_axis_tlast = save_eth_payload_axis_tlast_reg; + shift_eth_payload_axis_tuser = save_eth_payload_axis_tuser_reg; + shift_eth_payload_axis_input_tready = flush_save; + end else begin + shift_eth_payload_axis_tdata = {s_eth_payload_axis_tdata, save_eth_payload_axis_tdata_reg} >> ((KEEP_WIDTH-OFFSET)*8); + shift_eth_payload_axis_tkeep = {s_eth_payload_axis_tkeep, save_eth_payload_axis_tkeep_reg} >> (KEEP_WIDTH-OFFSET); + shift_eth_payload_axis_tvalid = s_eth_payload_axis_tvalid; + shift_eth_payload_axis_tlast = (s_eth_payload_axis_tlast && ((s_eth_payload_axis_tkeep & ({KEEP_WIDTH{1'b1}} << (KEEP_WIDTH-OFFSET))) == 0)); + shift_eth_payload_axis_tuser = (s_eth_payload_axis_tuser && ((s_eth_payload_axis_tkeep & ({KEEP_WIDTH{1'b1}} << (KEEP_WIDTH-OFFSET))) == 0)); + shift_eth_payload_axis_input_tready = !(s_eth_payload_axis_tlast && s_eth_payload_axis_tready && s_eth_payload_axis_tvalid); + end +end + +always @* begin + send_eth_header_next = send_eth_header_reg; + send_eth_payload_next = send_eth_payload_reg; + ptr_next = ptr_reg; + + s_eth_hdr_ready_next = 1'b0; + s_eth_payload_axis_tready_next = 1'b0; + + store_eth_hdr = 1'b0; + + flush_save = 1'b0; + transfer_in_save = 1'b0; + + m_axis_tdata_int = {DATA_WIDTH{1'b0}}; + m_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tuser_int = 1'b0; + + if (s_eth_hdr_ready && s_eth_hdr_valid) begin + store_eth_hdr = 1'b1; + ptr_next = 0; + send_eth_header_next = 1'b1; + send_eth_payload_next = (OFFSET != 0) && (CYCLE_COUNT == 1); + s_eth_payload_axis_tready_next = send_eth_payload_next && m_axis_tready_int_early; + end + + if (send_eth_payload_reg) begin + s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_axis_input_tready; + + m_axis_tdata_int = shift_eth_payload_axis_tdata; + m_axis_tkeep_int = shift_eth_payload_axis_tkeep; + m_axis_tlast_int = shift_eth_payload_axis_tlast; + m_axis_tuser_int = shift_eth_payload_axis_tuser; + + if ((s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) || (m_axis_tready_int_reg && shift_eth_payload_axis_extra_cycle_reg)) begin + transfer_in_save = 1'b1; + + m_axis_tvalid_int = 1'b1; + + if (shift_eth_payload_axis_tlast) begin + flush_save = 1'b1; + s_eth_payload_axis_tready_next = 1'b0; + ptr_next = 0; + send_eth_payload_next = 1'b0; + end + end + end + + if (m_axis_tready_int_reg && (!OFFSET || !send_eth_payload_reg || m_axis_tvalid_int)) begin + if (send_eth_header_reg) begin + ptr_next = ptr_reg + 1; + + if ((OFFSET != 0) && (CYCLE_COUNT == 1 || ptr_next == CYCLE_COUNT-1) && !send_eth_payload_reg) begin + send_eth_payload_next = 1'b1; + s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_axis_input_tready; + end + + m_axis_tvalid_int = 1'b1; + + `define _HEADER_FIELD_(offset, field) \ + if (ptr_reg == offset/BYTE_LANES) begin \ + m_axis_tdata_int[(offset%BYTE_LANES)*8 +: 8] = field; \ + m_axis_tkeep_int[offset%BYTE_LANES] = 1'b1; \ + end + + `_HEADER_FIELD_(0, eth_dest_mac_reg[5*8 +: 8]) + `_HEADER_FIELD_(1, eth_dest_mac_reg[4*8 +: 8]) + `_HEADER_FIELD_(2, eth_dest_mac_reg[3*8 +: 8]) + `_HEADER_FIELD_(3, eth_dest_mac_reg[2*8 +: 8]) + `_HEADER_FIELD_(4, eth_dest_mac_reg[1*8 +: 8]) + `_HEADER_FIELD_(5, eth_dest_mac_reg[0*8 +: 8]) + `_HEADER_FIELD_(6, eth_src_mac_reg[5*8 +: 8]) + `_HEADER_FIELD_(7, eth_src_mac_reg[4*8 +: 8]) + `_HEADER_FIELD_(8, eth_src_mac_reg[3*8 +: 8]) + `_HEADER_FIELD_(9, eth_src_mac_reg[2*8 +: 8]) + `_HEADER_FIELD_(10, eth_src_mac_reg[1*8 +: 8]) + `_HEADER_FIELD_(11, eth_src_mac_reg[0*8 +: 8]) + `_HEADER_FIELD_(12, eth_type_reg[1*8 +: 8]) + `_HEADER_FIELD_(13, eth_type_reg[0*8 +: 8]) + + if (ptr_reg == 13/BYTE_LANES) begin + if (!send_eth_payload_reg) begin + s_eth_payload_axis_tready_next = m_axis_tready_int_early; + send_eth_payload_next = 1'b1; + end + send_eth_header_next = 1'b0; + end + + `undef _HEADER_FIELD_ + end + end + + s_eth_hdr_ready_next = !(send_eth_header_next || send_eth_payload_next); +end + +always @(posedge clk) begin + send_eth_header_reg <= send_eth_header_next; + send_eth_payload_reg <= send_eth_payload_next; + ptr_reg <= ptr_next; + + s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; + s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; + + busy_reg <= send_eth_header_next || send_eth_payload_next; + + if (store_eth_hdr) begin + eth_dest_mac_reg <= s_eth_dest_mac; + eth_src_mac_reg <= s_eth_src_mac; + eth_type_reg <= s_eth_type; + end + + if (transfer_in_save) begin + save_eth_payload_axis_tdata_reg <= s_eth_payload_axis_tdata; + save_eth_payload_axis_tkeep_reg <= s_eth_payload_axis_tkeep; + save_eth_payload_axis_tuser_reg <= s_eth_payload_axis_tuser; + end + + if (flush_save) begin + save_eth_payload_axis_tlast_reg <= 1'b0; + shift_eth_payload_axis_extra_cycle_reg <= 1'b0; + end else if (transfer_in_save) begin + save_eth_payload_axis_tlast_reg <= s_eth_payload_axis_tlast; + shift_eth_payload_axis_extra_cycle_reg <= OFFSET ? s_eth_payload_axis_tlast && ((s_eth_payload_axis_tkeep & ({KEEP_WIDTH{1'b1}} << (KEEP_WIDTH-OFFSET))) != 0) : 1'b0; + end + + if (rst) begin + send_eth_header_reg <= 1'b0; + send_eth_payload_reg <= 1'b0; + ptr_reg <= 0; + s_eth_hdr_ready_reg <= 1'b0; + s_eth_payload_axis_tready_reg <= 1'b0; + busy_reg <= 1'b0; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg m_axis_tuser_reg = 1'b0; + +reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg temp_m_axis_tuser_reg = 1'b0; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tuser = m_axis_tuser_reg; + +// enable ready input next cycle if output is ready or if both output registers are empty +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg); + +always @* begin + // transfer sink ready state to source + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (m_axis_tready_int_reg) begin + // input is ready + if (m_axis_tready || !m_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_axis_tready) begin + // input is not ready, but output is ready + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; + + // datapath + if (store_axis_int_to_output) begin + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tuser_reg <= m_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; + end + + if (rst) begin + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; + end +end + +endmodule + +`resetall diff --git a/src/rvvi/eth_mac_1g.sv b/src/rvvi/eth_mac_1g.sv new file mode 100644 index 000000000..6e0592fac --- /dev/null +++ b/src/rvvi/eth_mac_1g.sv @@ -0,0 +1,643 @@ +/* + +Copyright (c) 2015-2023 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * 1G Ethernet MAC + */ +module eth_mac_1g # +( + parameter DATA_WIDTH = 8, + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64, + parameter PTP_TS_ENABLE = 0, + parameter PTP_TS_FMT_TOD = 1, + parameter PTP_TS_WIDTH = PTP_TS_FMT_TOD ? 96 : 64, + parameter TX_PTP_TS_CTRL_IN_TUSER = 0, + parameter TX_PTP_TAG_ENABLE = PTP_TS_ENABLE, + parameter TX_PTP_TAG_WIDTH = 16, + parameter TX_USER_WIDTH = (PTP_TS_ENABLE ? (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + (TX_PTP_TS_CTRL_IN_TUSER ? 1 : 0) : 0) + 1, + parameter RX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1, + parameter PFC_ENABLE = 0, + parameter PAUSE_ENABLE = PFC_ENABLE +) +( + input wire rx_clk, + input wire rx_rst, + input wire tx_clk, + input wire tx_rst, + + /* + * AXI input + */ + input wire [DATA_WIDTH-1:0] tx_axis_tdata, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire [TX_USER_WIDTH-1:0] tx_axis_tuser, + + /* + * AXI output + */ + output wire [DATA_WIDTH-1:0] rx_axis_tdata, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire [RX_USER_WIDTH-1:0] rx_axis_tuser, + + /* + * GMII interface + */ + input wire [DATA_WIDTH-1:0] gmii_rxd, + input wire gmii_rx_dv, + input wire gmii_rx_er, + output wire [DATA_WIDTH-1:0] gmii_txd, + output wire gmii_tx_en, + output wire gmii_tx_er, + + /* + * PTP + */ + input wire [PTP_TS_WIDTH-1:0] tx_ptp_ts, + input wire [PTP_TS_WIDTH-1:0] rx_ptp_ts, + output wire [PTP_TS_WIDTH-1:0] tx_axis_ptp_ts, + output wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag, + output wire tx_axis_ptp_ts_valid, + + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + input wire tx_lfc_req, + input wire tx_lfc_resend, + input wire rx_lfc_en, + output wire rx_lfc_req, + input wire rx_lfc_ack, + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + input wire [7:0] tx_pfc_req, + input wire tx_pfc_resend, + input wire [7:0] rx_pfc_en, + output wire [7:0] rx_pfc_req, + input wire [7:0] rx_pfc_ack, + + /* + * Pause interface + */ + input wire tx_lfc_pause_en, + input wire tx_pause_req, + output wire tx_pause_ack, + + /* + * Control + */ + input wire rx_clk_enable, + input wire tx_clk_enable, + input wire rx_mii_select, + input wire tx_mii_select, + + /* + * Status + */ + output wire tx_start_packet, + output wire tx_error_underflow, + output wire rx_start_packet, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire stat_tx_mcf, + output wire stat_rx_mcf, + output wire stat_tx_lfc_pkt, + output wire stat_tx_lfc_xon, + output wire stat_tx_lfc_xoff, + output wire stat_tx_lfc_paused, + output wire stat_tx_pfc_pkt, + output wire [7:0] stat_tx_pfc_xon, + output wire [7:0] stat_tx_pfc_xoff, + output wire [7:0] stat_tx_pfc_paused, + output wire stat_rx_lfc_pkt, + output wire stat_rx_lfc_xon, + output wire stat_rx_lfc_xoff, + output wire stat_rx_lfc_paused, + output wire stat_rx_pfc_pkt, + output wire [7:0] stat_rx_pfc_xon, + output wire [7:0] stat_rx_pfc_xoff, + output wire [7:0] stat_rx_pfc_paused, + + /* + * Configuration + */ + input wire [7:0] cfg_ifg, + input wire cfg_tx_enable, + input wire cfg_rx_enable, + input wire [47:0] cfg_mcf_rx_eth_dst_mcast, + input wire cfg_mcf_rx_check_eth_dst_mcast, + input wire [47:0] cfg_mcf_rx_eth_dst_ucast, + input wire cfg_mcf_rx_check_eth_dst_ucast, + input wire [47:0] cfg_mcf_rx_eth_src, + input wire cfg_mcf_rx_check_eth_src, + input wire [15:0] cfg_mcf_rx_eth_type, + input wire [15:0] cfg_mcf_rx_opcode_lfc, + input wire cfg_mcf_rx_check_opcode_lfc, + input wire [15:0] cfg_mcf_rx_opcode_pfc, + input wire cfg_mcf_rx_check_opcode_pfc, + input wire cfg_mcf_rx_forward, + input wire cfg_mcf_rx_enable, + input wire [47:0] cfg_tx_lfc_eth_dst, + input wire [47:0] cfg_tx_lfc_eth_src, + input wire [15:0] cfg_tx_lfc_eth_type, + input wire [15:0] cfg_tx_lfc_opcode, + input wire cfg_tx_lfc_en, + input wire [15:0] cfg_tx_lfc_quanta, + input wire [15:0] cfg_tx_lfc_refresh, + input wire [47:0] cfg_tx_pfc_eth_dst, + input wire [47:0] cfg_tx_pfc_eth_src, + input wire [15:0] cfg_tx_pfc_eth_type, + input wire [15:0] cfg_tx_pfc_opcode, + input wire cfg_tx_pfc_en, + input wire [8*16-1:0] cfg_tx_pfc_quanta, + input wire [8*16-1:0] cfg_tx_pfc_refresh, + input wire [15:0] cfg_rx_lfc_opcode, + input wire cfg_rx_lfc_en, + input wire [15:0] cfg_rx_pfc_opcode, + input wire cfg_rx_pfc_en +); + +parameter MAC_CTRL_ENABLE = PAUSE_ENABLE || PFC_ENABLE; +parameter TX_USER_WIDTH_INT = MAC_CTRL_ENABLE ? (PTP_TS_ENABLE ? (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1 : 0) + 1 : TX_USER_WIDTH; + +wire [DATA_WIDTH-1:0] tx_axis_tdata_int; +wire tx_axis_tvalid_int; +wire tx_axis_tready_int; +wire tx_axis_tlast_int; +wire [TX_USER_WIDTH_INT-1:0] tx_axis_tuser_int; + +wire [DATA_WIDTH-1:0] rx_axis_tdata_int; +wire rx_axis_tvalid_int; +wire rx_axis_tlast_int; +wire [RX_USER_WIDTH-1:0] rx_axis_tuser_int; + +axis_gmii_rx #( + .DATA_WIDTH(DATA_WIDTH), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .USER_WIDTH(RX_USER_WIDTH) +) +axis_gmii_rx_inst ( + .clk(rx_clk), + .rst(rx_rst), + .gmii_rxd(gmii_rxd), + .gmii_rx_dv(gmii_rx_dv), + .gmii_rx_er(gmii_rx_er), + .m_axis_tdata(rx_axis_tdata_int), + .m_axis_tvalid(rx_axis_tvalid_int), + .m_axis_tlast(rx_axis_tlast_int), + .m_axis_tuser(rx_axis_tuser_int), + .ptp_ts(rx_ptp_ts), + .clk_enable(rx_clk_enable), + .mii_select(rx_mii_select), + .cfg_rx_enable(cfg_rx_enable), + .start_packet(rx_start_packet), + .error_bad_frame(rx_error_bad_frame), + .error_bad_fcs(rx_error_bad_fcs) +); + +axis_gmii_tx #( + .DATA_WIDTH(DATA_WIDTH), + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), + .PTP_TS_ENABLE(PTP_TS_ENABLE), + .PTP_TS_WIDTH(PTP_TS_WIDTH), + .PTP_TS_CTRL_IN_TUSER(MAC_CTRL_ENABLE ? PTP_TS_ENABLE : TX_PTP_TS_CTRL_IN_TUSER), + .PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), + .PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), + .USER_WIDTH(TX_USER_WIDTH_INT) +) +axis_gmii_tx_inst ( + .clk(tx_clk), + .rst(tx_rst), + .s_axis_tdata(tx_axis_tdata_int), + .s_axis_tvalid(tx_axis_tvalid_int), + .s_axis_tready(tx_axis_tready_int), + .s_axis_tlast(tx_axis_tlast_int), + .s_axis_tuser(tx_axis_tuser_int), + .gmii_txd(gmii_txd), + .gmii_tx_en(gmii_tx_en), + .gmii_tx_er(gmii_tx_er), + .ptp_ts(tx_ptp_ts), + .m_axis_ptp_ts(tx_axis_ptp_ts), + .m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), + .m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), + .clk_enable(tx_clk_enable), + .mii_select(tx_mii_select), + .cfg_ifg(cfg_ifg), + .cfg_tx_enable(cfg_tx_enable), + .start_packet(tx_start_packet), + .error_underflow(tx_error_underflow) +); + +generate + +if (MAC_CTRL_ENABLE) begin : mac_ctrl + + localparam MCF_PARAMS_SIZE = PFC_ENABLE ? 18 : 2; + + wire tx_mcf_valid; + wire tx_mcf_ready; + wire [47:0] tx_mcf_eth_dst; + wire [47:0] tx_mcf_eth_src; + wire [15:0] tx_mcf_eth_type; + wire [15:0] tx_mcf_opcode; + wire [MCF_PARAMS_SIZE*8-1:0] tx_mcf_params; + + wire rx_mcf_valid; + wire [47:0] rx_mcf_eth_dst; + wire [47:0] rx_mcf_eth_src; + wire [15:0] rx_mcf_eth_type; + wire [15:0] rx_mcf_opcode; + wire [MCF_PARAMS_SIZE*8-1:0] rx_mcf_params; + + // terminate LFC pause requests from RX internally on TX side + wire tx_pause_req_int; + wire rx_lfc_ack_int; + + reg tx_lfc_req_sync_reg_1 = 1'b0; + reg tx_lfc_req_sync_reg_2 = 1'b0; + reg tx_lfc_req_sync_reg_3 = 1'b0; + + always @(posedge rx_clk or posedge rx_rst) begin + if (rx_rst) begin + tx_lfc_req_sync_reg_1 <= 1'b0; + end else begin + tx_lfc_req_sync_reg_1 <= rx_lfc_req; + end + end + + always @(posedge tx_clk or posedge tx_rst) begin + if (tx_rst) begin + tx_lfc_req_sync_reg_2 <= 1'b0; + tx_lfc_req_sync_reg_3 <= 1'b0; + end else begin + tx_lfc_req_sync_reg_2 <= tx_lfc_req_sync_reg_1; + tx_lfc_req_sync_reg_3 <= tx_lfc_req_sync_reg_2; + end + end + + reg rx_lfc_ack_sync_reg_1 = 1'b0; + reg rx_lfc_ack_sync_reg_2 = 1'b0; + reg rx_lfc_ack_sync_reg_3 = 1'b0; + + always @(posedge tx_clk or posedge tx_rst) begin + if (tx_rst) begin + rx_lfc_ack_sync_reg_1 <= 1'b0; + end else begin + rx_lfc_ack_sync_reg_1 <= tx_lfc_pause_en ? tx_pause_ack : 0; + end + end + + always @(posedge rx_clk or posedge rx_rst) begin + if (rx_rst) begin + rx_lfc_ack_sync_reg_2 <= 1'b0; + rx_lfc_ack_sync_reg_3 <= 1'b0; + end else begin + rx_lfc_ack_sync_reg_2 <= rx_lfc_ack_sync_reg_1; + rx_lfc_ack_sync_reg_3 <= rx_lfc_ack_sync_reg_2; + end + end + + assign tx_pause_req_int = tx_pause_req || (tx_lfc_pause_en ? tx_lfc_req_sync_reg_3 : 0); + + assign rx_lfc_ack_int = rx_lfc_ack || rx_lfc_ack_sync_reg_3; + + // handle PTP TS enable bit in tuser + wire [TX_USER_WIDTH_INT-1:0] tx_axis_tuser_in; + + if (PTP_TS_ENABLE && !TX_PTP_TS_CTRL_IN_TUSER) begin + assign tx_axis_tuser_in = {tx_axis_tuser[TX_USER_WIDTH-1:1], 1'b1, tx_axis_tuser[0]}; + end else begin + assign tx_axis_tuser_in = tx_axis_tuser; + end + + mac_ctrl_tx #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(TX_USER_WIDTH_INT), + .MCF_PARAMS_SIZE(MCF_PARAMS_SIZE) + ) + mac_ctrl_tx_inst ( + .clk(tx_clk), + .rst(tx_rst), + + /* + * AXI stream input + */ + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(1'b1), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(tx_axis_tuser_in), + + /* + * AXI stream output + */ + .m_axis_tdata(tx_axis_tdata_int), + .m_axis_tkeep(), + .m_axis_tvalid(tx_axis_tvalid_int), + .m_axis_tready(tx_axis_tready_int), + .m_axis_tlast(tx_axis_tlast_int), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_axis_tuser_int), + + /* + * MAC control frame interface + */ + .mcf_valid(tx_mcf_valid), + .mcf_ready(tx_mcf_ready), + .mcf_eth_dst(tx_mcf_eth_dst), + .mcf_eth_src(tx_mcf_eth_src), + .mcf_eth_type(tx_mcf_eth_type), + .mcf_opcode(tx_mcf_opcode), + .mcf_params(tx_mcf_params), + .mcf_id(0), + .mcf_dest(0), + .mcf_user(0), + + /* + * Pause interface + */ + .tx_pause_req(tx_pause_req_int), + .tx_pause_ack(tx_pause_ack), + + /* + * Status + */ + .stat_tx_mcf(stat_tx_mcf) + ); + + mac_ctrl_rx #( + .DATA_WIDTH(DATA_WIDTH), + .KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(RX_USER_WIDTH), + .USE_READY(0), + .MCF_PARAMS_SIZE(MCF_PARAMS_SIZE) + ) + mac_ctrl_rx_inst ( + .clk(rx_clk), + .rst(rx_rst), + + /* + * AXI stream input + */ + .s_axis_tdata(rx_axis_tdata_int), + .s_axis_tkeep(1'b1), + .s_axis_tvalid(rx_axis_tvalid_int), + .s_axis_tready(), + .s_axis_tlast(rx_axis_tlast_int), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_axis_tuser_int), + + /* + * AXI stream output + */ + .m_axis_tdata(rx_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tready(1'b1), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(rx_axis_tuser), + + /* + * MAC control frame interface + */ + .mcf_valid(rx_mcf_valid), + .mcf_eth_dst(rx_mcf_eth_dst), + .mcf_eth_src(rx_mcf_eth_src), + .mcf_eth_type(rx_mcf_eth_type), + .mcf_opcode(rx_mcf_opcode), + .mcf_params(rx_mcf_params), + .mcf_id(), + .mcf_dest(), + .mcf_user(), + + /* + * Configuration + */ + .cfg_mcf_rx_eth_dst_mcast(cfg_mcf_rx_eth_dst_mcast), + .cfg_mcf_rx_check_eth_dst_mcast(cfg_mcf_rx_check_eth_dst_mcast), + .cfg_mcf_rx_eth_dst_ucast(cfg_mcf_rx_eth_dst_ucast), + .cfg_mcf_rx_check_eth_dst_ucast(cfg_mcf_rx_check_eth_dst_ucast), + .cfg_mcf_rx_eth_src(cfg_mcf_rx_eth_src), + .cfg_mcf_rx_check_eth_src(cfg_mcf_rx_check_eth_src), + .cfg_mcf_rx_eth_type(cfg_mcf_rx_eth_type), + .cfg_mcf_rx_opcode_lfc(cfg_mcf_rx_opcode_lfc), + .cfg_mcf_rx_check_opcode_lfc(cfg_mcf_rx_check_opcode_lfc), + .cfg_mcf_rx_opcode_pfc(cfg_mcf_rx_opcode_pfc), + .cfg_mcf_rx_check_opcode_pfc(cfg_mcf_rx_check_opcode_pfc), + .cfg_mcf_rx_forward(cfg_mcf_rx_forward), + .cfg_mcf_rx_enable(cfg_mcf_rx_enable), + + /* + * Status + */ + .stat_rx_mcf(stat_rx_mcf) + ); + + mac_pause_ctrl_tx #( + .MCF_PARAMS_SIZE(MCF_PARAMS_SIZE), + .PFC_ENABLE(PFC_ENABLE) + ) + mac_pause_ctrl_tx_inst ( + .clk(tx_clk), + .rst(tx_rst), + + /* + * MAC control frame interface + */ + .mcf_valid(tx_mcf_valid), + .mcf_ready(tx_mcf_ready), + .mcf_eth_dst(tx_mcf_eth_dst), + .mcf_eth_src(tx_mcf_eth_src), + .mcf_eth_type(tx_mcf_eth_type), + .mcf_opcode(tx_mcf_opcode), + .mcf_params(tx_mcf_params), + + /* + * Pause (IEEE 802.3 annex 31B) + */ + .tx_lfc_req(tx_lfc_req), + .tx_lfc_resend(tx_lfc_resend), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D) + */ + .tx_pfc_req(tx_pfc_req), + .tx_pfc_resend(tx_pfc_resend), + + /* + * Configuration + */ + .cfg_tx_lfc_eth_dst(cfg_tx_lfc_eth_dst), + .cfg_tx_lfc_eth_src(cfg_tx_lfc_eth_src), + .cfg_tx_lfc_eth_type(cfg_tx_lfc_eth_type), + .cfg_tx_lfc_opcode(cfg_tx_lfc_opcode), + .cfg_tx_lfc_en(cfg_tx_lfc_en), + .cfg_tx_lfc_quanta(cfg_tx_lfc_quanta), + .cfg_tx_lfc_refresh(cfg_tx_lfc_refresh), + .cfg_tx_pfc_eth_dst(cfg_tx_pfc_eth_dst), + .cfg_tx_pfc_eth_src(cfg_tx_pfc_eth_src), + .cfg_tx_pfc_eth_type(cfg_tx_pfc_eth_type), + .cfg_tx_pfc_opcode(cfg_tx_pfc_opcode), + .cfg_tx_pfc_en(cfg_tx_pfc_en), + .cfg_tx_pfc_quanta(cfg_tx_pfc_quanta), + .cfg_tx_pfc_refresh(cfg_tx_pfc_refresh), + .cfg_quanta_step(tx_mii_select ? (4*256)/512 : (8*256)/512), + .cfg_quanta_clk_en(tx_clk_enable), + + /* + * Status + */ + .stat_tx_lfc_pkt(stat_tx_lfc_pkt), + .stat_tx_lfc_xon(stat_tx_lfc_xon), + .stat_tx_lfc_xoff(stat_tx_lfc_xoff), + .stat_tx_lfc_paused(stat_tx_lfc_paused), + .stat_tx_pfc_pkt(stat_tx_pfc_pkt), + .stat_tx_pfc_xon(stat_tx_pfc_xon), + .stat_tx_pfc_xoff(stat_tx_pfc_xoff), + .stat_tx_pfc_paused(stat_tx_pfc_paused) + ); + + mac_pause_ctrl_rx #( + .MCF_PARAMS_SIZE(18), + .PFC_ENABLE(PFC_ENABLE) + ) + mac_pause_ctrl_rx_inst ( + .clk(rx_clk), + .rst(rx_rst), + + /* + * MAC control frame interface + */ + .mcf_valid(rx_mcf_valid), + .mcf_eth_dst(rx_mcf_eth_dst), + .mcf_eth_src(rx_mcf_eth_src), + .mcf_eth_type(rx_mcf_eth_type), + .mcf_opcode(rx_mcf_opcode), + .mcf_params(rx_mcf_params), + + /* + * Pause (IEEE 802.3 annex 31B) + */ + .rx_lfc_en(rx_lfc_en), + .rx_lfc_req(rx_lfc_req), + .rx_lfc_ack(rx_lfc_ack_int), + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D) + */ + .rx_pfc_en(rx_pfc_en), + .rx_pfc_req(rx_pfc_req), + .rx_pfc_ack(rx_pfc_ack), + + /* + * Configuration + */ + .cfg_rx_lfc_opcode(cfg_rx_lfc_opcode), + .cfg_rx_lfc_en(cfg_rx_lfc_en), + .cfg_rx_pfc_opcode(cfg_rx_pfc_opcode), + .cfg_rx_pfc_en(cfg_rx_pfc_en), + .cfg_quanta_step(rx_mii_select ? (4*256)/512 : (8*256)/512), + .cfg_quanta_clk_en(rx_clk_enable), + + /* + * Status + */ + .stat_rx_lfc_pkt(stat_rx_lfc_pkt), + .stat_rx_lfc_xon(stat_rx_lfc_xon), + .stat_rx_lfc_xoff(stat_rx_lfc_xoff), + .stat_rx_lfc_paused(stat_rx_lfc_paused), + .stat_rx_pfc_pkt(stat_rx_pfc_pkt), + .stat_rx_pfc_xon(stat_rx_pfc_xon), + .stat_rx_pfc_xoff(stat_rx_pfc_xoff), + .stat_rx_pfc_paused(stat_rx_pfc_paused) + ); + +end else begin + + assign tx_axis_tdata_int = tx_axis_tdata; + assign tx_axis_tvalid_int = tx_axis_tvalid; + assign tx_axis_tready = tx_axis_tready_int; + assign tx_axis_tlast_int = tx_axis_tlast; + assign tx_axis_tuser_int = tx_axis_tuser; + + assign rx_axis_tdata = rx_axis_tdata_int; + assign rx_axis_tvalid = rx_axis_tvalid_int; + assign rx_axis_tlast = rx_axis_tlast_int; + assign rx_axis_tuser = rx_axis_tuser_int; + + assign rx_lfc_req = 0; + assign rx_pfc_req = 0; + assign tx_pause_ack = 0; + + assign stat_tx_mcf = 0; + assign stat_rx_mcf = 0; + assign stat_tx_lfc_pkt = 0; + assign stat_tx_lfc_xon = 0; + assign stat_tx_lfc_xoff = 0; + assign stat_tx_lfc_paused = 0; + assign stat_tx_pfc_pkt = 0; + assign stat_tx_pfc_xon = 0; + assign stat_tx_pfc_xoff = 0; + assign stat_tx_pfc_paused = 0; + assign stat_rx_lfc_pkt = 0; + assign stat_rx_lfc_xon = 0; + assign stat_rx_lfc_xoff = 0; + assign stat_rx_lfc_paused = 0; + assign stat_rx_pfc_pkt = 0; + assign stat_rx_pfc_xon = 0; + assign stat_rx_pfc_xoff = 0; + assign stat_rx_pfc_paused = 0; + +end + +endgenerate + +endmodule + +`resetall diff --git a/src/rvvi/eth_mac_mii.sv b/src/rvvi/eth_mac_mii.sv new file mode 100644 index 000000000..212f4b84a --- /dev/null +++ b/src/rvvi/eth_mac_mii.sv @@ -0,0 +1,175 @@ +/* + +Copyright (c) 2019 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * 10M/100M Ethernet MAC with MII interface + */ +module eth_mac_mii # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64 +) +( + input wire rst, + output wire rx_clk, + output wire rx_rst, + output wire tx_clk, + output wire tx_rst, + + /* + * AXI input + */ + input wire [7:0] tx_axis_tdata, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [7:0] rx_axis_tdata, + output wire rx_axis_tvalid, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * MII interface + */ + input wire mii_rx_clk, + input wire [3:0] mii_rxd, + input wire mii_rx_dv, + input wire mii_rx_er, + input wire mii_tx_clk, + output wire [3:0] mii_txd, + output wire mii_tx_en, + output wire mii_tx_er, + + /* + * Status + */ + output wire tx_start_packet, + output wire tx_error_underflow, + output wire rx_start_packet, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + + /* + * Configuration + */ + input wire [7:0] cfg_ifg, + input wire cfg_tx_enable, + input wire cfg_rx_enable +); + +wire [3:0] mac_mii_rxd; +wire mac_mii_rx_dv; +wire mac_mii_rx_er; +wire [3:0] mac_mii_txd; +wire mac_mii_tx_en; +wire mac_mii_tx_er; + +mii_phy_if #( + .TARGET(TARGET), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE) +) +mii_phy_if_inst ( + .rst(rst), + + .mac_mii_rx_clk(rx_clk), + .mac_mii_rx_rst(rx_rst), + .mac_mii_rxd(mac_mii_rxd), + .mac_mii_rx_dv(mac_mii_rx_dv), + .mac_mii_rx_er(mac_mii_rx_er), + .mac_mii_tx_clk(tx_clk), + .mac_mii_tx_rst(tx_rst), + .mac_mii_txd(mac_mii_txd), + .mac_mii_tx_en(mac_mii_tx_en), + .mac_mii_tx_er(mac_mii_tx_er), + + .phy_mii_rx_clk(mii_rx_clk), + .phy_mii_rxd(mii_rxd), + .phy_mii_rx_dv(mii_rx_dv), + .phy_mii_rx_er(mii_rx_er), + .phy_mii_tx_clk(mii_tx_clk), + .phy_mii_txd(mii_txd), + .phy_mii_tx_en(mii_tx_en), + .phy_mii_tx_er(mii_tx_er) +); + // *** there a bunch of missing pins +/* verilator lint_off PINMISSING */ +eth_mac_1g #( + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +eth_mac_1g_inst ( + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_axis_tdata(tx_axis_tdata), + .tx_axis_tvalid(tx_axis_tvalid), + .tx_axis_tready(tx_axis_tready), + .tx_axis_tlast(tx_axis_tlast), + .tx_axis_tuser(tx_axis_tuser), + .rx_axis_tdata(rx_axis_tdata), + .rx_axis_tvalid(rx_axis_tvalid), + .rx_axis_tlast(rx_axis_tlast), + .rx_axis_tuser(rx_axis_tuser), + .gmii_rxd(mac_mii_rxd), + .gmii_rx_dv(mac_mii_rx_dv), + .gmii_rx_er(mac_mii_rx_er), + .gmii_txd(mac_mii_txd), + .gmii_tx_en(mac_mii_tx_en), + .gmii_tx_er(mac_mii_tx_er), + .rx_clk_enable(1'b1), + .tx_clk_enable(1'b1), + .rx_mii_select(1'b1), + .tx_mii_select(1'b1), + .tx_start_packet(tx_start_packet), + .tx_error_underflow(tx_error_underflow), + .rx_start_packet(rx_start_packet), + .rx_error_bad_frame(rx_error_bad_frame), + .rx_error_bad_fcs(rx_error_bad_fcs), + .cfg_ifg(cfg_ifg), + .cfg_tx_enable(cfg_tx_enable), + .cfg_rx_enable(cfg_rx_enable) +); +/* verilator lint_on PINMISSING */ + +endmodule + +`resetall diff --git a/src/rvvi/eth_mac_mii_fifo.sv b/src/rvvi/eth_mac_mii_fifo.sv new file mode 100644 index 000000000..a285ceeed --- /dev/null +++ b/src/rvvi/eth_mac_mii_fifo.sv @@ -0,0 +1,339 @@ +/* + +Copyright (c) 2019 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * 10M/100M Ethernet MAC with MII interface and TX and RX FIFOs + */ +module eth_mac_mii_fifo # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + parameter AXIS_DATA_WIDTH = 8, + parameter AXIS_KEEP_ENABLE = (AXIS_DATA_WIDTH>8), + parameter AXIS_KEEP_WIDTH = (AXIS_DATA_WIDTH/8), + parameter ENABLE_PADDING = 1, + parameter MIN_FRAME_LENGTH = 64, + parameter TX_FIFO_DEPTH = 4096, + parameter TX_FIFO_RAM_PIPELINE = 1, + parameter TX_FRAME_FIFO = 1, + parameter TX_DROP_OVERSIZE_FRAME = TX_FRAME_FIFO, + parameter TX_DROP_BAD_FRAME = TX_DROP_OVERSIZE_FRAME, + parameter TX_DROP_WHEN_FULL = 0, + parameter RX_FIFO_DEPTH = 4096, + parameter RX_FIFO_RAM_PIPELINE = 1, + parameter RX_FRAME_FIFO = 1, + parameter RX_DROP_OVERSIZE_FRAME = RX_FRAME_FIFO, + parameter RX_DROP_BAD_FRAME = RX_DROP_OVERSIZE_FRAME, + parameter RX_DROP_WHEN_FULL = RX_DROP_OVERSIZE_FRAME +) +( + input wire rst, + input wire logic_clk, + input wire logic_rst, + + /* + * AXI input + */ + input wire [AXIS_DATA_WIDTH-1:0] tx_axis_tdata, + input wire [AXIS_KEEP_WIDTH-1:0] tx_axis_tkeep, + input wire tx_axis_tvalid, + output wire tx_axis_tready, + input wire tx_axis_tlast, + input wire tx_axis_tuser, + + /* + * AXI output + */ + output wire [AXIS_DATA_WIDTH-1:0] rx_axis_tdata, + output wire [AXIS_KEEP_WIDTH-1:0] rx_axis_tkeep, + output wire rx_axis_tvalid, + input wire rx_axis_tready, + output wire rx_axis_tlast, + output wire rx_axis_tuser, + + /* + * MII interface + */ + input wire mii_rx_clk, + input wire [3:0] mii_rxd, + input wire mii_rx_dv, + input wire mii_rx_er, + input wire mii_tx_clk, + output wire [3:0] mii_txd, + output wire mii_tx_en, + output wire mii_tx_er, + + /* + * Status + */ + output wire tx_error_underflow, + output wire tx_fifo_overflow, + output wire tx_fifo_bad_frame, + output wire tx_fifo_good_frame, + output wire rx_error_bad_frame, + output wire rx_error_bad_fcs, + output wire rx_fifo_overflow, + output wire rx_fifo_bad_frame, + output wire rx_fifo_good_frame, + + /* + * Configuration + */ + input wire [7:0] cfg_ifg, + input wire cfg_tx_enable, + input wire cfg_rx_enable +); + +wire tx_clk; +wire rx_clk; +wire tx_rst; +wire rx_rst; + +wire [7:0] tx_fifo_axis_tdata; +wire tx_fifo_axis_tvalid; +wire tx_fifo_axis_tready; +wire tx_fifo_axis_tlast; +wire tx_fifo_axis_tuser; + +wire [7:0] rx_fifo_axis_tdata; +wire rx_fifo_axis_tvalid; +wire rx_fifo_axis_tlast; +wire rx_fifo_axis_tuser; + +// synchronize MAC status signals into logic clock domain +wire tx_error_underflow_int; + +reg [0:0] tx_sync_reg_1 = 1'b0; +reg [0:0] tx_sync_reg_2 = 1'b0; +reg [0:0] tx_sync_reg_3 = 1'b0; +reg [0:0] tx_sync_reg_4 = 1'b0; + +assign tx_error_underflow = tx_sync_reg_3[0] ^ tx_sync_reg_4[0]; + +always @(posedge tx_clk or posedge tx_rst) begin + if (tx_rst) begin + tx_sync_reg_1 <= 1'b0; + end else begin + tx_sync_reg_1 <= tx_sync_reg_1 ^ {tx_error_underflow_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + tx_sync_reg_2 <= 1'b0; + tx_sync_reg_3 <= 1'b0; + tx_sync_reg_4 <= 1'b0; + end else begin + tx_sync_reg_2 <= tx_sync_reg_1; + tx_sync_reg_3 <= tx_sync_reg_2; + tx_sync_reg_4 <= tx_sync_reg_3; + end +end + +wire rx_error_bad_frame_int; +wire rx_error_bad_fcs_int; + +reg [1:0] rx_sync_reg_1 = 2'd0; +reg [1:0] rx_sync_reg_2 = 2'd0; +reg [1:0] rx_sync_reg_3 = 2'd0; +reg [1:0] rx_sync_reg_4 = 2'd0; + +assign rx_error_bad_frame = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; +assign rx_error_bad_fcs = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; + +always @(posedge rx_clk or posedge rx_rst) begin + if (rx_rst) begin + rx_sync_reg_1 <= 2'd0; + end else begin + rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_error_bad_fcs_int, rx_error_bad_frame_int}; + end +end + +always @(posedge logic_clk or posedge logic_rst) begin + if (logic_rst) begin + rx_sync_reg_2 <= 2'd0; + rx_sync_reg_3 <= 2'd0; + rx_sync_reg_4 <= 2'd0; + end else begin + rx_sync_reg_2 <= rx_sync_reg_1; + rx_sync_reg_3 <= rx_sync_reg_2; + rx_sync_reg_4 <= rx_sync_reg_3; + end +end + + // *** there are a bunch of missing pins + /* verilator lint_off PINMISSING */ +eth_mac_mii #( + .TARGET(TARGET), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .ENABLE_PADDING(ENABLE_PADDING), + .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) +) +eth_mac_1g_mii_inst ( + .rst(rst), + .tx_clk(tx_clk), + .tx_rst(tx_rst), + .rx_clk(rx_clk), + .rx_rst(rx_rst), + .tx_axis_tdata(tx_fifo_axis_tdata), + .tx_axis_tvalid(tx_fifo_axis_tvalid), + .tx_axis_tready(tx_fifo_axis_tready), + .tx_axis_tlast(tx_fifo_axis_tlast), + .tx_axis_tuser(tx_fifo_axis_tuser), + .rx_axis_tdata(rx_fifo_axis_tdata), + .rx_axis_tvalid(rx_fifo_axis_tvalid), + .rx_axis_tlast(rx_fifo_axis_tlast), + .rx_axis_tuser(rx_fifo_axis_tuser), + .mii_rx_clk(mii_rx_clk), + .mii_rxd(mii_rxd), + .mii_rx_dv(mii_rx_dv), + .mii_rx_er(mii_rx_er), + .mii_tx_clk(mii_tx_clk), + .mii_txd(mii_txd), + .mii_tx_en(mii_tx_en), + .mii_tx_er(mii_tx_er), + .tx_error_underflow(tx_error_underflow_int), + .rx_error_bad_frame(rx_error_bad_frame_int), + .rx_error_bad_fcs(rx_error_bad_fcs_int), + .cfg_ifg(cfg_ifg), + .cfg_tx_enable(cfg_tx_enable), + .cfg_rx_enable(cfg_rx_enable) +); + +axis_async_fifo_adapter #( + .DEPTH(TX_FIFO_DEPTH), + .S_DATA_WIDTH(AXIS_DATA_WIDTH), + .S_KEEP_ENABLE(AXIS_KEEP_ENABLE), + .S_KEEP_WIDTH(AXIS_KEEP_WIDTH), + .M_DATA_WIDTH(8), + .M_KEEP_ENABLE(0), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .RAM_PIPELINE(TX_FIFO_RAM_PIPELINE), + .FRAME_FIFO(TX_FRAME_FIFO), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_OVERSIZE_FRAME(TX_DROP_OVERSIZE_FRAME), + .DROP_BAD_FRAME(TX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(TX_DROP_WHEN_FULL) +) +tx_fifo ( + // AXI input + .s_clk(logic_clk), + .s_rst(logic_rst), + .s_axis_tdata(tx_axis_tdata), + .s_axis_tkeep(tx_axis_tkeep), + .s_axis_tvalid(tx_axis_tvalid), + .s_axis_tready(tx_axis_tready), + .s_axis_tlast(tx_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(tx_axis_tuser), + // AXI output + .m_clk(tx_clk), + .m_rst(tx_rst), + .m_axis_tdata(tx_fifo_axis_tdata), + .m_axis_tkeep(), + .m_axis_tvalid(tx_fifo_axis_tvalid), + .m_axis_tready(tx_fifo_axis_tready), + .m_axis_tlast(tx_fifo_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(tx_fifo_axis_tuser), + // Status + .s_status_overflow(tx_fifo_overflow), + .s_status_bad_frame(tx_fifo_bad_frame), + .s_status_good_frame(tx_fifo_good_frame), + .m_status_overflow(), + .m_status_bad_frame(), + .m_status_good_frame() +); + +axis_async_fifo_adapter #( + .DEPTH(RX_FIFO_DEPTH), + .S_DATA_WIDTH(8), + .S_KEEP_ENABLE(0), + .M_DATA_WIDTH(AXIS_DATA_WIDTH), + .M_KEEP_ENABLE(AXIS_KEEP_ENABLE), + .M_KEEP_WIDTH(AXIS_KEEP_WIDTH), + .ID_ENABLE(0), + .DEST_ENABLE(0), + .USER_ENABLE(1), + .USER_WIDTH(1), + .RAM_PIPELINE(RX_FIFO_RAM_PIPELINE), + .FRAME_FIFO(RX_FRAME_FIFO), + .USER_BAD_FRAME_VALUE(1'b1), + .USER_BAD_FRAME_MASK(1'b1), + .DROP_OVERSIZE_FRAME(RX_DROP_OVERSIZE_FRAME), + .DROP_BAD_FRAME(RX_DROP_BAD_FRAME), + .DROP_WHEN_FULL(RX_DROP_WHEN_FULL) +) +rx_fifo ( + // AXI input + .s_clk(rx_clk), + .s_rst(rx_rst), + .s_axis_tdata(rx_fifo_axis_tdata), + .s_axis_tkeep(0), + .s_axis_tvalid(rx_fifo_axis_tvalid), + .s_axis_tready(), + .s_axis_tlast(rx_fifo_axis_tlast), + .s_axis_tid(0), + .s_axis_tdest(0), + .s_axis_tuser(rx_fifo_axis_tuser), + // AXI output + .m_clk(logic_clk), + .m_rst(logic_rst), + .m_axis_tdata(rx_axis_tdata), + .m_axis_tkeep(rx_axis_tkeep), + .m_axis_tvalid(rx_axis_tvalid), + .m_axis_tready(rx_axis_tready), + .m_axis_tlast(rx_axis_tlast), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(rx_axis_tuser), + // Status + .s_status_overflow(), + .s_status_bad_frame(), + .s_status_good_frame(), + .m_status_overflow(rx_fifo_overflow), + .m_status_bad_frame(rx_fifo_bad_frame), + .m_status_good_frame(rx_fifo_good_frame) +); +/* verilator lint_on PINMISSING */ + +endmodule + +`resetall diff --git a/src/rvvi/lfsr.sv b/src/rvvi/lfsr.sv new file mode 100644 index 000000000..4b404fe94 --- /dev/null +++ b/src/rvvi/lfsr.sv @@ -0,0 +1,446 @@ +/* + +Copyright (c) 2016-2023 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * Parametrizable combinatorial parallel LFSR/CRC + */ +module lfsr # +( + // width of LFSR + parameter LFSR_WIDTH = 31, + // LFSR polynomial + parameter LFSR_POLY = 31'h10000001, + // LFSR configuration: "GALOIS", "FIBONACCI" + parameter LFSR_CONFIG = "FIBONACCI", + // LFSR feed forward enable + parameter LFSR_FEED_FORWARD = 0, + // bit-reverse input and output + parameter REVERSE = 0, + // width of data input + parameter DATA_WIDTH = 8, + // implementation style: "AUTO", "LOOP", "REDUCTION" + parameter STYLE = "AUTO" +) +( + input wire [DATA_WIDTH-1:0] data_in, + input wire [LFSR_WIDTH-1:0] state_in, + output wire [DATA_WIDTH-1:0] data_out, + output wire [LFSR_WIDTH-1:0] state_out +); + +/* + +Fully parametrizable combinatorial parallel LFSR/CRC module. Implements an unrolled LFSR +next state computation, shifting DATA_WIDTH bits per pass through the module. Input data +is XORed with LFSR feedback path, tie data_in to zero if this is not required. + +Works in two parts: statically computes a set of bit masks, then uses these bit masks to +select bits for XORing to compute the next state. + +Ports: + +data_in + +Data bits to be shifted through the LFSR (DATA_WIDTH bits) + +state_in + +LFSR/CRC current state input (LFSR_WIDTH bits) + +data_out + +Data bits shifted out of LFSR (DATA_WIDTH bits) + +state_out + +LFSR/CRC next state output (LFSR_WIDTH bits) + +Parameters: + +LFSR_WIDTH + +Specify width of LFSR/CRC register + +LFSR_POLY + +Specify the LFSR/CRC polynomial in hex format. For example, the polynomial + +x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 + +would be represented as + +32'h04c11db7 + +Note that the largest term (x^32) is suppressed. This term is generated automatically based +on LFSR_WIDTH. + +LFSR_CONFIG + +Specify the LFSR configuration, either Fibonacci or Galois. Fibonacci is generally used +for linear-feedback shift registers (LFSR) for pseudorandom binary sequence (PRBS) generators, +scramblers, and descrambers, while Galois is generally used for cyclic redundancy check +generators and checkers. + +Fibonacci style (example for 64b66b scrambler, 0x8000000001) + + DIN (LSB first) + | + V + (+)<---------------------------(+)<-----------------------------. + | ^ | + | .----. .----. .----. | .----. .----. .----. | + +->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--' + | '----' '----' '----' '----' '----' '----' + V + DOUT + +Galois style (example for CRC16, 0x8005) + + ,-------------------+-------------------------+----------(+)<-- DIN (MSB first) + | | | ^ + | .----. .----. V .----. .----. V .----. | + `->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |--+---> DOUT + '----' '----' '----' '----' '----' + +LFSR_FEED_FORWARD + +Generate feed forward instead of feed back LFSR. Enable this for PRBS checking and self- +synchronous descrambling. + +Fibonacci feed-forward style (example for 64b66b descrambler, 0x8000000001) + + DIN (LSB first) + | + | .----. .----. .----. .----. .----. .----. + +->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--. + | '----' '----' '----' | '----' '----' '----' | + | V | + (+)<---------------------------(+)------------------------------' + | + V + DOUT + +Galois feed-forward style + + ,-------------------+-------------------------+------------+--- DIN (MSB first) + | | | | + | .----. .----. V .----. .----. V .----. V + `->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |->(+)-> DOUT + '----' '----' '----' '----' '----' + +REVERSE + +Bit-reverse LFSR input and output. Shifts MSB first by default, set REVERSE for LSB first. + +DATA_WIDTH + +Specify width of input and output data bus. The module will perform one shift per input +data bit, so if the input data bus is not required tie data_in to zero and set DATA_WIDTH +to the required number of shifts per clock cycle. + +STYLE + +Specify implementation style. Can be "AUTO", "LOOP", or "REDUCTION". When "AUTO" +is selected, implemenation will be "LOOP" or "REDUCTION" based on synthesis translate +directives. "REDUCTION" and "LOOP" are functionally identical, however they simulate +and synthesize differently. "REDUCTION" is implemented with a loop over a Verilog +reduction operator. "LOOP" is implemented as a doubly-nested loop with no reduction +operator. "REDUCTION" is very fast for simulation in iverilog and synthesizes well in +Quartus but synthesizes poorly in ISE, likely due to large inferred XOR gates causing +problems with the optimizer. "LOOP" synthesizes will in both ISE and Quartus. "AUTO" +will default to "REDUCTION" when simulating and "LOOP" for synthesizers that obey +synthesis translate directives. + +Settings for common LFSR/CRC implementations: + +Name Configuration Length Polynomial Initial value Notes +CRC16-IBM Galois, bit-reverse 16 16'h8005 16'hffff +CRC16-CCITT Galois 16 16'h1021 16'h1d0f +CRC32 Galois, bit-reverse 32 32'h04c11db7 32'hffffffff Ethernet FCS; invert final output +CRC32C Galois, bit-reverse 32 32'h1edc6f41 32'hffffffff iSCSI, Intel CRC32 instruction; invert final output +PRBS6 Fibonacci 6 6'h21 any +PRBS7 Fibonacci 7 7'h41 any +PRBS9 Fibonacci 9 9'h021 any ITU V.52 +PRBS10 Fibonacci 10 10'h081 any ITU +PRBS11 Fibonacci 11 11'h201 any ITU O.152 +PRBS15 Fibonacci, inverted 15 15'h4001 any ITU O.152 +PRBS17 Fibonacci 17 17'h04001 any +PRBS20 Fibonacci 20 20'h00009 any ITU V.57 +PRBS23 Fibonacci, inverted 23 23'h040001 any ITU O.151 +PRBS29 Fibonacci, inverted 29 29'h08000001 any +PRBS31 Fibonacci, inverted 31 31'h10000001 any +64b66b Fibonacci, bit-reverse 58 58'h8000000001 any 10G Ethernet +128b130b Galois, bit-reverse 23 23'h210125 any PCIe gen 3 + +*/ + +function [LFSR_WIDTH+DATA_WIDTH-1:0] lfsr_mask(input [31:0] index); + reg [LFSR_WIDTH-1:0] lfsr_mask_state[LFSR_WIDTH-1:0]; + reg [DATA_WIDTH-1:0] lfsr_mask_data[LFSR_WIDTH-1:0]; + reg [LFSR_WIDTH-1:0] output_mask_state[DATA_WIDTH-1:0]; + reg [DATA_WIDTH-1:0] output_mask_data[DATA_WIDTH-1:0]; + + reg [LFSR_WIDTH-1:0] state_val; + reg [DATA_WIDTH-1:0] data_val; + + reg [DATA_WIDTH-1:0] data_mask; + + integer i, j; + + begin + // init bit masks + for (i = 0; i < LFSR_WIDTH; i = i + 1) begin + lfsr_mask_state[i] = 0; + lfsr_mask_state[i][i] = 1'b1; + lfsr_mask_data[i] = 0; + end + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + output_mask_state[i] = 0; + if (i < LFSR_WIDTH) begin + output_mask_state[i][i] = 1'b1; + end + output_mask_data[i] = 0; + end + + // simulate shift register + if (LFSR_CONFIG == "FIBONACCI") begin + // Fibonacci configuration + for (data_mask = {1'b1, {DATA_WIDTH-1{1'b0}}}; data_mask != 0; data_mask = data_mask >> 1) begin + // determine shift in value + // current value in last FF, XOR with input data bit (MSB first) + state_val = lfsr_mask_state[LFSR_WIDTH-1]; + data_val = lfsr_mask_data[LFSR_WIDTH-1]; + data_val = data_val ^ data_mask; + + // add XOR inputs from correct indicies + for (j = 1; j < LFSR_WIDTH; j = j + 1) begin + if ((LFSR_POLY >> j) & 1) begin + state_val = lfsr_mask_state[j-1] ^ state_val; + data_val = lfsr_mask_data[j-1] ^ data_val; + end + end + + // shift + for (j = LFSR_WIDTH-1; j > 0; j = j - 1) begin + lfsr_mask_state[j] = lfsr_mask_state[j-1]; + lfsr_mask_data[j] = lfsr_mask_data[j-1]; + end + for (j = DATA_WIDTH-1; j > 0; j = j - 1) begin + output_mask_state[j] = output_mask_state[j-1]; + output_mask_data[j] = output_mask_data[j-1]; + end + output_mask_state[0] = state_val; + output_mask_data[0] = data_val; + if (LFSR_FEED_FORWARD) begin + // only shift in new input data + state_val = {LFSR_WIDTH{1'b0}}; + data_val = data_mask; + end + lfsr_mask_state[0] = state_val; + lfsr_mask_data[0] = data_val; + end + end else if (LFSR_CONFIG == "GALOIS") begin + // Galois configuration + for (data_mask = {1'b1, {DATA_WIDTH-1{1'b0}}}; data_mask != 0; data_mask = data_mask >> 1) begin + // determine shift in value + // current value in last FF, XOR with input data bit (MSB first) + state_val = lfsr_mask_state[LFSR_WIDTH-1]; + data_val = lfsr_mask_data[LFSR_WIDTH-1]; + data_val = data_val ^ data_mask; + + // shift + for (j = LFSR_WIDTH-1; j > 0; j = j - 1) begin + lfsr_mask_state[j] = lfsr_mask_state[j-1]; + lfsr_mask_data[j] = lfsr_mask_data[j-1]; + end + for (j = DATA_WIDTH-1; j > 0; j = j - 1) begin + output_mask_state[j] = output_mask_state[j-1]; + output_mask_data[j] = output_mask_data[j-1]; + end + output_mask_state[0] = state_val; + output_mask_data[0] = data_val; + if (LFSR_FEED_FORWARD) begin + // only shift in new input data + state_val = {LFSR_WIDTH{1'b0}}; + data_val = data_mask; + end + lfsr_mask_state[0] = state_val; + lfsr_mask_data[0] = data_val; + + // add XOR inputs at correct indicies + for (j = 1; j < LFSR_WIDTH; j = j + 1) begin + if ((LFSR_POLY >> j) & 1) begin + lfsr_mask_state[j] = lfsr_mask_state[j] ^ state_val; + lfsr_mask_data[j] = lfsr_mask_data[j] ^ data_val; + end + end + end + end else begin + $error("Error: unknown configuration setting!"); + $finish; + end + + // reverse bits if selected + if (REVERSE) begin + if (index < LFSR_WIDTH) begin + state_val = 0; + for (i = 0; i < LFSR_WIDTH; i = i + 1) begin + state_val[i] = lfsr_mask_state[LFSR_WIDTH-index-1][LFSR_WIDTH-i-1]; + end + + data_val = 0; + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + data_val[i] = lfsr_mask_data[LFSR_WIDTH-index-1][DATA_WIDTH-i-1]; + end + end else begin + state_val = 0; + for (i = 0; i < LFSR_WIDTH; i = i + 1) begin + state_val[i] = output_mask_state[DATA_WIDTH-(index-LFSR_WIDTH)-1][LFSR_WIDTH-i-1]; + end + + data_val = 0; + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + data_val[i] = output_mask_data[DATA_WIDTH-(index-LFSR_WIDTH)-1][DATA_WIDTH-i-1]; + end + end + end else begin + if (index < LFSR_WIDTH) begin + state_val = lfsr_mask_state[index]; + data_val = lfsr_mask_data[index]; + end else begin + state_val = output_mask_state[index-LFSR_WIDTH]; + data_val = output_mask_data[index-LFSR_WIDTH]; + end + end + lfsr_mask = {data_val, state_val}; + end +endfunction + +// synthesis translate_off +`define SIMULATION +// synthesis translate_on + +`ifdef SIMULATION +// "AUTO" style is "REDUCTION" for faster simulation +parameter STYLE_INT = (STYLE == "AUTO") ? "REDUCTION" : STYLE; +`else +// "AUTO" style is "LOOP" for better synthesis result +parameter STYLE_INT = (STYLE == "AUTO") ? "LOOP" : STYLE; +`endif + +genvar n; + +generate + +if (STYLE_INT == "REDUCTION") begin + + // use Verilog reduction operator + // fast in iverilog + // significantly larger than generated code with ISE (inferred wide XORs may be tripping up optimizer) + // slightly smaller than generated code with Quartus + // --> better for simulation + + for (n = 0; n < LFSR_WIDTH; n = n + 1) begin : lfsr_state + wire [LFSR_WIDTH+DATA_WIDTH-1:0] mask = lfsr_mask(n); + assign state_out[n] = ^({data_in, state_in} & mask); + end + for (n = 0; n < DATA_WIDTH; n = n + 1) begin : lfsr_data + wire [LFSR_WIDTH+DATA_WIDTH-1:0] mask = lfsr_mask(n+LFSR_WIDTH); + assign data_out[n] = ^({data_in, state_in} & mask); + end + +end else if (STYLE_INT == "LOOP") begin + + // use nested loops + // very slow in iverilog + // slightly smaller than generated code with ISE + // same size as generated code with Quartus + // --> better for synthesis + + for (n = 0; n < LFSR_WIDTH; n = n + 1) begin : lfsr_state + wire [LFSR_WIDTH+DATA_WIDTH-1:0] mask = lfsr_mask(n); + + reg state_reg; + + assign state_out[n] = state_reg; + + integer i; + + always @* begin + state_reg = 1'b0; + for (i = 0; i < LFSR_WIDTH; i = i + 1) begin + if (mask[i]) begin + state_reg = state_reg ^ state_in[i]; + end + end + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + if (mask[i+LFSR_WIDTH]) begin + state_reg = state_reg ^ data_in[i]; + end + end + end + end + for (n = 0; n < DATA_WIDTH; n = n + 1) begin : lfsr_data + wire [LFSR_WIDTH+DATA_WIDTH-1:0] mask = lfsr_mask(n+LFSR_WIDTH); + + reg data_reg; + + assign data_out[n] = data_reg; + + integer i; + + always @* begin + data_reg = 1'b0; + for (i = 0; i < LFSR_WIDTH; i = i + 1) begin + if (mask[i]) begin + data_reg = data_reg ^ state_in[i]; + end + end + for (i = 0; i < DATA_WIDTH; i = i + 1) begin + if (mask[i+LFSR_WIDTH]) begin + data_reg = data_reg ^ data_in[i]; + end + end + end + end + +end else begin + + initial begin + $error("Error: unknown style setting!"); + $finish; + end + +end + +endgenerate + +endmodule + +`resetall diff --git a/src/rvvi/mac_ctrl_rx.sv b/src/rvvi/mac_ctrl_rx.sv new file mode 100644 index 000000000..f7171887b --- /dev/null +++ b/src/rvvi/mac_ctrl_rx.sv @@ -0,0 +1,447 @@ +/* + +Copyright (c) 2023 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * MAC control receive + */ +module mac_ctrl_rx # +( + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = DATA_WIDTH>8, + parameter KEEP_WIDTH = DATA_WIDTH/8, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + parameter USE_READY = 0, + parameter MCF_PARAMS_SIZE = 18 +) +( + input wire clk, + input wire rst, + + /* + * AXI stream input + */ + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI stream output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * MAC control frame interface + */ + output wire mcf_valid, + output wire [47:0] mcf_eth_dst, + output wire [47:0] mcf_eth_src, + output wire [15:0] mcf_eth_type, + output wire [15:0] mcf_opcode, + output wire [MCF_PARAMS_SIZE*8-1:0] mcf_params, + output wire [ID_WIDTH-1:0] mcf_id, + output wire [DEST_WIDTH-1:0] mcf_dest, + output wire [USER_WIDTH-1:0] mcf_user, + + /* + * Configuration + */ + input wire [47:0] cfg_mcf_rx_eth_dst_mcast, + input wire cfg_mcf_rx_check_eth_dst_mcast, + input wire [47:0] cfg_mcf_rx_eth_dst_ucast, + input wire cfg_mcf_rx_check_eth_dst_ucast, + input wire [47:0] cfg_mcf_rx_eth_src, + input wire cfg_mcf_rx_check_eth_src, + input wire [15:0] cfg_mcf_rx_eth_type, + input wire [15:0] cfg_mcf_rx_opcode_lfc, + input wire cfg_mcf_rx_check_opcode_lfc, + input wire [15:0] cfg_mcf_rx_opcode_pfc, + input wire cfg_mcf_rx_check_opcode_pfc, + input wire cfg_mcf_rx_forward, + input wire cfg_mcf_rx_enable, + + /* + * Status + */ + output wire stat_rx_mcf +); + +parameter BYTE_LANES = KEEP_ENABLE ? KEEP_WIDTH : 1; + +parameter HDR_SIZE = 60; + +parameter CYCLE_COUNT = (HDR_SIZE+BYTE_LANES-1)/BYTE_LANES; + +parameter PTR_WIDTH = $clog2(CYCLE_COUNT); + +parameter OFFSET = HDR_SIZE % BYTE_LANES; + +// check configuration +initial begin + if (BYTE_LANES * 8 != DATA_WIDTH) begin + $error("Error: AXI stream interface requires byte (8-bit) granularity (instance %m)"); + $finish; + end + + if (MCF_PARAMS_SIZE > 44) begin + $error("Error: Maximum MCF_PARAMS_SIZE is 44 bytes (instance %m)"); + $finish; + end +end + +/* + +MAC control frame + + Field Length + Destination MAC address 6 octets [01:80:C2:00:00:01] + Source MAC address 6 octets + Ethertype 2 octets [0x8808] + Opcode 2 octets + Parameters 0-44 octets + +This module manages the reception of MAC control frames. Incoming frames are +checked based on the ethertype and (optionally) MAC addresses. Matching control +frames are marked by setting tuser[0] on the data output and forwarded through +a separate interface for processing. + +*/ + +reg read_mcf_reg = 1'b1, read_mcf_next; +reg mcf_frame_reg = 1'b0, mcf_frame_next; +reg [PTR_WIDTH-1:0] ptr_reg = 0, ptr_next; + +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; + +// internal datapath +reg [DATA_WIDTH-1:0] m_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg [ID_WIDTH-1:0] m_axis_tid_int; +reg [DEST_WIDTH-1:0] m_axis_tdest_int; +reg [USER_WIDTH-1:0] m_axis_tuser_int; +wire m_axis_tready_int_early; + +reg mcf_valid_reg = 0, mcf_valid_next; +reg [47:0] mcf_eth_dst_reg = 0, mcf_eth_dst_next; +reg [47:0] mcf_eth_src_reg = 0, mcf_eth_src_next; +reg [15:0] mcf_eth_type_reg = 0, mcf_eth_type_next; +reg [15:0] mcf_opcode_reg = 0, mcf_opcode_next; +reg [MCF_PARAMS_SIZE*8-1:0] mcf_params_reg = 0, mcf_params_next; +reg [ID_WIDTH-1:0] mcf_id_reg = 0, mcf_id_next; +reg [DEST_WIDTH-1:0] mcf_dest_reg = 0, mcf_dest_next; +reg [USER_WIDTH-1:0] mcf_user_reg = 0, mcf_user_next; + +reg stat_rx_mcf_reg = 1'b0, stat_rx_mcf_next; + +assign s_axis_tready = s_axis_tready_reg; + +assign mcf_valid = mcf_valid_reg; +assign mcf_eth_dst = mcf_eth_dst_reg; +assign mcf_eth_src = mcf_eth_src_reg; +assign mcf_eth_type = mcf_eth_type_reg; +assign mcf_opcode = mcf_opcode_reg; +assign mcf_params = mcf_params_reg; +assign mcf_id = mcf_id_reg; +assign mcf_dest = mcf_dest_reg; +assign mcf_user = mcf_user_reg; + +assign stat_rx_mcf = stat_rx_mcf_reg; + +wire mcf_eth_dst_mcast_match = mcf_eth_dst_next == cfg_mcf_rx_eth_dst_mcast; +wire mcf_eth_dst_ucast_match = mcf_eth_dst_next == cfg_mcf_rx_eth_dst_ucast; +wire mcf_eth_src_match = mcf_eth_src_next == cfg_mcf_rx_eth_src; +wire mcf_eth_type_match = mcf_eth_type_next == cfg_mcf_rx_eth_type; +wire mcf_opcode_lfc_match = mcf_opcode_next == cfg_mcf_rx_opcode_lfc; +wire mcf_opcode_pfc_match = mcf_opcode_next == cfg_mcf_rx_opcode_pfc; + +wire mcf_eth_dst_match = ((mcf_eth_dst_mcast_match && cfg_mcf_rx_check_eth_dst_mcast) || + (mcf_eth_dst_ucast_match && cfg_mcf_rx_check_eth_dst_ucast) || + (!cfg_mcf_rx_check_eth_dst_mcast && !cfg_mcf_rx_check_eth_dst_ucast)); + +wire mcf_opcode_match = ((mcf_opcode_lfc_match && cfg_mcf_rx_check_opcode_lfc) || + (mcf_opcode_pfc_match && cfg_mcf_rx_check_opcode_pfc) || + (!cfg_mcf_rx_check_opcode_lfc && !cfg_mcf_rx_check_opcode_pfc)); + +wire mcf_match = (mcf_eth_dst_match && + (mcf_eth_src_match || !cfg_mcf_rx_check_eth_src) && + mcf_eth_type_match && mcf_opcode_match); + +integer k; + +always @* begin + read_mcf_next = read_mcf_reg; + mcf_frame_next = mcf_frame_reg; + ptr_next = ptr_reg; + + // pass through data + m_axis_tdata_int = s_axis_tdata; + m_axis_tkeep_int = s_axis_tkeep; + m_axis_tvalid_int = s_axis_tvalid; + m_axis_tlast_int = s_axis_tlast; + m_axis_tid_int = s_axis_tid; + m_axis_tdest_int = s_axis_tdest; + m_axis_tuser_int = s_axis_tuser; + + s_axis_tready_next = m_axis_tready_int_early || !USE_READY; + + mcf_valid_next = 1'b0; + mcf_eth_dst_next = mcf_eth_dst_reg; + mcf_eth_src_next = mcf_eth_src_reg; + mcf_eth_type_next = mcf_eth_type_reg; + mcf_opcode_next = mcf_opcode_reg; + mcf_params_next = mcf_params_reg; + mcf_id_next = mcf_id_reg; + mcf_dest_next = mcf_dest_reg; + mcf_user_next = mcf_user_reg; + + stat_rx_mcf_next = 1'b0; + + if ((s_axis_tready || !USE_READY) && s_axis_tvalid) begin + if (read_mcf_reg) begin + ptr_next = ptr_reg + 1; + + mcf_id_next = s_axis_tid; + mcf_dest_next = s_axis_tdest; + mcf_user_next = s_axis_tuser; + + `define _HEADER_FIELD_(offset, field) \ + if (ptr_reg == offset/BYTE_LANES) begin \ + field = s_axis_tdata[(offset%BYTE_LANES)*8 +: 8]; \ + end + + `_HEADER_FIELD_(0, mcf_eth_dst_next[5*8 +: 8]) + `_HEADER_FIELD_(1, mcf_eth_dst_next[4*8 +: 8]) + `_HEADER_FIELD_(2, mcf_eth_dst_next[3*8 +: 8]) + `_HEADER_FIELD_(3, mcf_eth_dst_next[2*8 +: 8]) + `_HEADER_FIELD_(4, mcf_eth_dst_next[1*8 +: 8]) + `_HEADER_FIELD_(5, mcf_eth_dst_next[0*8 +: 8]) + `_HEADER_FIELD_(6, mcf_eth_src_next[5*8 +: 8]) + `_HEADER_FIELD_(7, mcf_eth_src_next[4*8 +: 8]) + `_HEADER_FIELD_(8, mcf_eth_src_next[3*8 +: 8]) + `_HEADER_FIELD_(9, mcf_eth_src_next[2*8 +: 8]) + `_HEADER_FIELD_(10, mcf_eth_src_next[1*8 +: 8]) + `_HEADER_FIELD_(11, mcf_eth_src_next[0*8 +: 8]) + `_HEADER_FIELD_(12, mcf_eth_type_next[1*8 +: 8]) + `_HEADER_FIELD_(13, mcf_eth_type_next[0*8 +: 8]) + `_HEADER_FIELD_(14, mcf_opcode_next[1*8 +: 8]) + `_HEADER_FIELD_(15, mcf_opcode_next[0*8 +: 8]) + + if (ptr_reg == 0/BYTE_LANES) begin + // ensure params field gets cleared + mcf_params_next = 0; + end + + for (k = 0; k < MCF_PARAMS_SIZE; k = k + 1) begin + if (ptr_reg == (16+k)/BYTE_LANES) begin + mcf_params_next[k*8 +: 8] = s_axis_tdata[((16+k)%BYTE_LANES)*8 +: 8]; + end + end + + if (ptr_reg == 15/BYTE_LANES && (!KEEP_ENABLE || s_axis_tkeep[13%BYTE_LANES])) begin + // record match at end of opcode field + mcf_frame_next = mcf_match && cfg_mcf_rx_enable; + end + + if (ptr_reg == (HDR_SIZE-1)/BYTE_LANES) begin + read_mcf_next = 1'b0; + end + + `undef _HEADER_FIELD_ + end + + if (s_axis_tlast) begin + if (s_axis_tuser[0]) begin + // frame marked invalid + end else if (mcf_frame_next) begin + if (!cfg_mcf_rx_forward) begin + // mark frame invalid + m_axis_tuser_int[0] = 1'b1; + end + // transfer out MAC control frame + mcf_valid_next = 1'b1; + stat_rx_mcf_next = 1'b1; + end + + read_mcf_next = 1'b1; + mcf_frame_next = 1'b0; + ptr_next = 0; + end + end +end + +always @(posedge clk) begin + read_mcf_reg <= read_mcf_next; + mcf_frame_reg <= mcf_frame_next; + ptr_reg <= ptr_next; + + s_axis_tready_reg <= s_axis_tready_next; + + mcf_valid_reg <= mcf_valid_next; + mcf_eth_dst_reg <= mcf_eth_dst_next; + mcf_eth_src_reg <= mcf_eth_src_next; + mcf_eth_type_reg <= mcf_eth_type_next; + mcf_opcode_reg <= mcf_opcode_next; + mcf_params_reg <= mcf_params_next; + mcf_id_reg <= mcf_id_next; + mcf_dest_reg <= mcf_dest_next; + mcf_user_reg <= mcf_user_next; + + stat_rx_mcf_reg <= stat_rx_mcf_next; + + if (rst) begin + read_mcf_reg <= 1'b1; + mcf_frame_reg <= 1'b0; + ptr_reg <= 0; + s_axis_tready_reg <= 1'b0; + mcf_valid_reg <= 1'b0; + stat_rx_mcf_reg <= 1'b0; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_axis_tready_int_early = m_axis_tready || !USE_READY || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (m_axis_tready_int_reg) begin + // input is ready + if (m_axis_tready || !USE_READY || !m_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_axis_tready || !USE_READY) begin + // input is not ready, but output is ready + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; + + // datapath + if (store_axis_int_to_output) begin + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tid_reg <= m_axis_tid_int; + m_axis_tdest_reg <= m_axis_tdest_int; + m_axis_tuser_reg <= m_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tid_reg <= temp_m_axis_tid_reg; + m_axis_tdest_reg <= temp_m_axis_tdest_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tid_reg <= m_axis_tid_int; + temp_m_axis_tdest_reg <= m_axis_tdest_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; + end + + if (rst) begin + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; + end +end + +endmodule + +`resetall diff --git a/src/rvvi/mac_ctrl_tx.sv b/src/rvvi/mac_ctrl_tx.sv new file mode 100644 index 000000000..3d321fd64 --- /dev/null +++ b/src/rvvi/mac_ctrl_tx.sv @@ -0,0 +1,420 @@ +/* + +Copyright (c) 2023 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * MAC control transmit + */ +module mac_ctrl_tx # +( + parameter DATA_WIDTH = 8, + parameter KEEP_ENABLE = DATA_WIDTH>8, + parameter KEEP_WIDTH = DATA_WIDTH/8, + parameter ID_ENABLE = 0, + parameter ID_WIDTH = 8, + parameter DEST_ENABLE = 0, + parameter DEST_WIDTH = 8, + parameter USER_ENABLE = 1, + parameter USER_WIDTH = 1, + parameter MCF_PARAMS_SIZE = 18 +) +( + input wire clk, + input wire rst, + + /* + * AXI stream input + */ + input wire [DATA_WIDTH-1:0] s_axis_tdata, + input wire [KEEP_WIDTH-1:0] s_axis_tkeep, + input wire s_axis_tvalid, + output wire s_axis_tready, + input wire s_axis_tlast, + input wire [ID_WIDTH-1:0] s_axis_tid, + input wire [DEST_WIDTH-1:0] s_axis_tdest, + input wire [USER_WIDTH-1:0] s_axis_tuser, + + /* + * AXI stream output + */ + output wire [DATA_WIDTH-1:0] m_axis_tdata, + output wire [KEEP_WIDTH-1:0] m_axis_tkeep, + output wire m_axis_tvalid, + input wire m_axis_tready, + output wire m_axis_tlast, + output wire [ID_WIDTH-1:0] m_axis_tid, + output wire [DEST_WIDTH-1:0] m_axis_tdest, + output wire [USER_WIDTH-1:0] m_axis_tuser, + + /* + * MAC control frame interface + */ + input wire mcf_valid, + output wire mcf_ready, + input wire [47:0] mcf_eth_dst, + input wire [47:0] mcf_eth_src, + input wire [15:0] mcf_eth_type, + input wire [15:0] mcf_opcode, + input wire [MCF_PARAMS_SIZE*8-1:0] mcf_params, + input wire [ID_WIDTH-1:0] mcf_id, + input wire [DEST_WIDTH-1:0] mcf_dest, + input wire [USER_WIDTH-1:0] mcf_user, + + /* + * Pause interface + */ + input wire tx_pause_req, + output wire tx_pause_ack, + + /* + * Status + */ + output wire stat_tx_mcf +); + +parameter BYTE_LANES = KEEP_ENABLE ? KEEP_WIDTH : 1; + +parameter HDR_SIZE = 60; + +parameter CYCLE_COUNT = (HDR_SIZE+BYTE_LANES-1)/BYTE_LANES; + +parameter PTR_WIDTH = $clog2(CYCLE_COUNT); + +parameter OFFSET = HDR_SIZE % BYTE_LANES; + +// check configuration +initial begin + if (BYTE_LANES * 8 != DATA_WIDTH) begin + $error("Error: AXI stream interface requires byte (8-bit) granularity (instance %m)"); + $finish; + end + + if (MCF_PARAMS_SIZE > 44) begin + $error("Error: Maximum MCF_PARAMS_SIZE is 44 bytes (instance %m)"); + $finish; + end +end + +/* + +MAC control frame + + Field Length + Destination MAC address 6 octets [01:80:C2:00:00:01] + Source MAC address 6 octets + Ethertype 2 octets [0x8808] + Opcode 2 octets + Parameters 0-44 octets + +This module manages the transmission of MAC control frames. Control frames +are accepted in parallel, serialized, and merged at a higher priority with +data traffic. + +*/ + +reg send_data_reg = 1'b0, send_data_next; +reg send_mcf_reg = 1'b0, send_mcf_next; +reg [PTR_WIDTH-1:0] ptr_reg = 0, ptr_next; + +reg s_axis_tready_reg = 1'b0, s_axis_tready_next; +reg mcf_ready_reg = 1'b0, mcf_ready_next; +reg tx_pause_ack_reg = 1'b0, tx_pause_ack_next; +reg stat_tx_mcf_reg = 1'b0, stat_tx_mcf_next; + +// internal datapath +reg [DATA_WIDTH-1:0] m_axis_tdata_int; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; +reg m_axis_tvalid_int; +reg m_axis_tready_int_reg = 1'b0; +reg m_axis_tlast_int; +reg [ID_WIDTH-1:0] m_axis_tid_int; +reg [DEST_WIDTH-1:0] m_axis_tdest_int; +reg [USER_WIDTH-1:0] m_axis_tuser_int; +wire m_axis_tready_int_early; + +assign s_axis_tready = s_axis_tready_reg; +assign mcf_ready = mcf_ready_reg; +assign tx_pause_ack = tx_pause_ack_reg; +assign stat_tx_mcf = stat_tx_mcf_reg; + +integer k; + +always @* begin + send_data_next = send_data_reg; + send_mcf_next = send_mcf_reg; + ptr_next = ptr_reg; + + s_axis_tready_next = 1'b0; + mcf_ready_next = 1'b0; + tx_pause_ack_next = tx_pause_ack_reg; + stat_tx_mcf_next = 1'b0; + + m_axis_tdata_int = 0; + m_axis_tkeep_int = 0; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = 1'b0; + m_axis_tid_int = 0; + m_axis_tdest_int = 0; + m_axis_tuser_int = 0; + + if (!send_data_reg && !send_mcf_reg) begin + m_axis_tdata_int = s_axis_tdata; + m_axis_tkeep_int = s_axis_tkeep; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = s_axis_tlast; + m_axis_tid_int = s_axis_tid; + m_axis_tdest_int = s_axis_tdest; + m_axis_tuser_int = s_axis_tuser; + s_axis_tready_next = m_axis_tready_int_early && !tx_pause_req; + tx_pause_ack_next = tx_pause_req; + if (s_axis_tvalid && s_axis_tready) begin + s_axis_tready_next = m_axis_tready_int_early; + tx_pause_ack_next = 1'b0; + m_axis_tvalid_int = 1'b1; + if (s_axis_tlast) begin + s_axis_tready_next = m_axis_tready_int_early && !mcf_valid && !mcf_ready; + send_data_next = 1'b0; + end else begin + send_data_next = 1'b1; + end + end else if (mcf_valid) begin + s_axis_tready_next = 1'b0; + ptr_next = 0; + send_mcf_next = 1'b1; + mcf_ready_next = (CYCLE_COUNT == 1) && m_axis_tready_int_early; + end + end + + if (send_data_reg) begin + m_axis_tdata_int = s_axis_tdata; + m_axis_tkeep_int = s_axis_tkeep; + m_axis_tvalid_int = 1'b0; + m_axis_tlast_int = s_axis_tlast; + m_axis_tid_int = s_axis_tid; + m_axis_tdest_int = s_axis_tdest; + m_axis_tuser_int = s_axis_tuser; + s_axis_tready_next = m_axis_tready_int_early; + if (s_axis_tvalid && s_axis_tready) begin + m_axis_tvalid_int = 1'b1; + if (s_axis_tlast) begin + s_axis_tready_next = m_axis_tready_int_early && !tx_pause_req; + send_data_next = 1'b0; + if (mcf_valid) begin + s_axis_tready_next = 1'b0; + ptr_next = 0; + send_mcf_next = 1'b1; + mcf_ready_next = (CYCLE_COUNT == 1) && m_axis_tready_int_early; + end + end else begin + send_data_next = 1'b1; + end + end + end + + if (send_mcf_reg) begin + mcf_ready_next = (CYCLE_COUNT == 1 || ptr_reg == CYCLE_COUNT-1) && m_axis_tready_int_early; + if (m_axis_tready_int_reg) begin + ptr_next = ptr_reg + 1; + + m_axis_tvalid_int = 1'b1; + m_axis_tid_int = mcf_id; + m_axis_tdest_int = mcf_dest; + m_axis_tuser_int = mcf_user; + + `define _HEADER_FIELD_(offset, field) \ + if (ptr_reg == offset/BYTE_LANES) begin \ + m_axis_tdata_int[(offset%BYTE_LANES)*8 +: 8] = field; \ + m_axis_tkeep_int[offset%BYTE_LANES] = 1'b1; \ + end + + `_HEADER_FIELD_(0, mcf_eth_dst[5*8 +: 8]) + `_HEADER_FIELD_(1, mcf_eth_dst[4*8 +: 8]) + `_HEADER_FIELD_(2, mcf_eth_dst[3*8 +: 8]) + `_HEADER_FIELD_(3, mcf_eth_dst[2*8 +: 8]) + `_HEADER_FIELD_(4, mcf_eth_dst[1*8 +: 8]) + `_HEADER_FIELD_(5, mcf_eth_dst[0*8 +: 8]) + `_HEADER_FIELD_(6, mcf_eth_src[5*8 +: 8]) + `_HEADER_FIELD_(7, mcf_eth_src[4*8 +: 8]) + `_HEADER_FIELD_(8, mcf_eth_src[3*8 +: 8]) + `_HEADER_FIELD_(9, mcf_eth_src[2*8 +: 8]) + `_HEADER_FIELD_(10, mcf_eth_src[1*8 +: 8]) + `_HEADER_FIELD_(11, mcf_eth_src[0*8 +: 8]) + `_HEADER_FIELD_(12, mcf_eth_type[1*8 +: 8]) + `_HEADER_FIELD_(13, mcf_eth_type[0*8 +: 8]) + `_HEADER_FIELD_(14, mcf_opcode[1*8 +: 8]) + `_HEADER_FIELD_(15, mcf_opcode[0*8 +: 8]) + + for (k = 0; k < HDR_SIZE-16; k = k + 1) begin + if (ptr_reg == (16+k)/BYTE_LANES) begin + if (k < MCF_PARAMS_SIZE) begin + m_axis_tdata_int[((16+k)%BYTE_LANES)*8 +: 8] = mcf_params[k*8 +: 8]; + end else begin + m_axis_tdata_int[((16+k)%BYTE_LANES)*8 +: 8] = 0; + end + m_axis_tkeep_int[(16+k)%BYTE_LANES] = 1'b1; + end + end + + if (ptr_reg == (HDR_SIZE-1)/BYTE_LANES) begin + s_axis_tready_next = m_axis_tready_int_early && !tx_pause_req; + mcf_ready_next = 1'b0; + m_axis_tlast_int = 1'b1; + send_mcf_next = 1'b0; + stat_tx_mcf_next = 1'b1; + end else begin + mcf_ready_next = (ptr_next == CYCLE_COUNT-1) && m_axis_tready_int_early; + end + + `undef _HEADER_FIELD_ + end + end +end + +always @(posedge clk) begin + send_data_reg <= send_data_next; + send_mcf_reg <= send_mcf_next; + ptr_reg <= ptr_next; + + s_axis_tready_reg <= s_axis_tready_next; + mcf_ready_reg <= mcf_ready_next; + tx_pause_ack_reg <= tx_pause_ack_next; + stat_tx_mcf_reg <= stat_tx_mcf_next; + + if (rst) begin + send_data_reg <= 1'b0; + send_mcf_reg <= 1'b0; + ptr_reg <= 0; + s_axis_tready_reg <= 1'b0; + mcf_ready_reg <= 1'b0; + tx_pause_ack_reg <= 1'b0; + stat_tx_mcf_reg <= 1'b0; + end +end + +// output datapath logic +reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; +reg m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; +reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; +reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; +reg temp_m_axis_tlast_reg = 1'b0; +reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; +reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; +reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; + +// datapath control +reg store_axis_int_to_output; +reg store_axis_int_to_temp; +reg store_axis_temp_to_output; + +assign m_axis_tdata = m_axis_tdata_reg; +assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; +assign m_axis_tvalid = m_axis_tvalid_reg; +assign m_axis_tlast = m_axis_tlast_reg; +assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; +assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; +assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; + +// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) +assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); + +always @* begin + // transfer sink ready state to source + m_axis_tvalid_next = m_axis_tvalid_reg; + temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; + + store_axis_int_to_output = 1'b0; + store_axis_int_to_temp = 1'b0; + store_axis_temp_to_output = 1'b0; + + if (m_axis_tready_int_reg) begin + // input is ready + if (m_axis_tready || !m_axis_tvalid_reg) begin + // output is ready or currently not valid, transfer data to output + m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_output = 1'b1; + end else begin + // output is not ready, store input in temp + temp_m_axis_tvalid_next = m_axis_tvalid_int; + store_axis_int_to_temp = 1'b1; + end + end else if (m_axis_tready) begin + // input is not ready, but output is ready + m_axis_tvalid_next = temp_m_axis_tvalid_reg; + temp_m_axis_tvalid_next = 1'b0; + store_axis_temp_to_output = 1'b1; + end +end + +always @(posedge clk) begin + m_axis_tvalid_reg <= m_axis_tvalid_next; + m_axis_tready_int_reg <= m_axis_tready_int_early; + temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; + + // datapath + if (store_axis_int_to_output) begin + m_axis_tdata_reg <= m_axis_tdata_int; + m_axis_tkeep_reg <= m_axis_tkeep_int; + m_axis_tlast_reg <= m_axis_tlast_int; + m_axis_tid_reg <= m_axis_tid_int; + m_axis_tdest_reg <= m_axis_tdest_int; + m_axis_tuser_reg <= m_axis_tuser_int; + end else if (store_axis_temp_to_output) begin + m_axis_tdata_reg <= temp_m_axis_tdata_reg; + m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; + m_axis_tlast_reg <= temp_m_axis_tlast_reg; + m_axis_tid_reg <= temp_m_axis_tid_reg; + m_axis_tdest_reg <= temp_m_axis_tdest_reg; + m_axis_tuser_reg <= temp_m_axis_tuser_reg; + end + + if (store_axis_int_to_temp) begin + temp_m_axis_tdata_reg <= m_axis_tdata_int; + temp_m_axis_tkeep_reg <= m_axis_tkeep_int; + temp_m_axis_tlast_reg <= m_axis_tlast_int; + temp_m_axis_tid_reg <= m_axis_tid_int; + temp_m_axis_tdest_reg <= m_axis_tdest_int; + temp_m_axis_tuser_reg <= m_axis_tuser_int; + end + + if (rst) begin + m_axis_tvalid_reg <= 1'b0; + m_axis_tready_int_reg <= 1'b0; + temp_m_axis_tvalid_reg <= 1'b0; + end +end + +endmodule + +`resetall diff --git a/src/rvvi/mac_pause_ctrl_rx.sv b/src/rvvi/mac_pause_ctrl_rx.sv new file mode 100644 index 000000000..e95c07bf9 --- /dev/null +++ b/src/rvvi/mac_pause_ctrl_rx.sv @@ -0,0 +1,220 @@ +/* + +Copyright (c) 2023 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * PFC and pause frame receive handling + */ +module mac_pause_ctrl_rx # +( + parameter MCF_PARAMS_SIZE = 18, + parameter PFC_ENABLE = 1 +) +( + input wire clk, + input wire rst, + + /* + * MAC control frame interface + */ + input wire mcf_valid, + input wire [47:0] mcf_eth_dst, + input wire [47:0] mcf_eth_src, + input wire [15:0] mcf_eth_type, + input wire [15:0] mcf_opcode, + input wire [MCF_PARAMS_SIZE*8-1:0] mcf_params, + + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + input wire rx_lfc_en, + output wire rx_lfc_req, + input wire rx_lfc_ack, + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) + */ + input wire [7:0] rx_pfc_en, + output wire [7:0] rx_pfc_req, + input wire [7:0] rx_pfc_ack, + + /* + * Configuration + */ + input wire [15:0] cfg_rx_lfc_opcode, + input wire cfg_rx_lfc_en, + input wire [15:0] cfg_rx_pfc_opcode, + input wire cfg_rx_pfc_en, + input wire [9:0] cfg_quanta_step, + input wire cfg_quanta_clk_en, + + /* + * Status + */ + output wire stat_rx_lfc_pkt, + output wire stat_rx_lfc_xon, + output wire stat_rx_lfc_xoff, + output wire stat_rx_lfc_paused, + output wire stat_rx_pfc_pkt, + output wire [7:0] stat_rx_pfc_xon, + output wire [7:0] stat_rx_pfc_xoff, + output wire [7:0] stat_rx_pfc_paused +); + +localparam QFB = 8; + +// check configuration +initial begin + if (MCF_PARAMS_SIZE < (PFC_ENABLE ? 18 : 2)) begin + $error("Error: MCF_PARAMS_SIZE too small for requested configuration (instance %m)"); + $finish; + end +end + +reg lfc_req_reg = 1'b0, lfc_req_next; +reg [7:0] pfc_req_reg = 8'd0, pfc_req_next; + +reg [16+QFB-1:0] lfc_quanta_reg = 0, lfc_quanta_next; +reg [16+QFB-1:0] pfc_quanta_reg[0:7], pfc_quanta_next[0:7]; + +reg stat_rx_lfc_pkt_reg = 1'b0, stat_rx_lfc_pkt_next; +reg stat_rx_lfc_xon_reg = 1'b0, stat_rx_lfc_xon_next; +reg stat_rx_lfc_xoff_reg = 1'b0, stat_rx_lfc_xoff_next; +reg stat_rx_pfc_pkt_reg = 1'b0, stat_rx_pfc_pkt_next; +reg [7:0] stat_rx_pfc_xon_reg = 0, stat_rx_pfc_xon_next; +reg [7:0] stat_rx_pfc_xoff_reg = 0, stat_rx_pfc_xoff_next; + +assign rx_lfc_req = lfc_req_reg; +assign rx_pfc_req = pfc_req_reg; + +assign stat_rx_lfc_pkt = stat_rx_lfc_pkt_reg; +assign stat_rx_lfc_xon = stat_rx_lfc_xon_reg; +assign stat_rx_lfc_xoff = stat_rx_lfc_xoff_reg; +assign stat_rx_lfc_paused = lfc_req_reg; +assign stat_rx_pfc_pkt = stat_rx_pfc_pkt_reg; +assign stat_rx_pfc_xon = stat_rx_pfc_xon_reg; +assign stat_rx_pfc_xoff = stat_rx_pfc_xoff_reg; +assign stat_rx_pfc_paused = pfc_req_reg; + +integer k; + +initial begin + for (k = 0; k < 8; k = k + 1) begin + pfc_quanta_reg[k] = 0; + end +end + +always @* begin + stat_rx_lfc_pkt_next = 1'b0; + stat_rx_lfc_xon_next = 1'b0; + stat_rx_lfc_xoff_next = 1'b0; + stat_rx_pfc_pkt_next = 1'b0; + stat_rx_pfc_xon_next = 0; + stat_rx_pfc_xoff_next = 0; + + if (cfg_quanta_clk_en && rx_lfc_ack) begin + if (lfc_quanta_reg > cfg_quanta_step) begin + lfc_quanta_next = lfc_quanta_reg - cfg_quanta_step; + end else begin + lfc_quanta_next = 0; + end + end else begin + lfc_quanta_next = lfc_quanta_reg; + end + + lfc_req_next = (lfc_quanta_reg != 0) && rx_lfc_en && cfg_rx_lfc_en; + + for (k = 0; k < 8; k = k + 1) begin + if (cfg_quanta_clk_en && rx_pfc_ack[k]) begin + if (pfc_quanta_reg[k] > cfg_quanta_step) begin + pfc_quanta_next[k] = pfc_quanta_reg[k] - cfg_quanta_step; + end else begin + pfc_quanta_next[k] = 0; + end + end else begin + pfc_quanta_next[k] = pfc_quanta_reg[k]; + end + + pfc_req_next[k] = (pfc_quanta_reg[k] != 0) && rx_pfc_en[k] && cfg_rx_pfc_en; + end + + if (mcf_valid) begin + if (mcf_opcode == cfg_rx_lfc_opcode && cfg_rx_lfc_en) begin + stat_rx_lfc_pkt_next = 1'b1; + stat_rx_lfc_xon_next = {mcf_params[7:0], mcf_params[15:8]} == 0; + stat_rx_lfc_xoff_next = {mcf_params[7:0], mcf_params[15:8]} != 0; + lfc_quanta_next = {mcf_params[7:0], mcf_params[15:8], {QFB{1'b0}}}; + end else if (PFC_ENABLE && mcf_opcode == cfg_rx_pfc_opcode && cfg_rx_pfc_en) begin + stat_rx_pfc_pkt_next = 1'b1; + for (k = 0; k < 8; k = k + 1) begin + if (mcf_params[k+8]) begin + stat_rx_pfc_xon_next[k] = {mcf_params[16+(k*16)+0 +: 8], mcf_params[16+(k*16)+8 +: 8]} == 0; + stat_rx_pfc_xoff_next[k] = {mcf_params[16+(k*16)+0 +: 8], mcf_params[16+(k*16)+8 +: 8]} != 0; + pfc_quanta_next[k] = {mcf_params[16+(k*16)+0 +: 8], mcf_params[16+(k*16)+8 +: 8], {QFB{1'b0}}}; + end + end + end + end +end + +always @(posedge clk) begin + lfc_req_reg <= lfc_req_next; + pfc_req_reg <= pfc_req_next; + + lfc_quanta_reg <= lfc_quanta_next; + for (k = 0; k < 8; k = k + 1) begin + pfc_quanta_reg[k] <= pfc_quanta_next[k]; + end + + stat_rx_lfc_pkt_reg <= stat_rx_lfc_pkt_next; + stat_rx_lfc_xon_reg <= stat_rx_lfc_xon_next; + stat_rx_lfc_xoff_reg <= stat_rx_lfc_xoff_next; + stat_rx_pfc_pkt_reg <= stat_rx_pfc_pkt_next; + stat_rx_pfc_xon_reg <= stat_rx_pfc_xon_next; + stat_rx_pfc_xoff_reg <= stat_rx_pfc_xoff_next; + + if (rst) begin + lfc_req_reg <= 1'b0; + pfc_req_reg <= 8'd0; + lfc_quanta_reg <= 0; + for (k = 0; k < 8; k = k + 1) begin + pfc_quanta_reg[k] <= 0; + end + + stat_rx_lfc_pkt_reg <= 1'b0; + stat_rx_lfc_xon_reg <= 1'b0; + stat_rx_lfc_xoff_reg <= 1'b0; + stat_rx_pfc_pkt_reg <= 1'b0; + stat_rx_pfc_xon_reg <= 0; + stat_rx_pfc_xoff_reg <= 0; + end +end + +endmodule + +`resetall diff --git a/src/rvvi/mac_pause_ctrl_tx.sv b/src/rvvi/mac_pause_ctrl_tx.sv new file mode 100644 index 000000000..20566d888 --- /dev/null +++ b/src/rvvi/mac_pause_ctrl_tx.sv @@ -0,0 +1,312 @@ +/* + +Copyright (c) 2023 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * PFC and pause frame transmit handling + */ +module mac_pause_ctrl_tx # +( + parameter MCF_PARAMS_SIZE = 18, + parameter PFC_ENABLE = 1 +) +( + input wire clk, + input wire rst, + + /* + * MAC control frame interface + */ + output wire mcf_valid, + input wire mcf_ready, + output wire [47:0] mcf_eth_dst, + output wire [47:0] mcf_eth_src, + output wire [15:0] mcf_eth_type, + output wire [15:0] mcf_opcode, + output wire [MCF_PARAMS_SIZE*8-1:0] mcf_params, + + /* + * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) + */ + input wire tx_lfc_req, + input wire tx_lfc_resend, + + /* + * Priority Flow Control (PFC) (IEEE 802.3 annex 31D) + */ + input wire [7:0] tx_pfc_req, + input wire tx_pfc_resend, + + /* + * Configuration + */ + input wire [47:0] cfg_tx_lfc_eth_dst, + input wire [47:0] cfg_tx_lfc_eth_src, + input wire [15:0] cfg_tx_lfc_eth_type, + input wire [15:0] cfg_tx_lfc_opcode, + input wire cfg_tx_lfc_en, + input wire [15:0] cfg_tx_lfc_quanta, + input wire [15:0] cfg_tx_lfc_refresh, + input wire [47:0] cfg_tx_pfc_eth_dst, + input wire [47:0] cfg_tx_pfc_eth_src, + input wire [15:0] cfg_tx_pfc_eth_type, + input wire [15:0] cfg_tx_pfc_opcode, + input wire cfg_tx_pfc_en, + input wire [8*16-1:0] cfg_tx_pfc_quanta, + input wire [8*16-1:0] cfg_tx_pfc_refresh, + input wire [9:0] cfg_quanta_step, + input wire cfg_quanta_clk_en, + + /* + * Status + */ + output wire stat_tx_lfc_pkt, + output wire stat_tx_lfc_xon, + output wire stat_tx_lfc_xoff, + output wire stat_tx_lfc_paused, + output wire stat_tx_pfc_pkt, + output wire [7:0] stat_tx_pfc_xon, + output wire [7:0] stat_tx_pfc_xoff, + output wire [7:0] stat_tx_pfc_paused +); + +localparam QFB = 8; + +// check configuration +initial begin + if (MCF_PARAMS_SIZE < (PFC_ENABLE ? 18 : 2)) begin + $error("Error: MCF_PARAMS_SIZE too small for requested configuration (instance %m)"); + $finish; + end +end + +reg lfc_req_reg = 1'b0, lfc_req_next; +reg lfc_act_reg = 1'b0, lfc_act_next; +reg lfc_send_reg = 1'b0, lfc_send_next; +reg [7:0] pfc_req_reg = 8'd0, pfc_req_next; +reg [7:0] pfc_act_reg = 8'd0, pfc_act_next; +reg [7:0] pfc_en_reg = 8'd0, pfc_en_next; +reg pfc_send_reg = 1'b0, pfc_send_next; + +reg [16+QFB-1:0] lfc_refresh_reg = 0, lfc_refresh_next; +reg [16+QFB-1:0] pfc_refresh_reg[0:7], pfc_refresh_next[0:7]; + +reg stat_tx_lfc_pkt_reg = 1'b0, stat_tx_lfc_pkt_next; +reg stat_tx_lfc_xon_reg = 1'b0, stat_tx_lfc_xon_next; +reg stat_tx_lfc_xoff_reg = 1'b0, stat_tx_lfc_xoff_next; +reg stat_tx_pfc_pkt_reg = 1'b0, stat_tx_pfc_pkt_next; +reg [7:0] stat_tx_pfc_xon_reg = 0, stat_tx_pfc_xon_next; +reg [7:0] stat_tx_pfc_xoff_reg = 0, stat_tx_pfc_xoff_next; + +// MAC control interface +reg mcf_pfc_sel_reg = PFC_ENABLE != 0, mcf_pfc_sel_next; +reg mcf_valid_reg = 1'b0, mcf_valid_next; + +wire [2*8-1:0] mcf_lfc_params; +assign mcf_lfc_params[16*0 +: 16] = lfc_req_reg ? {cfg_tx_lfc_quanta[0 +: 8], cfg_tx_lfc_quanta[8 +: 8]} : 0; + +wire [18*8-1:0] mcf_pfc_params; +assign mcf_pfc_params[16*0 +: 16] = {pfc_en_reg, 8'd0}; +assign mcf_pfc_params[16*1 +: 16] = pfc_req_reg[0] ? {cfg_tx_pfc_quanta[16*0+0 +: 8], cfg_tx_pfc_quanta[16*0+8 +: 8]} : 0; +assign mcf_pfc_params[16*2 +: 16] = pfc_req_reg[1] ? {cfg_tx_pfc_quanta[16*1+0 +: 8], cfg_tx_pfc_quanta[16*1+8 +: 8]} : 0; +assign mcf_pfc_params[16*3 +: 16] = pfc_req_reg[2] ? {cfg_tx_pfc_quanta[16*2+0 +: 8], cfg_tx_pfc_quanta[16*2+8 +: 8]} : 0; +assign mcf_pfc_params[16*4 +: 16] = pfc_req_reg[3] ? {cfg_tx_pfc_quanta[16*3+0 +: 8], cfg_tx_pfc_quanta[16*3+8 +: 8]} : 0; +assign mcf_pfc_params[16*5 +: 16] = pfc_req_reg[4] ? {cfg_tx_pfc_quanta[16*4+0 +: 8], cfg_tx_pfc_quanta[16*4+8 +: 8]} : 0; +assign mcf_pfc_params[16*6 +: 16] = pfc_req_reg[5] ? {cfg_tx_pfc_quanta[16*5+0 +: 8], cfg_tx_pfc_quanta[16*5+8 +: 8]} : 0; +assign mcf_pfc_params[16*7 +: 16] = pfc_req_reg[6] ? {cfg_tx_pfc_quanta[16*6+0 +: 8], cfg_tx_pfc_quanta[16*6+8 +: 8]} : 0; +assign mcf_pfc_params[16*8 +: 16] = pfc_req_reg[7] ? {cfg_tx_pfc_quanta[16*7+0 +: 8], cfg_tx_pfc_quanta[16*7+8 +: 8]} : 0; + +assign mcf_valid = mcf_valid_reg; +assign mcf_eth_dst = (PFC_ENABLE && mcf_pfc_sel_reg) ? cfg_tx_pfc_eth_dst : cfg_tx_lfc_eth_dst; +assign mcf_eth_src = (PFC_ENABLE && mcf_pfc_sel_reg) ? cfg_tx_pfc_eth_src : cfg_tx_lfc_eth_src; +assign mcf_eth_type = (PFC_ENABLE && mcf_pfc_sel_reg) ? cfg_tx_pfc_eth_type : cfg_tx_lfc_eth_type; +assign mcf_opcode = (PFC_ENABLE && mcf_pfc_sel_reg) ? cfg_tx_pfc_opcode : cfg_tx_lfc_opcode; +assign mcf_params = (PFC_ENABLE && mcf_pfc_sel_reg) ? mcf_pfc_params : mcf_lfc_params; + +assign stat_tx_lfc_pkt = stat_tx_lfc_pkt_reg; +assign stat_tx_lfc_xon = stat_tx_lfc_xon_reg; +assign stat_tx_lfc_xoff = stat_tx_lfc_xoff_reg; +assign stat_tx_lfc_paused = lfc_req_reg; +assign stat_tx_pfc_pkt = stat_tx_pfc_pkt_reg; +assign stat_tx_pfc_xon = stat_tx_pfc_xon_reg; +assign stat_tx_pfc_xoff = stat_tx_pfc_xoff_reg; +assign stat_tx_pfc_paused = pfc_req_reg; + +integer k; + +initial begin + for (k = 0; k < 8; k = k + 1) begin + pfc_refresh_reg[k] = 0; + end +end + +always @* begin + lfc_req_next = lfc_req_reg; + lfc_act_next = lfc_act_reg; + lfc_send_next = lfc_send_reg | tx_lfc_resend; + pfc_req_next = pfc_req_reg; + pfc_act_next = pfc_act_reg; + pfc_en_next = pfc_en_reg; + pfc_send_next = pfc_send_reg | tx_pfc_resend; + + mcf_pfc_sel_next = mcf_pfc_sel_reg; + mcf_valid_next = mcf_valid_reg && !mcf_ready; + + stat_tx_lfc_pkt_next = 1'b0; + stat_tx_lfc_xon_next = 1'b0; + stat_tx_lfc_xoff_next = 1'b0; + stat_tx_pfc_pkt_next = 1'b0; + stat_tx_pfc_xon_next = 0; + stat_tx_pfc_xoff_next = 0; + + if (cfg_quanta_clk_en) begin + if (lfc_refresh_reg > cfg_quanta_step) begin + lfc_refresh_next = lfc_refresh_reg - cfg_quanta_step; + end else begin + lfc_refresh_next = 0; + if (lfc_req_reg) begin + lfc_send_next = 1'b1; + end + end + end else begin + lfc_refresh_next = lfc_refresh_reg; + end + + for (k = 0; k < 8; k = k + 1) begin + if (cfg_quanta_clk_en) begin + if (pfc_refresh_reg[k] > cfg_quanta_step) begin + pfc_refresh_next[k] = pfc_refresh_reg[k] - cfg_quanta_step; + end else begin + pfc_refresh_next[k] = 0; + if (pfc_req_reg[k]) begin + pfc_send_next = 1'b1; + end + end + end else begin + pfc_refresh_next[k] = pfc_refresh_reg[k]; + end + end + + if (cfg_tx_lfc_en) begin + if (!mcf_valid_reg) begin + if (lfc_req_reg != tx_lfc_req) begin + lfc_req_next = tx_lfc_req; + lfc_act_next = lfc_act_reg | tx_lfc_req; + lfc_send_next = 1'b1; + end + + if (lfc_send_reg && !(PFC_ENABLE && cfg_tx_pfc_en && pfc_send_reg)) begin + mcf_pfc_sel_next = 1'b0; + mcf_valid_next = lfc_act_reg; + lfc_act_next = lfc_req_reg; + lfc_refresh_next = lfc_req_reg ? {cfg_tx_lfc_refresh, {QFB{1'b0}}} : 0; + lfc_send_next = 1'b0; + + stat_tx_lfc_pkt_next = lfc_act_reg; + stat_tx_lfc_xon_next = lfc_act_reg && !lfc_req_reg; + stat_tx_lfc_xoff_next = lfc_act_reg && lfc_req_reg; + end + end + end + + if (PFC_ENABLE && cfg_tx_pfc_en) begin + if (!mcf_valid_reg) begin + if (pfc_req_reg != tx_pfc_req) begin + pfc_req_next = tx_pfc_req; + pfc_act_next = pfc_act_reg | tx_pfc_req; + pfc_send_next = 1'b1; + end + + if (pfc_send_reg) begin + mcf_pfc_sel_next = 1'b1; + mcf_valid_next = pfc_act_reg != 0; + pfc_en_next = pfc_act_reg; + pfc_act_next = pfc_req_reg; + for (k = 0; k < 8; k = k + 1) begin + pfc_refresh_next[k] = pfc_req_reg[k] ? {cfg_tx_pfc_refresh[16*k +: 16], {QFB{1'b0}}} : 0; + end + pfc_send_next = 1'b0; + + stat_tx_pfc_pkt_next = pfc_act_reg != 0; + stat_tx_pfc_xon_next = pfc_act_reg & ~pfc_req_reg; + stat_tx_pfc_xoff_next = pfc_act_reg & pfc_req_reg; + end + end + end +end + +always @(posedge clk) begin + lfc_req_reg <= lfc_req_next; + lfc_act_reg <= lfc_act_next; + lfc_send_reg <= lfc_send_next; + pfc_req_reg <= pfc_req_next; + pfc_act_reg <= pfc_act_next; + pfc_en_reg <= pfc_en_next; + pfc_send_reg <= pfc_send_next; + + mcf_pfc_sel_reg <= mcf_pfc_sel_next; + mcf_valid_reg <= mcf_valid_next; + + lfc_refresh_reg <= lfc_refresh_next; + for (k = 0; k < 8; k = k + 1) begin + pfc_refresh_reg[k] <= pfc_refresh_next[k]; + end + + stat_tx_lfc_pkt_reg <= stat_tx_lfc_pkt_next; + stat_tx_lfc_xon_reg <= stat_tx_lfc_xon_next; + stat_tx_lfc_xoff_reg <= stat_tx_lfc_xoff_next; + stat_tx_pfc_pkt_reg <= stat_tx_pfc_pkt_next; + stat_tx_pfc_xon_reg <= stat_tx_pfc_xon_next; + stat_tx_pfc_xoff_reg <= stat_tx_pfc_xoff_next; + + if (rst) begin + lfc_req_reg <= 1'b0; + lfc_act_reg <= 1'b0; + lfc_send_reg <= 1'b0; + pfc_req_reg <= 0; + pfc_act_reg <= 0; + pfc_send_reg <= 0; + mcf_pfc_sel_reg <= PFC_ENABLE != 0; + mcf_valid_reg <= 1'b0; + lfc_refresh_reg <= 0; + for (k = 0; k < 8; k = k + 1) begin + pfc_refresh_reg[k] <= 0; + end + + stat_tx_lfc_pkt_reg <= 1'b0; + stat_tx_lfc_xon_reg <= 1'b0; + stat_tx_lfc_xoff_reg <= 1'b0; + stat_tx_pfc_pkt_reg <= 1'b0; + stat_tx_pfc_xon_reg <= 0; + stat_tx_pfc_xoff_reg <= 0; + end +end + +endmodule + +`resetall diff --git a/src/rvvi/mii_phy_if.sv b/src/rvvi/mii_phy_if.sv new file mode 100644 index 000000000..340d7ad24 --- /dev/null +++ b/src/rvvi/mii_phy_if.sv @@ -0,0 +1,140 @@ +/* + +Copyright (c) 2019 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * MII PHY interface + */ +module mii_phy_if # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2" +) +( + input wire rst, + + /* + * MII interface to MAC + */ + output wire mac_mii_rx_clk, + output wire mac_mii_rx_rst, + output wire [3:0] mac_mii_rxd, + output wire mac_mii_rx_dv, + output wire mac_mii_rx_er, + output wire mac_mii_tx_clk, + output wire mac_mii_tx_rst, + input wire [3:0] mac_mii_txd, + input wire mac_mii_tx_en, + input wire mac_mii_tx_er, + + /* + * MII interface to PHY + */ + input wire phy_mii_rx_clk, + input wire [3:0] phy_mii_rxd, + input wire phy_mii_rx_dv, + input wire phy_mii_rx_er, + input wire phy_mii_tx_clk, + output wire [3:0] phy_mii_txd, + output wire phy_mii_tx_en, + output wire phy_mii_tx_er +); + +ssio_sdr_in # +( + .TARGET(TARGET), + .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), + .WIDTH(6) +) +rx_ssio_sdr_inst ( + .input_clk(phy_mii_rx_clk), + .input_d({phy_mii_rxd, phy_mii_rx_dv, phy_mii_rx_er}), + .output_clk(mac_mii_rx_clk), + .output_q({mac_mii_rxd, mac_mii_rx_dv, mac_mii_rx_er}) +); + +(* IOB = "TRUE" *) +reg [3:0] phy_mii_txd_reg = 4'd0; +(* IOB = "TRUE" *) +reg phy_mii_tx_en_reg = 1'b0, phy_mii_tx_er_reg = 1'b0; + +assign phy_mii_txd = phy_mii_txd_reg; +assign phy_mii_tx_en = phy_mii_tx_en_reg; +assign phy_mii_tx_er = phy_mii_tx_er_reg; + +always @(posedge mac_mii_tx_clk) begin + phy_mii_txd_reg <= mac_mii_txd; + phy_mii_tx_en_reg <= mac_mii_tx_en; + phy_mii_tx_er_reg <= mac_mii_tx_er; +end + +generate + +if (TARGET == "XILINX") begin + BUFG + mii_bufg_inst ( + .I(phy_mii_tx_clk), + .O(mac_mii_tx_clk) + ); +end else begin + assign mac_mii_tx_clk = phy_mii_tx_clk; +end + +endgenerate + +// reset sync +reg [3:0] tx_rst_reg = 4'hf; +assign mac_mii_tx_rst = tx_rst_reg[0]; + +always @(posedge mac_mii_tx_clk or posedge rst) begin + if (rst) begin + tx_rst_reg <= 4'hf; + end else begin + tx_rst_reg <= {1'b0, tx_rst_reg[3:1]}; + end +end + +reg [3:0] rx_rst_reg = 4'hf; +assign mac_mii_rx_rst = rx_rst_reg[0]; + +always @(posedge mac_mii_rx_clk or posedge rst) begin + if (rst) begin + rx_rst_reg <= 4'hf; + end else begin + rx_rst_reg <= {1'b0, rx_rst_reg[3:1]}; + end +end + +endmodule + +`resetall diff --git a/src/rvvi/ssio_ddr_in.sv b/src/rvvi/ssio_ddr_in.sv new file mode 100644 index 000000000..5060f4d27 --- /dev/null +++ b/src/rvvi/ssio_ddr_in.sv @@ -0,0 +1,150 @@ +/* + +Copyright (c) 2016-2018 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * Generic source synchronous DDR input + */ +module ssio_ddr_in # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // IODDR style ("IODDR", "IODDR2") + // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale + // Use IODDR2 for Spartan-6 + parameter IODDR_STYLE = "IODDR2", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-6, 7-series + // Use BUFG for Virtex-5, Spartan-6, Ultrascale + parameter CLOCK_INPUT_STYLE = "BUFG", + // Width of register in bits + parameter WIDTH = 1 +) +( + input wire input_clk, + + input wire [WIDTH-1:0] input_d, + + output wire output_clk, + + output wire [WIDTH-1:0] output_q1, + output wire [WIDTH-1:0] output_q2 +); + +wire clk_int; +wire clk_io; + +generate + +if (TARGET == "XILINX") begin + + // use Xilinx clocking primitives + + if (CLOCK_INPUT_STYLE == "BUFG") begin + + // buffer RX clock + BUFG + clk_bufg ( + .I(input_clk), + .O(clk_int) + ); + + // pass through RX clock to logic and input buffers + assign clk_io = clk_int; + assign output_clk = clk_int; + + end else if (CLOCK_INPUT_STYLE == "BUFR") begin + + assign clk_int = input_clk; + + // pass through RX clock to input buffers + BUFIO + clk_bufio ( + .I(clk_int), + .O(clk_io) + ); + + // pass through RX clock to logic + BUFR #( + .BUFR_DIVIDE("BYPASS") + ) + clk_bufr ( + .I(clk_int), + .O(output_clk), + .CE(1'b1), + .CLR(1'b0) + ); + + end else if (CLOCK_INPUT_STYLE == "BUFIO") begin + + assign clk_int = input_clk; + + // pass through RX clock to input buffers + BUFIO + clk_bufio ( + .I(clk_int), + .O(clk_io) + ); + + // pass through RX clock to MAC + BUFG + clk_bufg ( + .I(clk_int), + .O(output_clk) + ); + + end + +end else begin + + // pass through RX clock to input buffers + assign clk_io = input_clk; + + // pass through RX clock to logic + assign clk_int = input_clk; + assign output_clk = clk_int; + +end + +endgenerate + +iddr #( + .TARGET(TARGET), + .IODDR_STYLE(IODDR_STYLE), + .WIDTH(WIDTH) +) +data_iddr_inst ( + .clk(clk_io), + .d(input_d), + .q1(output_q1), + .q2(output_q2) +); + +endmodule + +`resetall diff --git a/src/rvvi/ssio_sdr_in.sv b/src/rvvi/ssio_sdr_in.sv new file mode 100644 index 000000000..351cadc1d --- /dev/null +++ b/src/rvvi/ssio_sdr_in.sv @@ -0,0 +1,166 @@ +/* + +Copyright (c) 2016-2018 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`default_nettype none + +/* + * Generic source synchronous SDR input + */ +module ssio_sdr_in # +( + // target ("SIM", "GENERIC", "XILINX", "ALTERA") + parameter TARGET = "GENERIC", + // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") + // Use BUFR for Virtex-5, Virtex-6, 7-series + // Use BUFG for Ultrascale + // Use BUFIO2 for Spartan-6 + parameter CLOCK_INPUT_STYLE = "BUFIO2", + // Width of register in bits + parameter WIDTH = 1 +) +( + input wire input_clk, + + input wire [WIDTH-1:0] input_d, + + output wire output_clk, + + output wire [WIDTH-1:0] output_q +); + +wire clk_int; +wire clk_io; + +generate + +if (TARGET == "XILINX") begin + + // use Xilinx clocking primitives + + if (CLOCK_INPUT_STYLE == "BUFG") begin + + // buffer RX clock + BUFG + clk_bufg ( + .I(input_clk), + .O(clk_int) + ); + + // pass through RX clock to logic and input buffers + assign clk_io = clk_int; + assign output_clk = clk_int; + + end else if (CLOCK_INPUT_STYLE == "BUFR") begin + + assign clk_int = input_clk; + + // pass through RX clock to input buffers + BUFIO + clk_bufio ( + .I(clk_int), + .O(clk_io) + ); + + // pass through RX clock to logic + BUFR #( + .BUFR_DIVIDE("BYPASS") + ) + clk_bufr ( + .I(clk_int), + .O(output_clk), + .CE(1'b1), + .CLR(1'b0) + ); + + end else if (CLOCK_INPUT_STYLE == "BUFIO") begin + + assign clk_int = input_clk; + + // pass through RX clock to input buffers + BUFIO + clk_bufio ( + .I(clk_int), + .O(clk_io) + ); + + // pass through RX clock to MAC + BUFG + clk_bufg ( + .I(clk_int), + .O(output_clk) + ); + + end else if (CLOCK_INPUT_STYLE == "BUFIO2") begin + + // pass through RX clock to input buffers + BUFIO2 #( + .DIVIDE(1), + .DIVIDE_BYPASS("TRUE"), + .I_INVERT("FALSE"), + .USE_DOUBLER("FALSE") + ) + clk_bufio ( + .I(input_clk), + .DIVCLK(clk_int), + .IOCLK(clk_io), + .SERDESSTROBE() + ); + + // pass through RX clock to MAC + BUFG + clk_bufg ( + .I(clk_int), + .O(output_clk) + ); + + end + +end else begin + + // pass through RX clock to input buffers + assign clk_io = input_clk; + + // pass through RX clock to logic + assign clk_int = input_clk; + assign output_clk = clk_int; + +end + +endgenerate + +(* IOB = "TRUE" *) +reg [WIDTH-1:0] output_q_reg = {WIDTH{1'b0}}; + +assign output_q = output_q_reg; + +always @(posedge clk_io) begin + output_q_reg <= input_d; +end + +endmodule + +`resetall From 6a4c8667df32fbe0bc7260edd6679e788bf832a6 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 30 May 2024 16:43:25 -0500 Subject: [PATCH 20/95] Added new signals to ILA to debug the RVVI tracer. The tracer appears to be stuck and the CPU is never getting out of (into reset). --- fpga/constraints/small-debug.xdc | 25 +++++++++++++++++++++++++ fpga/src/fpgaTopArtyA7.sv | 10 +++++----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/fpga/constraints/small-debug.xdc b/fpga/constraints/small-debug.xdc index b73581ab7..62fcbe545 100644 --- a/fpga/constraints/small-debug.xdc +++ b/fpga/constraints/small-debug.xdc @@ -58,6 +58,31 @@ set_property port_width 64 [get_debug_ports u_ila_0/probe7] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7] connect_debug_port u_ila_0/probe7 [get_nets [list {wallypipelinedsoc/core/lsu/WriteDataM[0]} {wallypipelinedsoc/core/lsu/WriteDataM[1]} {wallypipelinedsoc/core/lsu/WriteDataM[2]} {wallypipelinedsoc/core/lsu/WriteDataM[3]} {wallypipelinedsoc/core/lsu/WriteDataM[4]} {wallypipelinedsoc/core/lsu/WriteDataM[5]} {wallypipelinedsoc/core/lsu/WriteDataM[6]} {wallypipelinedsoc/core/lsu/WriteDataM[7]} {wallypipelinedsoc/core/lsu/WriteDataM[8]} {wallypipelinedsoc/core/lsu/WriteDataM[9]} {wallypipelinedsoc/core/lsu/WriteDataM[10]} {wallypipelinedsoc/core/lsu/WriteDataM[11]} {wallypipelinedsoc/core/lsu/WriteDataM[12]} {wallypipelinedsoc/core/lsu/WriteDataM[13]} {wallypipelinedsoc/core/lsu/WriteDataM[14]} {wallypipelinedsoc/core/lsu/WriteDataM[15]} {wallypipelinedsoc/core/lsu/WriteDataM[16]} {wallypipelinedsoc/core/lsu/WriteDataM[17]} {wallypipelinedsoc/core/lsu/WriteDataM[18]} {wallypipelinedsoc/core/lsu/WriteDataM[19]} {wallypipelinedsoc/core/lsu/WriteDataM[20]} {wallypipelinedsoc/core/lsu/WriteDataM[21]} {wallypipelinedsoc/core/lsu/WriteDataM[22]} {wallypipelinedsoc/core/lsu/WriteDataM[23]} {wallypipelinedsoc/core/lsu/WriteDataM[24]} {wallypipelinedsoc/core/lsu/WriteDataM[25]} {wallypipelinedsoc/core/lsu/WriteDataM[26]} {wallypipelinedsoc/core/lsu/WriteDataM[27]} {wallypipelinedsoc/core/lsu/WriteDataM[28]} {wallypipelinedsoc/core/lsu/WriteDataM[29]} {wallypipelinedsoc/core/lsu/WriteDataM[30]} {wallypipelinedsoc/core/lsu/WriteDataM[31]} {wallypipelinedsoc/core/lsu/WriteDataM[32]} {wallypipelinedsoc/core/lsu/WriteDataM[33]} {wallypipelinedsoc/core/lsu/WriteDataM[34]} {wallypipelinedsoc/core/lsu/WriteDataM[35]} {wallypipelinedsoc/core/lsu/WriteDataM[36]} {wallypipelinedsoc/core/lsu/WriteDataM[37]} {wallypipelinedsoc/core/lsu/WriteDataM[38]} {wallypipelinedsoc/core/lsu/WriteDataM[39]} {wallypipelinedsoc/core/lsu/WriteDataM[40]} {wallypipelinedsoc/core/lsu/WriteDataM[41]} {wallypipelinedsoc/core/lsu/WriteDataM[42]} {wallypipelinedsoc/core/lsu/WriteDataM[43]} {wallypipelinedsoc/core/lsu/WriteDataM[44]} {wallypipelinedsoc/core/lsu/WriteDataM[45]} {wallypipelinedsoc/core/lsu/WriteDataM[46]} {wallypipelinedsoc/core/lsu/WriteDataM[47]} {wallypipelinedsoc/core/lsu/WriteDataM[48]} {wallypipelinedsoc/core/lsu/WriteDataM[49]} {wallypipelinedsoc/core/lsu/WriteDataM[50]} {wallypipelinedsoc/core/lsu/WriteDataM[51]} {wallypipelinedsoc/core/lsu/WriteDataM[52]} {wallypipelinedsoc/core/lsu/WriteDataM[53]} {wallypipelinedsoc/core/lsu/WriteDataM[54]} {wallypipelinedsoc/core/lsu/WriteDataM[55]} {wallypipelinedsoc/core/lsu/WriteDataM[56]} {wallypipelinedsoc/core/lsu/WriteDataM[57]} {wallypipelinedsoc/core/lsu/WriteDataM[58]} {wallypipelinedsoc/core/lsu/WriteDataM[59]} {wallypipelinedsoc/core/lsu/WriteDataM[60]} {wallypipelinedsoc/core/lsu/WriteDataM[61]} {wallypipelinedsoc/core/lsu/WriteDataM[62]} {wallypipelinedsoc/core/lsu/WriteDataM[63]} ]] +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe8] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe8] +connect_debug_port u_ila_0/probe8 [get_nets [list {RVVIStall}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe9] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe9] +connect_debug_port u_ila_0/probe9 [get_nets [list {valid}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe10] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe10] +connect_debug_port u_ila_0/probe10 [get_nets [list {RvviAxiWready}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe11] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe11] +connect_debug_port u_ila_0/probe11 [get_nets [list {RvviAxiWvalid}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe12] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe12] +connect_debug_port u_ila_0/probe12 [get_nets [list {bus_struct_reset}]] + # the debug hub has issues with the clocks from the mmcm so lets give up an connect to the 100Mhz input clock. #connect_debug_port dbg_hub/clk [get_nets default_100mhz_clk] connect_debug_port dbg_hub/clk [get_nets CPUCLK] diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index 295c62c38..8a6b08f47 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -78,7 +78,7 @@ module fpgaTop wire CPUCLK; wire c0_ddr4_ui_clk_sync_rst; - wire bus_struct_reset; +(* mark_debug = "true" *) wire bus_struct_reset; wire peripheral_reset; wire interconnect_aresetn; wire peripheral_aresetn; @@ -444,7 +444,7 @@ module fpgaTop wire [11:0] device_temp; wire mmcm1_locked; - logic RVVIStall; +(* mark_debug = "true" *) logic RVVIStall; assign GPIOIN = {28'b0, GPI}; assign GPO = GPIOOUT[4:0]; @@ -1116,7 +1116,7 @@ module fpgaTop .device_temp(device_temp)); localparam MAX_CSRS = 3; - logic valid; +(* mark_debug = "true" *) logic valid; logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; rvvisynth #(P, MAX_CSRS) rvvisynth(.clk(CPUCLK), .reset(bus_struct_reset), .valid, .rvvi); @@ -1125,8 +1125,8 @@ module fpgaTop logic [31:0] RvviAxiWdata; logic [3:0] RvviAxiWstrb; logic RvviAxiWlast; - logic RvviAxiWvalid; - logic RvviAxiWready; +(* mark_debug = "true" *) logic RvviAxiWvalid; +(* mark_debug = "true" *) logic RvviAxiWready; logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; From 1df3e5239a56f8639b1539b7288f87e2384086af Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 30 May 2024 17:57:28 -0500 Subject: [PATCH 21/95] This is great. The FPGA is able to send ethernet frames consisting of the RVVI data to the host computer. wireshark is able to capture the frames and they match the expected data! --- src/rvvi/packetizer.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 93390d03b..1040e8593 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -71,7 +71,8 @@ module packetizer import cvw::*; #(parameter cvw_t P, case(CurrState) STATE_RDY: if (TransReady & valid) NextState = STATE_TRANS; else if(~TransReady & valid) NextState = STATE_WAIT; - STATE_WAIT: if(TransReady) NextState = STATE_TRANS; + else NextState = STATE_RDY; + STATE_WAIT: if(TransReady) NextState = STATE_TRANS; else NextState = STATE_WAIT; STATE_TRANS: if(BurstDone) NextState = STATE_RDY; else NextState = STATE_TRANS; From 0dccc6051d14ec5ac01c0e75ff78e1d0f5032db7 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 31 May 2024 13:55:25 -0500 Subject: [PATCH 22/95] draft of receiving code to unpack the ethernet frames into rvvi. --- src/rvvi/packetizer.sv | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 1040e8593..e1685192c 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -53,7 +53,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, logic WordCountEnable; logic [47:0] SrcMac, DstMac; logic [31:0] Tag; - logic [15:0] Length; + logic [15:0] EthType; logic [TotalFrameLengthBits-1:0] TotalFrame; logic [31:0] TotalFrameWords [TotalFrameLengthBytes/4-1:0]; @@ -99,13 +99,13 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign TotalFrameWords[index] = TotalFrame[(index*32)+32-1 : (index*32)]; end - assign TotalFrame = {rvviDelay, Length, Tag, DstMac, SrcMac}; + assign TotalFrame = {rvviDelay, EthType, Tag, DstMac, SrcMac}; // *** fix me later assign SrcMac = 48'h8F54_0000_1654; // made something up assign DstMac = 48'h4502_1111_6843; assign Tag = '0; - assign Length = BytesInFrame + 16'd6 + 16'd6 + 16'd4 + 16'd2; + assign Length = 16'h0801; assign RvviAxiWdata = TotalFrameWords[WordCount]; assign RvviAxiWstrb = '1; From e05ebc30b85460745a9a28f720c1418f87ca8e25 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 31 May 2024 16:48:41 -0500 Subject: [PATCH 23/95] Almost worked out the bugs in packetizer. --- src/rvvi/packetizer.sv | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index e1685192c..4a742f7da 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -52,8 +52,8 @@ module packetizer import cvw::*; #(parameter cvw_t P, logic WordCountReset; logic WordCountEnable; logic [47:0] SrcMac, DstMac; - logic [31:0] Tag; logic [15:0] EthType; + logic [31:0] Tag; logic [TotalFrameLengthBits-1:0] TotalFrame; logic [31:0] TotalFrameWords [TotalFrameLengthBytes/4-1:0]; @@ -91,7 +91,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, counter #(10) WordCounter(m_axi_aclk, WordCountReset, WordCountEnable, WordCount); // *** BUG BytesInFrame will eventually depend on the length of the data stored into the ethernet frame // for now this will be exactly 608 bits (76 bytes, 19 words) - assign BytesInFrame = 12'd76; + assign BytesInFrame = 12'd2 + 12'd76 + 12'd6 + 12'd6 + 12'd2; assign BurstDone = WordCount == (BytesInFrame[11:2] - 1'b1); genvar index; @@ -99,13 +99,13 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign TotalFrameWords[index] = TotalFrame[(index*32)+32-1 : (index*32)]; end - assign TotalFrame = {rvviDelay, EthType, Tag, DstMac, SrcMac}; + assign TotalFrame = {16'b0, rvviDelay, 4'b0, BytesInFrame, DstMac, SrcMac}; // *** fix me later - assign SrcMac = 48'h8F54_0000_1654; // made something up - assign DstMac = 48'h4502_1111_6843; - assign Tag = '0; - assign Length = 16'h0801; + assign DstMac = 48'h8F54_0000_1654; // made something up + assign SrcMac = 48'h4502_1111_6843; + assign Tag = 32'b0; + assign EthType = 16'h0801; assign RvviAxiWdata = TotalFrameWords[WordCount]; assign RvviAxiWstrb = '1; From a830bd57f0b58ba8bc98af16e6a64f03bf9e5c8c Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 31 May 2024 17:46:43 -0500 Subject: [PATCH 24/95] Have to reverse the byte order for ethernet frame length. --- src/rvvi/packetizer.sv | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 4a742f7da..48db68f76 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -54,6 +54,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, logic [47:0] SrcMac, DstMac; logic [15:0] EthType; logic [31:0] Tag; + logic [15:0] Length; logic [TotalFrameLengthBits-1:0] TotalFrame; logic [31:0] TotalFrameWords [TotalFrameLengthBytes/4-1:0]; @@ -99,7 +100,8 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign TotalFrameWords[index] = TotalFrame[(index*32)+32-1 : (index*32)]; end - assign TotalFrame = {16'b0, rvviDelay, 4'b0, BytesInFrame, DstMac, SrcMac}; + assign Length = {BytesInFrame[7:0], 4'b0, BytesInFrame[11:8]}; + assign TotalFrame = {16'b0, rvviDelay, Length, DstMac, SrcMac}; // *** fix me later assign DstMac = 48'h8F54_0000_1654; // made something up From dc904cdbbb9a99692667e2a6114e5b819c1ee1d2 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 3 Jun 2024 18:10:25 -0500 Subject: [PATCH 25/95] The ethernet frame is mostly formatted correctly. Just need to reverse the byte order in the Ethernet length/type field. --- src/rvvi/packetizer.sv | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 48db68f76..4a742f7da 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -54,7 +54,6 @@ module packetizer import cvw::*; #(parameter cvw_t P, logic [47:0] SrcMac, DstMac; logic [15:0] EthType; logic [31:0] Tag; - logic [15:0] Length; logic [TotalFrameLengthBits-1:0] TotalFrame; logic [31:0] TotalFrameWords [TotalFrameLengthBytes/4-1:0]; @@ -100,8 +99,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign TotalFrameWords[index] = TotalFrame[(index*32)+32-1 : (index*32)]; end - assign Length = {BytesInFrame[7:0], 4'b0, BytesInFrame[11:8]}; - assign TotalFrame = {16'b0, rvviDelay, Length, DstMac, SrcMac}; + assign TotalFrame = {16'b0, rvviDelay, 4'b0, BytesInFrame, DstMac, SrcMac}; // *** fix me later assign DstMac = 48'h8F54_0000_1654; // made something up From 80f98b3223ac54b1199ef4ecf2de68427407508a Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 4 Jun 2024 10:20:51 -0500 Subject: [PATCH 26/95] now have a working ethernet daemon to collect frames and partially decode into RVVI. --- fpga/rvvidaemon/rvvidaemon.c | 145 +++++++++++++++++++++++++++++++++++ src/rvvi/packetizer.sv | 7 +- 2 files changed, 149 insertions(+), 3 deletions(-) create mode 100644 fpga/rvvidaemon/rvvidaemon.c diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c new file mode 100644 index 000000000..b4be770ca --- /dev/null +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -0,0 +1,145 @@ +/////////////////////////////////////////// +// rvvi daemon +// +// Written: Rose Thomposn ross1728@gmail.com +// Created: 31 May 2024 +// Modified: 31 May 2024 +// +// Purpose: Converts raw socket into rvvi interface to connect into ImperasDV +// +// Documentation: +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// https://github.com/openhwgroup/cvw +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define DEST_MAC0 0x43 +#define DEST_MAC1 0x68 +#define DEST_MAC2 0x11 +#define DEST_MAC3 0x11 +#define DEST_MAC4 0x02 +#define DEST_MAC5 0x45 + +#define SRC_MAC0 0x54 +#define SRC_MAC1 0x16 +#define SRC_MAC2 0x00 +#define SRC_MAC3 0x00 +#define SRC_MAC4 0x54 +#define SRC_MAC5 0x8F + +#define BUF_SIZ 1024 + +//#define ETHER_TYPE 0x0801 // The type defined in packetizer.sv +#define ETHER_TYPE 0x5c00 // The type defined in packetizer.sv +//#define ETHER_TYPE 0x0000 // The type defined in packetizer.sv +#define DEFAULT_IF "eno1" + +void DecodeRVVI(uint8_t *payload, uint64_t * PC, uint32_t *insn); + +int main(int argc, char **argv){ + + if(argc != 2){ + printf("Wrong number of arguments.\n"); + printf("rvvidaemon \n"); + return -1; + } + + char sender[INET6_ADDRSTRLEN]; + int sockfd; + struct ifreq if_idx; + uint8_t buf[BUF_SIZ]; + int sockopt; + struct ifreq ifopts; /* set promiscuous mode */ + struct ether_header *eh = (struct ether_header *) buf; + ssize_t headerbytes, numbytes, payloadbytes; + + /* Open RAW socket to receive frames */ + if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) { + perror("socket"); + } + printf("Here 0\n"); + + /* Set interface to promiscuous mode - do we need to do this every time? */ + strncpy(ifopts.ifr_name, argv[1], IFNAMSIZ-1); + ioctl(sockfd, SIOCGIFFLAGS, &ifopts); + printf("Here 1\n"); + ifopts.ifr_flags |= IFF_PROMISC; + ioctl(sockfd, SIOCSIFFLAGS, &ifopts); + printf("Here 2\n"); + + /* Allow the socket to be reused - incase connection is closed prematurely */ + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) { + perror("setsockopt"); + close(sockfd); + exit(EXIT_FAILURE); + } + printf("Here 3\n"); + + /* Bind to device */ + if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, argv[1], IFNAMSIZ-1) == -1) { + perror("SO_BINDTODEVICE"); + close(sockfd); + exit(EXIT_FAILURE); + } + printf("Here 4\n"); + + while(1) { + printf("listener: Waiting to recvfrom...\n"); + numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL); + headerbytes = (sizeof(struct ether_header)); + payloadbytes = numbytes - headerbytes; + printf("listener: got frame %lu bytes\n", numbytes); + printf("payload size: %lu bytes\n", payloadbytes); + if (eh->ether_dhost[0] == DEST_MAC0 && + eh->ether_dhost[1] == DEST_MAC1 && + eh->ether_dhost[2] == DEST_MAC2 && + eh->ether_dhost[3] == DEST_MAC3 && + eh->ether_dhost[4] == DEST_MAC4 && + eh->ether_dhost[5] == DEST_MAC5) { + printf("Correct destination MAC address\n"); + uint64_t PC; + uint32_t insn; + DecodeRVVI(buf + headerbytes, &PC, &insn); + printf("PC = %lx, insn = %x\n", PC, insn); + } + } + + close(sockfd); + + return 0; +} + +void DecodeRVVI(uint8_t *payload, uint64_t * PC, uint32_t *insn){ + // you know this actually easiser in assembly. :( + *PC = *((uint64_t *) payload); + *insn = *((uint32_t *) (payload + 8)); +} diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 4a742f7da..a1f62ba9f 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -52,7 +52,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, logic WordCountReset; logic WordCountEnable; logic [47:0] SrcMac, DstMac; - logic [15:0] EthType; + logic [15:0] EthType, Length; logic [31:0] Tag; logic [TotalFrameLengthBits-1:0] TotalFrame; logic [31:0] TotalFrameWords [TotalFrameLengthBytes/4-1:0]; @@ -90,7 +90,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, counter #(10) WordCounter(m_axi_aclk, WordCountReset, WordCountEnable, WordCount); // *** BUG BytesInFrame will eventually depend on the length of the data stored into the ethernet frame - // for now this will be exactly 608 bits (76 bytes, 19 words) + // for now this will be exactly 608 bits (76 bytes, 19 words) + the ethernet frame overhead and 2-byte padding = 92-bytes assign BytesInFrame = 12'd2 + 12'd76 + 12'd6 + 12'd6 + 12'd2; assign BurstDone = WordCount == (BytesInFrame[11:2] - 1'b1); @@ -99,7 +99,8 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign TotalFrameWords[index] = TotalFrame[(index*32)+32-1 : (index*32)]; end - assign TotalFrame = {16'b0, rvviDelay, 4'b0, BytesInFrame, DstMac, SrcMac}; + assign Length = {4'b0, BytesInFrame}; + assign TotalFrame = {16'b0, rvviDelay, Length[7:0], Length[15:8], DstMac, SrcMac}; // *** fix me later assign DstMac = 48'h8F54_0000_1654; // made something up From fc62f804071d2a3ba49e0d39df1bd537d209359e Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 4 Jun 2024 11:31:05 -0500 Subject: [PATCH 27/95] Closer to fully working hardware tracer. --- src/rvvi/packetizer.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index a1f62ba9f..5b16615a6 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -100,13 +100,13 @@ module packetizer import cvw::*; #(parameter cvw_t P, end assign Length = {4'b0, BytesInFrame}; - assign TotalFrame = {16'b0, rvviDelay, Length[7:0], Length[15:8], DstMac, SrcMac}; + assign TotalFrame = {16'b0, rvviDelay, EthType, DstMac, SrcMac}; // *** fix me later assign DstMac = 48'h8F54_0000_1654; // made something up assign SrcMac = 48'h4502_1111_6843; assign Tag = 32'b0; - assign EthType = 16'h0801; + assign EthType = 16'h005c; assign RvviAxiWdata = TotalFrameWords[WordCount]; assign RvviAxiWstrb = '1; From 08ff88f428b1b2a6c90406b66e2fdefd76467f8c Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 4 Jun 2024 11:47:46 -0500 Subject: [PATCH 28/95] On the way towards complete reconstruction of the RVVI trace. --- fpga/rvvidaemon/rvvidaemon.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index b4be770ca..13088a478 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -63,6 +63,20 @@ //#define ETHER_TYPE 0x0000 // The type defined in packetizer.sv #define DEFAULT_IF "eno1" + +typedef struct { + uint64_t PC; + uint32_t insn; + uint64_t Mcycle; + uint64_t Minstret; + uint8_t Trap : 1; + uint8_t PrivilegeMode : 2; + uint8_t GPREn : 1; + uint8_t FPREn : 1; + uint16_t CSRCount : 12; +} RequiredRVVI_t; + + void DecodeRVVI(uint8_t *payload, uint64_t * PC, uint32_t *insn); int main(int argc, char **argv){ @@ -140,6 +154,7 @@ int main(int argc, char **argv){ void DecodeRVVI(uint8_t *payload, uint64_t * PC, uint32_t *insn){ // you know this actually easiser in assembly. :( - *PC = *((uint64_t *) payload); - *insn = *((uint32_t *) (payload + 8)); + RequiredRVVI_t *RequiredFields = (RequiredRVVI_t *) payload; + *PC = RequiredFields->PC; + *insn = RequiredFields->insn; } From 07d66c246c97542a3249dc8240e1813804881cb2 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 4 Jun 2024 11:59:17 -0500 Subject: [PATCH 29/95] Update. --- fpga/rvvidaemon/rvvidaemon.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 13088a478..b3e5f97ea 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -157,4 +157,6 @@ void DecodeRVVI(uint8_t *payload, uint64_t * PC, uint32_t *insn){ RequiredRVVI_t *RequiredFields = (RequiredRVVI_t *) payload; *PC = RequiredFields->PC; *insn = RequiredFields->insn; + if(RequiredFields->GPREn) + printf("Wrote a reg\n"); } From f0ed7807456e56cd58ac8c70c3997b4247bf2134 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 4 Jun 2024 15:11:03 -0500 Subject: [PATCH 30/95] progress. --- fpga/rvvidaemon/rvvidaemon.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index b3e5f97ea..7154b2410 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -74,8 +74,20 @@ typedef struct { uint8_t GPREn : 1; uint8_t FPREn : 1; uint16_t CSRCount : 12; -} RequiredRVVI_t; - +} RequiredRVVI_t; // total size is 241 bits or 30.25 bytes + +typedef struct { + uint8_t fill : 1; // *** depends on the size of the RequiredRVVI_t + uint8_t RegAddress : 5; + uint64_t RegValue; +} FirstReg_t; + +typedef struct { + uint8_t fill : 6; // *** depends on the size of the RequiredRVVI_t and FirstReg_t + uint8_t RegAddress : 5; + uint64_t RegValue; +} SecondReg_t; + void DecodeRVVI(uint8_t *payload, uint64_t * PC, uint32_t *insn); @@ -127,23 +139,22 @@ int main(int argc, char **argv){ printf("Here 4\n"); while(1) { - printf("listener: Waiting to recvfrom...\n"); + //printf("listener: Waiting to recvfrom...\n"); numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL); headerbytes = (sizeof(struct ether_header)); payloadbytes = numbytes - headerbytes; - printf("listener: got frame %lu bytes\n", numbytes); - printf("payload size: %lu bytes\n", payloadbytes); + //printf("listener: got frame %lu bytes\n", numbytes); + //printf("payload size: %lu bytes\n", payloadbytes); if (eh->ether_dhost[0] == DEST_MAC0 && eh->ether_dhost[1] == DEST_MAC1 && eh->ether_dhost[2] == DEST_MAC2 && eh->ether_dhost[3] == DEST_MAC3 && eh->ether_dhost[4] == DEST_MAC4 && eh->ether_dhost[5] == DEST_MAC5) { - printf("Correct destination MAC address\n"); + //printf("Correct destination MAC address\n"); uint64_t PC; uint32_t insn; DecodeRVVI(buf + headerbytes, &PC, &insn); - printf("PC = %lx, insn = %x\n", PC, insn); } } @@ -155,8 +166,13 @@ int main(int argc, char **argv){ void DecodeRVVI(uint8_t *payload, uint64_t * PC, uint32_t *insn){ // you know this actually easiser in assembly. :( RequiredRVVI_t *RequiredFields = (RequiredRVVI_t *) payload; + FirstReg_t FirstReg; + SecondReg_t SecondReg; *PC = RequiredFields->PC; *insn = RequiredFields->insn; - if(RequiredFields->GPREn) + printf("PC = %lx, insn = %x\n", *PC, *insn); + if(RequiredFields->GPREn){ + FirstReg = *(FirstReg_t *) (payload + sizeof(RequiredRVVI_t) - 1); printf("Wrote a reg\n"); + } } From 72c1374d9c826882a0046495b2bcbbc80e3d02e1 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 4 Jun 2024 15:11:57 -0500 Subject: [PATCH 31/95] Minor code cleanup. --- fpga/rvvidaemon/rvvidaemon.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 7154b2410..9d08883d0 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -99,9 +99,7 @@ int main(int argc, char **argv){ return -1; } - char sender[INET6_ADDRSTRLEN]; int sockfd; - struct ifreq if_idx; uint8_t buf[BUF_SIZ]; int sockopt; struct ifreq ifopts; /* set promiscuous mode */ From e16cf9d7392fb6ba47e9915ba63d0c4692d8ab35 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 10 Jun 2024 16:56:53 -0700 Subject: [PATCH 32/95] Added Makefile to compile rvvidaemon --- fpga/rvvidaemon/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 fpga/rvvidaemon/Makefile diff --git a/fpga/rvvidaemon/Makefile b/fpga/rvvidaemon/Makefile new file mode 100644 index 000000000..c1d1d5a1c --- /dev/null +++ b/fpga/rvvidaemon/Makefile @@ -0,0 +1,10 @@ +all: rvvidaemon + +rvvidaemon: rvvidaemon.o + gcc $^ -o rvvidaemon + +%.o:%.c + gcc -c $^ -o $@ + +clean: + rm *.o rvvidaemon From 49912589f537e33bc67d5f3267f41c0fefb48c0e Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 10 Jun 2024 17:57:24 -0700 Subject: [PATCH 33/95] Added rvviApi.h to rvvidaemon. --- fpga/rvvidaemon/rvvidaemon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 9d08883d0..48e83a6a7 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -40,6 +40,7 @@ #include #include #include +#include "rvviApi.h" // *** bug fix me when this file gets included into the correct directory. #define DEST_MAC0 0x43 From 3d9f796f21dd7a3ae16544b596128558c1cae2b8 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 11 Jun 2024 14:36:34 -0700 Subject: [PATCH 34/95] Better parsing of rvvi. --- fpga/rvvidaemon/rvvidaemon.c | 91 +++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 17 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 48e83a6a7..24732f181 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -75,22 +75,15 @@ typedef struct { uint8_t GPREn : 1; uint8_t FPREn : 1; uint16_t CSRCount : 12; -} RequiredRVVI_t; // total size is 241 bits or 30.25 bytes +} RequiredRVVI_t; // total size is 241 bits or 30.125 bytes typedef struct { - uint8_t fill : 1; // *** depends on the size of the RequiredRVVI_t uint8_t RegAddress : 5; uint64_t RegValue; -} FirstReg_t; - -typedef struct { - uint8_t fill : 6; // *** depends on the size of the RequiredRVVI_t and FirstReg_t - uint8_t RegAddress : 5; - uint64_t RegValue; -} SecondReg_t; - +} Reg_t; void DecodeRVVI(uint8_t *payload, uint64_t * PC, uint32_t *insn); +void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length); int main(int argc, char **argv){ @@ -164,14 +157,78 @@ int main(int argc, char **argv){ void DecodeRVVI(uint8_t *payload, uint64_t * PC, uint32_t *insn){ // you know this actually easiser in assembly. :( + uint8_t buf2[BUF_SIZ], buf3[BUF_SIZ]; + //int PayloadSize = sizeof(RequiredRVVI_t) - 1; + int PayloadSize = 30; + int Buf2Size = BUF_SIZ - PayloadSize; RequiredRVVI_t *RequiredFields = (RequiredRVVI_t *) payload; - FirstReg_t FirstReg; - SecondReg_t SecondReg; - *PC = RequiredFields->PC; - *insn = RequiredFields->insn; - printf("PC = %lx, insn = %x\n", *PC, *insn); + uint8_t *CurrentBytePointer = payload + PayloadSize; + Reg_t *FirstReg; + Reg_t SecondReg; + uint64_t Mcycle, Minstret; + // unforunately the struct appoarch does not work?!? + //*PC = RequiredFields->PC; + *PC = * (uint64_t *) payload; + //*insn = RequiredFields->insn; + payload += 8; + *insn = * (uint32_t *) payload; + // Mcycle = RequiredFields->Mcycle; + payload += 4; + Mcycle = * (uint64_t *) payload; + payload += 8; + Minstret = * (uint64_t *) payload; + //Minstret = RequiredFields->Minstret; + payload += 8; + // the next 4 bytes contain CSRCount (12), FPRWen(1), GPRWen(1), PrivilegeMode(2), Trap(1) + uint32_t RequiredFlags; + RequiredFlags = * (uint32_t *) payload; + uint8_t Trap, PrivilegeMode, GPRWen, FPRWen; + uint16_t CSRCount; + + Trap = RequiredFlags & 0x1; + PrivilegeMode = (RequiredFlags >> 1) & 0x3; + GPRWen = (RequiredFlags >> 3) & 0x1; + FPRWen = (RequiredFlags >> 4) & 0x1; + CSRCount = (RequiredFlags >> 5) & 0xFFF; + + int bits; + + printf("PC = %lx, insn = %x, Mcycle = %lx, Minstret = %lx, Trap = %hhx, PrivilegeMode = %hhx, GPRWen = %hhx, FPRWen = %hhx, CSRCount == %hx\n", *PC, *insn, Mcycle, Minstret, Trap, PrivilegeMode, GPRWen, FPRWen, CSRCount); if(RequiredFields->GPREn){ - FirstReg = *(FirstReg_t *) (payload + sizeof(RequiredRVVI_t) - 1); - printf("Wrote a reg\n"); + BitShiftArray(buf2, CurrentBytePointer, 1, Buf2Size); + FirstReg = (Reg_t *) buf2; + printf("Wrote reg %d = %lx\n", FirstReg->RegAddress, FirstReg->RegValue); } + printf("!!!!!\n\n"); +} + +void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length){ + // always shift right by ShiftAmount (0 to 7 bit positions). + // *** this implemenation is very inefficient. improve later. + if(ShiftAmount < 0 || ShiftAmount > 7) return; + /* Read the first source byte + Read the second source byte + Right Shift byte 1 by ShiftAmount + Right Rotate byte 2 by ShiftAmount + Mask byte 2 by ~(2^ShiftAmount -1) + OR together the two bytes to form the final next byte + + repeat this for each byte + On the last byte we don't do the last steps + */ + int Index; + for(Index = 0; Index < Length - 1; Index++){ + uint8_t byte1 = src[Index]; + uint8_t byte2 = src[Index+1]; + byte1 = byte1 >> ShiftAmount; + uint8_t byte2rot = byte2 >> ShiftAmount | byte2 << (unsigned) (8 - ShiftAmount); + byte2rot = byte2rot & ~(2^ShiftAmount - 1); + uint8_t byte1final = byte2rot | byte1; + dst[Index] = byte1final; + } + // fence post + // For last one there is only one source byte + uint8_t byte1 = src[Length-1]; + byte1 = byte1 >> ShiftAmount; + dst[Length-1] = byte1; } From c9f3da51cbdabf1cbb8b9c3982a53dd541ecbac5 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 11 Jun 2024 15:35:35 -0700 Subject: [PATCH 35/95] getting closer to full reconstruction of rvvi. --- fpga/rvvidaemon/rvvidaemon.c | 56 ++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 24732f181..f7447d9dd 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -82,7 +82,7 @@ typedef struct { uint64_t RegValue; } Reg_t; -void DecodeRVVI(uint8_t *payload, uint64_t * PC, uint32_t *insn); +void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t *insn); void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length); int main(int argc, char **argv){ @@ -146,7 +146,7 @@ int main(int argc, char **argv){ //printf("Correct destination MAC address\n"); uint64_t PC; uint32_t insn; - DecodeRVVI(buf + headerbytes, &PC, &insn); + DecodeRVVI(buf + headerbytes, payloadbytes, &PC, &insn); } } @@ -155,35 +155,29 @@ int main(int argc, char **argv){ return 0; } -void DecodeRVVI(uint8_t *payload, uint64_t * PC, uint32_t *insn){ +void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t *insn){ // you know this actually easiser in assembly. :( uint8_t buf2[BUF_SIZ], buf3[BUF_SIZ]; //int PayloadSize = sizeof(RequiredRVVI_t) - 1; int PayloadSize = 30; int Buf2Size = BUF_SIZ - PayloadSize; - RequiredRVVI_t *RequiredFields = (RequiredRVVI_t *) payload; - uint8_t *CurrentBytePointer = payload + PayloadSize; - Reg_t *FirstReg; - Reg_t SecondReg; uint64_t Mcycle, Minstret; // unforunately the struct appoarch does not work?!? - //*PC = RequiredFields->PC; *PC = * (uint64_t *) payload; - //*insn = RequiredFields->insn; payload += 8; *insn = * (uint32_t *) payload; - // Mcycle = RequiredFields->Mcycle; payload += 4; Mcycle = * (uint64_t *) payload; payload += 8; Minstret = * (uint64_t *) payload; - //Minstret = RequiredFields->Minstret; payload += 8; // the next 4 bytes contain CSRCount (12), FPRWen(1), GPRWen(1), PrivilegeMode(2), Trap(1) uint32_t RequiredFlags; RequiredFlags = * (uint32_t *) payload; uint8_t Trap, PrivilegeMode, GPRWen, FPRWen; uint16_t CSRCount; + uint8_t GPRReg; + uint64_t GPRData; Trap = RequiredFlags & 0x1; PrivilegeMode = (RequiredFlags >> 1) & 0x3; @@ -191,13 +185,38 @@ void DecodeRVVI(uint8_t *payload, uint64_t * PC, uint32_t *insn){ FPRWen = (RequiredFlags >> 4) & 0x1; CSRCount = (RequiredFlags >> 5) & 0xFFF; - int bits; - printf("PC = %lx, insn = %x, Mcycle = %lx, Minstret = %lx, Trap = %hhx, PrivilegeMode = %hhx, GPRWen = %hhx, FPRWen = %hhx, CSRCount == %hx\n", *PC, *insn, Mcycle, Minstret, Trap, PrivilegeMode, GPRWen, FPRWen, CSRCount); - if(RequiredFields->GPREn){ - BitShiftArray(buf2, CurrentBytePointer, 1, Buf2Size); - FirstReg = (Reg_t *) buf2; - printf("Wrote reg %d = %lx\n", FirstReg->RegAddress, FirstReg->RegValue); + if(GPRWen || FPRWen || (CSRCount != 0)){ + payload += 2; + // the first bit of payload is the last bit of CSRCount. + ssize_t newPayloadSize = payloadsize - 30; + BitShiftArray(buf2, payload, 1, newPayloadSize); + int index; + printf("payload = "); + for(index = 0; index < 10; index++){ + printf("%02hhx", payload[index]); + } + printf("\n"); + printf("buf2 = "); + for(index = 0; index < 10; index++){ + printf("%02hhx", buf2[index]); + } + printf("\n"); + if(GPRWen){ + GPRReg = * (uint8_t *) buf2; + GPRReg = GPRReg & 0x1F; + BitShiftArray(buf3, buf2, 5, newPayloadSize); + GPRData = * (uint64_t *) buf3; + } + printf("Wrote register %d with value = %lx\n", GPRReg, GPRData); + int bits; + printf("Start at Reg data = "); + for(bits = 0; bits < newPayloadSize; bits++){ + printf("%02hhX", buf2[bits]); + } + printf("\n"); + + //printf("Wrote reg %d = %lx\n", FirstReg->RegAddress, FirstReg->RegValue); } printf("!!!!!\n\n"); } @@ -221,8 +240,7 @@ void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length){ uint8_t byte1 = src[Index]; uint8_t byte2 = src[Index+1]; byte1 = byte1 >> ShiftAmount; - uint8_t byte2rot = byte2 >> ShiftAmount | byte2 << (unsigned) (8 - ShiftAmount); - byte2rot = byte2rot & ~(2^ShiftAmount - 1); + uint8_t byte2rot = (byte2 << (unsigned) (8 - ShiftAmount)) & 0xff; uint8_t byte1final = byte2rot | byte1; dst[Index] = byte1final; } From 8bce2fc739d7d490f1a6d056e5373549ae85f627 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 11 Jun 2024 16:21:53 -0700 Subject: [PATCH 36/95] Getting closer. --- fpga/rvvidaemon/rvvidaemon.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index f7447d9dd..1b4a25d0e 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -158,6 +158,9 @@ int main(int argc, char **argv){ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t *insn){ // you know this actually easiser in assembly. :( uint8_t buf2[BUF_SIZ], buf3[BUF_SIZ]; + uint8_t * buf2ptr, *buf3ptr; + buf2ptr = buf2; + buf3ptr = buf3; //int PayloadSize = sizeof(RequiredRVVI_t) - 1; int PayloadSize = 30; int Buf2Size = BUF_SIZ - PayloadSize; @@ -175,9 +178,11 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t * uint32_t RequiredFlags; RequiredFlags = * (uint32_t *) payload; uint8_t Trap, PrivilegeMode, GPRWen, FPRWen; - uint16_t CSRCount; - uint8_t GPRReg; - uint64_t GPRData; + uint16_t CSRCount = 0; + uint8_t GPRReg = 0; + uint64_t GPRData = 0; + uint8_t FPRReg = 0; + uint64_t FPRData = 0; Trap = RequiredFlags & 0x1; PrivilegeMode = (RequiredFlags >> 1) & 0x3; @@ -203,10 +208,22 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t * } printf("\n"); if(GPRWen){ - GPRReg = * (uint8_t *) buf2; + GPRReg = * (uint8_t *) buf2ptr; GPRReg = GPRReg & 0x1F; - BitShiftArray(buf3, buf2, 5, newPayloadSize); + BitShiftArray(buf3, buf2ptr, 5, newPayloadSize); GPRData = * (uint64_t *) buf3; + if(FPRWen){ + buf3ptr += 8; + FPRReg = * (uint8_t *) buf3ptr; + BitShiftArray(buf2, buf3ptr, 5, newPayloadSize - 8); + FPRReg = FPRReg & 0x1F; + FPRData = * (uint64_t *) buf2; + } + }else if(FPRWen){ + FPRReg = * (uint8_t *) buf2; + FPRReg = FPRReg & 0x1F; + BitShiftArray(buf3, buf2, 5, newPayloadSize); + FPRData = * (uint64_t *) buf3; } printf("Wrote register %d with value = %lx\n", GPRReg, GPRData); int bits; From 3e7d07dfb6dc7f8f5c8aa71f6455af95f71911ca Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 11 Jun 2024 17:14:59 -0700 Subject: [PATCH 37/95] Better. --- fpga/rvvidaemon/rvvidaemon.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 1b4a25d0e..a1e6e0eb7 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -189,10 +189,10 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t * GPRWen = (RequiredFlags >> 3) & 0x1; FPRWen = (RequiredFlags >> 4) & 0x1; CSRCount = (RequiredFlags >> 5) & 0xFFF; + payload += 2; printf("PC = %lx, insn = %x, Mcycle = %lx, Minstret = %lx, Trap = %hhx, PrivilegeMode = %hhx, GPRWen = %hhx, FPRWen = %hhx, CSRCount == %hx\n", *PC, *insn, Mcycle, Minstret, Trap, PrivilegeMode, GPRWen, FPRWen, CSRCount); if(GPRWen || FPRWen || (CSRCount != 0)){ - payload += 2; // the first bit of payload is the last bit of CSRCount. ssize_t newPayloadSize = payloadsize - 30; BitShiftArray(buf2, payload, 1, newPayloadSize); @@ -232,6 +232,36 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t * printf("%02hhX", buf2[bits]); } printf("\n"); + if(GPRWen ^ FPRWen){ + payload += 8; + Buf2Size = payloadsize - 38; + BitShiftArray(buf2, payload, 6, Buf2Size); + }else if(GPRWen & FPRWen){ + payload += 17; + Buf2Size = payloadsize - 47; + BitShiftArray(buf2, payload, 3, Buf2Size); + }else{ + Buf2Size = payloadsize - 30; + BitShiftArray(buf2, payload, 1, Buf2Size); + } + int CSRIndex; + uint8_t CSRWen[3] = {0, 0, 0}; + uint16_t CSRReg[3]; + uint64_t CSRValue[3]; + buf2ptr = buf2; + for(CSRIndex = 0; CSRIndex < CSRCount; CSRIndex++){ + CSRReg[CSRIndex] = (*(uint16_t *) buf2ptr) & 0xFFF; + Buf2Size -= 1; + BitShiftArray(buf3, buf2ptr + 1, 4, Buf2Size); + CSRValue[CSRIndex] = (*(uint64_t *) buf3); + CSRWen[CSRIndex] = 1; + buf2ptr = buf3; + } + for(CSRIndex = 0; CSRIndex < 3; CSRIndex++){ + if(CSRWen[CSRIndex]){ + printf("Wrote CSR %x with value %lx\n", CSRReg[CSRIndex], CSRValue[CSRIndex]); + } + } //printf("Wrote reg %d = %lx\n", FirstReg->RegAddress, FirstReg->RegValue); } From f5d4db68b17d6d663f60c5ab75f70c301ec64b6a Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 12 Jun 2024 08:56:16 -0700 Subject: [PATCH 38/95] Modified rvvidaemon to populate a struct with all the relavent fields. --- fpga/rvvidaemon/rvvidaemon.c | 40 ++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index a1e6e0eb7..fa7db2801 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -75,6 +75,14 @@ typedef struct { uint8_t GPREn : 1; uint8_t FPREn : 1; uint16_t CSRCount : 12; + uint8_t GPRReg : 5; + uint64_t GPRValue; + uint8_t FPRReg : 5; + uint64_t FPRValue; + uint8_t CSRWen[3]; + uint16_t CSRReg[3]; + uint64_t CSRValue[3]; + } RequiredRVVI_t; // total size is 241 bits or 30.125 bytes typedef struct { @@ -82,7 +90,7 @@ typedef struct { uint64_t RegValue; } Reg_t; -void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t *insn); +void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t *insn, RequiredRVVI_t *InstructionData); void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length); int main(int argc, char **argv){ @@ -146,7 +154,8 @@ int main(int argc, char **argv){ //printf("Correct destination MAC address\n"); uint64_t PC; uint32_t insn; - DecodeRVVI(buf + headerbytes, payloadbytes, &PC, &insn); + RequiredRVVI_t InstructionData; + DecodeRVVI(buf + headerbytes, payloadbytes, &PC, &insn, &InstructionData); } } @@ -155,7 +164,7 @@ int main(int argc, char **argv){ return 0; } -void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t *insn){ +void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t *insn, RequiredRVVI_t *InstructionData){ // you know this actually easiser in assembly. :( uint8_t buf2[BUF_SIZ], buf3[BUF_SIZ]; uint8_t * buf2ptr, *buf3ptr; @@ -183,6 +192,9 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t * uint64_t GPRData = 0; uint8_t FPRReg = 0; uint64_t FPRData = 0; + uint8_t CSRWen[3] = {0, 0, 0}; + uint16_t CSRReg[3]; + uint64_t CSRValue[3]; Trap = RequiredFlags & 0x1; PrivilegeMode = (RequiredFlags >> 1) & 0x3; @@ -245,9 +257,6 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t * BitShiftArray(buf2, payload, 1, Buf2Size); } int CSRIndex; - uint8_t CSRWen[3] = {0, 0, 0}; - uint16_t CSRReg[3]; - uint64_t CSRValue[3]; buf2ptr = buf2; for(CSRIndex = 0; CSRIndex < CSRCount; CSRIndex++){ CSRReg[CSRIndex] = (*(uint16_t *) buf2ptr) & 0xFFF; @@ -263,6 +272,25 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t * } } + InstructionData->PC = *PC; + InstructionData->insn = *insn; + InstructionData->Mcycle = Mcycle; + InstructionData->Minstret = Minstret; + InstructionData->Trap = Trap; + InstructionData->PrivilegeMode = PrivilegeMode; + InstructionData->GPREn = GPRWen; + InstructionData->FPREn = FPRWen; + InstructionData->CSRCount = CSRCount; + InstructionData->GPRReg = GPRReg; + InstructionData->GPRValue = GPRData; + InstructionData->FPRReg = FPRReg; + InstructionData->FPRValue = FPRData; + for(CSRIndex = 0; CSRIndex < 3; CSRIndex++){ + InstructionData->CSRWen[CSRIndex] = CSRWen[CSRIndex]; + InstructionData->CSRReg[CSRIndex] = CSRReg[CSRIndex]; + InstructionData->CSRValue[CSRIndex] = CSRValue[CSRIndex]; + } + //printf("Wrote reg %d = %lx\n", FirstReg->RegAddress, FirstReg->RegValue); } printf("!!!!!\n\n"); From 323dbd348e7638c6c73644f18a2819471ba59dbf Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 12 Jun 2024 12:54:21 -0700 Subject: [PATCH 39/95] Progress. --- fpga/rvvidaemon/rvvidaemon.c | 43 +++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index fa7db2801..1f083d165 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -90,7 +91,7 @@ typedef struct { uint64_t RegValue; } Reg_t; -void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t *insn, RequiredRVVI_t *InstructionData); +void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *InstructionData); void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length); int main(int argc, char **argv){ @@ -138,6 +139,14 @@ int main(int argc, char **argv){ } printf("Here 4\n"); + if(!rvviVersionCheck(RVVI_API_VERSION)){ + printf("Bad RVVI_API_VERSION\n"); + } + + //rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"); + + rvviRefInit(NULL); + while(1) { //printf("listener: Waiting to recvfrom...\n"); numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL); @@ -155,16 +164,18 @@ int main(int argc, char **argv){ uint64_t PC; uint32_t insn; RequiredRVVI_t InstructionData; - DecodeRVVI(buf + headerbytes, payloadbytes, &PC, &insn, &InstructionData); + DecodeRVVI(buf + headerbytes, payloadbytes, &InstructionData); } } close(sockfd); + + return 0; } -void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t *insn, RequiredRVVI_t *InstructionData){ +void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *InstructionData){ // you know this actually easiser in assembly. :( uint8_t buf2[BUF_SIZ], buf3[BUF_SIZ]; uint8_t * buf2ptr, *buf3ptr; @@ -174,10 +185,12 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t * int PayloadSize = 30; int Buf2Size = BUF_SIZ - PayloadSize; uint64_t Mcycle, Minstret; + uint64_t PC; + uint32_t insn; // unforunately the struct appoarch does not work?!? - *PC = * (uint64_t *) payload; + PC = * (uint64_t *) payload; payload += 8; - *insn = * (uint32_t *) payload; + insn = * (uint32_t *) payload; payload += 4; Mcycle = * (uint64_t *) payload; payload += 8; @@ -203,7 +216,7 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t * CSRCount = (RequiredFlags >> 5) & 0xFFF; payload += 2; - printf("PC = %lx, insn = %x, Mcycle = %lx, Minstret = %lx, Trap = %hhx, PrivilegeMode = %hhx, GPRWen = %hhx, FPRWen = %hhx, CSRCount == %hx\n", *PC, *insn, Mcycle, Minstret, Trap, PrivilegeMode, GPRWen, FPRWen, CSRCount); + printf("PC = %lx, insn = %x, Mcycle = %lx, Minstret = %lx, Trap = %hhx, PrivilegeMode = %hhx, GPRWen = %hhx, FPRWen = %hhx, CSRCount == %hx\n", PC, insn, Mcycle, Minstret, Trap, PrivilegeMode, GPRWen, FPRWen, CSRCount); if(GPRWen || FPRWen || (CSRCount != 0)){ // the first bit of payload is the last bit of CSRCount. ssize_t newPayloadSize = payloadsize - 30; @@ -272,8 +285,8 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t * } } - InstructionData->PC = *PC; - InstructionData->insn = *insn; + InstructionData->PC = PC; + InstructionData->insn = insn; InstructionData->Mcycle = Mcycle; InstructionData->Minstret = Minstret; InstructionData->Trap = Trap; @@ -296,6 +309,20 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, uint64_t * PC, uint32_t * printf("!!!!!\n\n"); } +void PrintInstructionData(RequiredRVVI_t *InstructionData){ + int CSRIndex; + printf("PC = %lx, insn = %x, Mcycle = %lx, Minstret = %lx, Trap = %hhx, PrivilegeMode = %hhx, GPRWen = %hhx, FPRWen = %hhx, CSRCount == %hx\n", + InstructionData->PC, InstructionData->insn, InstructionData->Mcycle, InstructionData->Minstret, InstructionData->Trap, InstructionData->PrivilegeMode, InstructionData->GPREn, InstructionData->FPREn, InstructionData->CSRCount); + if(InstructionData->GPREn){ + + } + for(CSRIndex = 0; CSRIndex < 3; CSRIndex++){ + if(InstructionData->CSRWen[CSRIndex]){ + printf("Wrote CSR %x with value %lx\n", InstructionData->CSRReg[CSRIndex], InstructionData->CSRValue[CSRIndex]); + } + } +} + void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length){ // always shift right by ShiftAmount (0 to 7 bit positions). // *** this implemenation is very inefficient. improve later. From c9f51df34a1bae8c9cb2f51ad6458b84e8cce385 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 12 Jun 2024 14:47:32 -0700 Subject: [PATCH 40/95] Fixed bug in rvvi reset. --- fpga/rvvidaemon/rvvidaemon.c | 87 ++++++++++++++---------------------- fpga/src/fpgaTopArtyA7.sv | 2 +- 2 files changed, 34 insertions(+), 55 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 1f083d165..54240e72b 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -93,6 +93,7 @@ typedef struct { void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *InstructionData); void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length); +void PrintInstructionData(RequiredRVVI_t *InstructionData); int main(int argc, char **argv){ @@ -139,13 +140,13 @@ int main(int argc, char **argv){ } printf("Here 4\n"); - if(!rvviVersionCheck(RVVI_API_VERSION)){ - printf("Bad RVVI_API_VERSION\n"); - } + /* if(!rvviVersionCheck(RVVI_API_VERSION)){ */ + /* printf("Bad RVVI_API_VERSION\n"); */ + /* } */ //rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"); - rvviRefInit(NULL); + //rvviRefInit(NULL); while(1) { //printf("listener: Waiting to recvfrom...\n"); @@ -165,6 +166,7 @@ int main(int argc, char **argv){ uint32_t insn; RequiredRVVI_t InstructionData; DecodeRVVI(buf + headerbytes, payloadbytes, &InstructionData); + PrintInstructionData(&InstructionData); } } @@ -208,6 +210,7 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *Instructi uint8_t CSRWen[3] = {0, 0, 0}; uint16_t CSRReg[3]; uint64_t CSRValue[3]; + int CSRIndex; Trap = RequiredFlags & 0x1; PrivilegeMode = (RequiredFlags >> 1) & 0x3; @@ -216,22 +219,11 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *Instructi CSRCount = (RequiredFlags >> 5) & 0xFFF; payload += 2; - printf("PC = %lx, insn = %x, Mcycle = %lx, Minstret = %lx, Trap = %hhx, PrivilegeMode = %hhx, GPRWen = %hhx, FPRWen = %hhx, CSRCount == %hx\n", PC, insn, Mcycle, Minstret, Trap, PrivilegeMode, GPRWen, FPRWen, CSRCount); if(GPRWen || FPRWen || (CSRCount != 0)){ // the first bit of payload is the last bit of CSRCount. ssize_t newPayloadSize = payloadsize - 30; BitShiftArray(buf2, payload, 1, newPayloadSize); int index; - printf("payload = "); - for(index = 0; index < 10; index++){ - printf("%02hhx", payload[index]); - } - printf("\n"); - printf("buf2 = "); - for(index = 0; index < 10; index++){ - printf("%02hhx", buf2[index]); - } - printf("\n"); if(GPRWen){ GPRReg = * (uint8_t *) buf2ptr; GPRReg = GPRReg & 0x1F; @@ -250,13 +242,6 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *Instructi BitShiftArray(buf3, buf2, 5, newPayloadSize); FPRData = * (uint64_t *) buf3; } - printf("Wrote register %d with value = %lx\n", GPRReg, GPRData); - int bits; - printf("Start at Reg data = "); - for(bits = 0; bits < newPayloadSize; bits++){ - printf("%02hhX", buf2[bits]); - } - printf("\n"); if(GPRWen ^ FPRWen){ payload += 8; Buf2Size = payloadsize - 38; @@ -269,7 +254,6 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *Instructi Buf2Size = payloadsize - 30; BitShiftArray(buf2, payload, 1, Buf2Size); } - int CSRIndex; buf2ptr = buf2; for(CSRIndex = 0; CSRIndex < CSRCount; CSRIndex++){ CSRReg[CSRIndex] = (*(uint16_t *) buf2ptr) & 0xFFF; @@ -279,48 +263,43 @@ void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *Instructi CSRWen[CSRIndex] = 1; buf2ptr = buf3; } - for(CSRIndex = 0; CSRIndex < 3; CSRIndex++){ - if(CSRWen[CSRIndex]){ - printf("Wrote CSR %x with value %lx\n", CSRReg[CSRIndex], CSRValue[CSRIndex]); - } - } - - InstructionData->PC = PC; - InstructionData->insn = insn; - InstructionData->Mcycle = Mcycle; - InstructionData->Minstret = Minstret; - InstructionData->Trap = Trap; - InstructionData->PrivilegeMode = PrivilegeMode; - InstructionData->GPREn = GPRWen; - InstructionData->FPREn = FPRWen; - InstructionData->CSRCount = CSRCount; - InstructionData->GPRReg = GPRReg; - InstructionData->GPRValue = GPRData; - InstructionData->FPRReg = FPRReg; - InstructionData->FPRValue = FPRData; - for(CSRIndex = 0; CSRIndex < 3; CSRIndex++){ - InstructionData->CSRWen[CSRIndex] = CSRWen[CSRIndex]; - InstructionData->CSRReg[CSRIndex] = CSRReg[CSRIndex]; - InstructionData->CSRValue[CSRIndex] = CSRValue[CSRIndex]; - } - - //printf("Wrote reg %d = %lx\n", FirstReg->RegAddress, FirstReg->RegValue); } - printf("!!!!!\n\n"); + InstructionData->PC = PC; + InstructionData->insn = insn; + InstructionData->Mcycle = Mcycle; + InstructionData->Minstret = Minstret; + InstructionData->Trap = Trap; + InstructionData->PrivilegeMode = PrivilegeMode; + InstructionData->GPREn = GPRWen; + InstructionData->FPREn = FPRWen; + InstructionData->CSRCount = CSRCount; + InstructionData->GPRReg = GPRReg; + InstructionData->GPRValue = GPRData; + InstructionData->FPRReg = FPRReg; + InstructionData->FPRValue = FPRData; + for(CSRIndex = 0; CSRIndex < 3; CSRIndex++){ + InstructionData->CSRWen[CSRIndex] = CSRWen[CSRIndex]; + InstructionData->CSRReg[CSRIndex] = CSRReg[CSRIndex]; + InstructionData->CSRValue[CSRIndex] = CSRValue[CSRIndex]; + } } void PrintInstructionData(RequiredRVVI_t *InstructionData){ int CSRIndex; - printf("PC = %lx, insn = %x, Mcycle = %lx, Minstret = %lx, Trap = %hhx, PrivilegeMode = %hhx, GPRWen = %hhx, FPRWen = %hhx, CSRCount == %hx\n", - InstructionData->PC, InstructionData->insn, InstructionData->Mcycle, InstructionData->Minstret, InstructionData->Trap, InstructionData->PrivilegeMode, InstructionData->GPREn, InstructionData->FPREn, InstructionData->CSRCount); + printf("PC = %lx, insn = %x, Mcycle = %lx, Minstret = %lx, Trap = %hhx, PrivilegeMode = %hhx", + InstructionData->PC, InstructionData->insn, InstructionData->Mcycle, InstructionData->Minstret, InstructionData->Trap, InstructionData->PrivilegeMode); if(InstructionData->GPREn){ - + printf(", GPR[%d] = %lx", InstructionData->GPRReg, InstructionData->GPRValue); + } + if(InstructionData->FPREn){ + printf(", FPR[%d] = %lx", InstructionData->FPRReg, InstructionData->FPRValue); } for(CSRIndex = 0; CSRIndex < 3; CSRIndex++){ if(InstructionData->CSRWen[CSRIndex]){ - printf("Wrote CSR %x with value %lx\n", InstructionData->CSRReg[CSRIndex], InstructionData->CSRValue[CSRIndex]); + printf(", CSR[%x] = %lx", InstructionData->CSRReg[CSRIndex], InstructionData->CSRValue[CSRIndex]); } } + printf("\n"); } void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length){ diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index 8a6b08f47..0efca4f53 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -1134,7 +1134,7 @@ module fpgaTop packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(CPUCLK), .m_axi_aresetn(~bus_struct_reset), .RVVIStall, .RvviAxiWdata, .RvviAxiWstrb, .RvviAxiWlast, .RvviAxiWvalid, .RvviAxiWready); - eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(reset), .logic_clk(CPUCLK), .logic_rst(bus_struct_reset), + eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(bus_struct_reset), .logic_clk(CPUCLK), .logic_rst(bus_struct_reset), .tx_axis_tdata(RvviAxiWdata), .tx_axis_tkeep(RvviAxiWstrb), .tx_axis_tvalid(RvviAxiWvalid), .tx_axis_tready(RvviAxiWready), .tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), .rx_axis_tlast(), .rx_axis_tuser(), From 47523c97acc430a6636050abfe8c9ffeecf792d9 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 13 Jun 2024 15:46:54 -0700 Subject: [PATCH 41/95] Getting closer to figuring out the lost ethernet frame bugs. --- fpga/rvvidaemon/Makefile | 2 +- fpga/src/fpgaTopArtyA7.sv | 8 ++++---- src/rvvi/mii_phy_if.sv | 4 ++-- src/rvvi/packetizer.sv | 31 ++++++++++++++++++++++++------- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/fpga/rvvidaemon/Makefile b/fpga/rvvidaemon/Makefile index c1d1d5a1c..d529a1212 100644 --- a/fpga/rvvidaemon/Makefile +++ b/fpga/rvvidaemon/Makefile @@ -1,7 +1,7 @@ all: rvvidaemon rvvidaemon: rvvidaemon.o - gcc $^ -o rvvidaemon + gcc $^ /opt/riscv/ImperasDV-OpenHW/Imperas/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model.so -o rvvidaemon %.o:%.c gcc -c $^ -o $@ diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index 0efca4f53..51de188db 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -1122,9 +1122,9 @@ module fpgaTop rvvisynth #(P, MAX_CSRS) rvvisynth(.clk(CPUCLK), .reset(bus_struct_reset), .valid, .rvvi); // axi 4 write data channel - logic [31:0] RvviAxiWdata; - logic [3:0] RvviAxiWstrb; - logic RvviAxiWlast; +(* mark_debug = "true" *) logic [31:0] RvviAxiWdata; +(* mark_debug = "true" *) logic [3:0] RvviAxiWstrb; +(* mark_debug = "true" *) logic RvviAxiWlast; (* mark_debug = "true" *) logic RvviAxiWvalid; (* mark_debug = "true" *) logic RvviAxiWready; @@ -1134,7 +1134,7 @@ module fpgaTop packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(CPUCLK), .m_axi_aresetn(~bus_struct_reset), .RVVIStall, .RvviAxiWdata, .RvviAxiWstrb, .RvviAxiWlast, .RvviAxiWvalid, .RvviAxiWready); - eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(bus_struct_reset), .logic_clk(CPUCLK), .logic_rst(bus_struct_reset), + eth_mac_mii_fifo #(.TARGET("GENERIC"), .CLOCK_INPUT_STYLE("BUFG"), .AXIS_DATA_WIDTH(32), .TX_FIFO_DEPTH(1024)) ethernet(.rst(bus_struct_reset), .logic_clk(CPUCLK), .logic_rst(bus_struct_reset), .tx_axis_tdata(RvviAxiWdata), .tx_axis_tkeep(RvviAxiWstrb), .tx_axis_tvalid(RvviAxiWvalid), .tx_axis_tready(RvviAxiWready), .tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), .rx_axis_tlast(), .rx_axis_tuser(), diff --git a/src/rvvi/mii_phy_if.sv b/src/rvvi/mii_phy_if.sv index 340d7ad24..f3857ed06 100644 --- a/src/rvvi/mii_phy_if.sv +++ b/src/rvvi/mii_phy_if.sv @@ -53,8 +53,8 @@ module mii_phy_if # output wire mac_mii_rx_er, output wire mac_mii_tx_clk, output wire mac_mii_tx_rst, - input wire [3:0] mac_mii_txd, - input wire mac_mii_tx_en, +(* mark_debug = "true" *) input wire [3:0] mac_mii_txd, +(* mark_debug = "true" *) input wire mac_mii_tx_en, input wire mac_mii_tx_er, /* diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 5b16615a6..f2c80d928 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -59,23 +59,32 @@ module packetizer import cvw::*; #(parameter cvw_t P, logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvviDelay; - typedef enum {STATE_RDY, STATE_WAIT, STATE_TRANS, STATE_TRANS_DONE} statetype; - statetype CurrState, NextState; + typedef enum {STATE_RST, STATE_COUNT, STATE_RDY, STATE_WAIT, STATE_TRANS, STATE_TRANS_INSERT_DELAY} statetype; +(* mark_debug = "true" *) statetype CurrState, NextState; + + logic [31:0] RstCount; + logic RstCountRst, RstCountEn, CountFlag, DelayFlag; + always_ff @(posedge m_axi_aclk) begin - if(~m_axi_aresetn) CurrState <= STATE_RDY; + if(~m_axi_aresetn) CurrState <= STATE_RST; else CurrState <= NextState; end always_comb begin case(CurrState) + STATE_RST: NextState = STATE_COUNT; + STATE_COUNT: if (CountFlag) NextState = STATE_RDY; + else NextState = STATE_COUNT; STATE_RDY: if (TransReady & valid) NextState = STATE_TRANS; else if(~TransReady & valid) NextState = STATE_WAIT; else NextState = STATE_RDY; - STATE_WAIT: if(TransReady) NextState = STATE_TRANS; - else NextState = STATE_WAIT; - STATE_TRANS: if(BurstDone) NextState = STATE_RDY; - else NextState = STATE_TRANS; + STATE_WAIT: if(TransReady) NextState = STATE_TRANS; + else NextState = STATE_WAIT; + STATE_TRANS: if(BurstDone) NextState = STATE_TRANS_INSERT_DELAY; + else NextState = STATE_TRANS; + STATE_TRANS_INSERT_DELAY: if(DelayFlag) NextState = STATE_RDY; + else NextState = STATE_TRANS_INSERT_DELAY; default: NextState = STATE_RDY; endcase end @@ -84,6 +93,14 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign TransReady = RvviAxiWready; assign WordCountEnable = (CurrState == STATE_RDY & valid) | (CurrState == STATE_TRANS & TransReady); assign WordCountReset = CurrState == STATE_RDY; + assign RstCountEn = CurrState == STATE_COUNT | CurrState == STATE_TRANS_INSERT_DELAY; + assign RstCountRst = CurrState == STATE_RST | CurrState == STATE_TRANS; + + // have to count at least 250 ms after reset pulled to wait for the phy to actually be ready + // at 20MHz 250 ms is 250e-3 / (1/20e6) = 5,000,000. + counter #(32) rstcounter(m_axi_aclk, RstCountRst, RstCountEn, RstCount); + assign CountFlag = RstCount == 32'd100000000; + assign DelayFlag = RstCount == 32'd48; flopenr #(187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)) rvvireg(m_axi_aclk, ~m_axi_aresetn, valid, rvvi, rvviDelay); From 82b54c0887669e11aedb79605807245b72808bcf Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 17 Jun 2024 09:15:59 -0700 Subject: [PATCH 42/95] Got IDV properly initalized. --- fpga/rvvidaemon/rvvidaemon.c | 51 ++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 54240e72b..7a33a00b5 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -42,6 +42,7 @@ #include #include #include "rvviApi.h" // *** bug fix me when this file gets included into the correct directory. +#include "idv/idv.h" #define DEST_MAC0 0x43 @@ -140,13 +141,53 @@ int main(int argc, char **argv){ } printf("Here 4\n"); - /* if(!rvviVersionCheck(RVVI_API_VERSION)){ */ - /* printf("Bad RVVI_API_VERSION\n"); */ - /* } */ + if(!rvviVersionCheck(RVVI_API_VERSION)){ + printf("Bad RVVI_API_VERSION\n"); + } - //rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"); + rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"); + rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME,"riscv"); + rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC"); + rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56); + rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6); - //rvviRefInit(NULL); + // eventually we want to put the elffiles here + rvviRefInit(NULL); + rvviRefPcSet(0, 0x1000); + + // Volatile CSRs + rvviRefCsrSetVolatile(0, 0xC00); // CYCLE + rvviRefCsrSetVolatile(0, 0xB00); // MCYCLE + rvviRefCsrSetVolatile(0, 0xC02); // INSTRET + rvviRefCsrSetVolatile(0, 0xB02); // MINSTRET + rvviRefCsrSetVolatile(0, 0xC01); // TIME + + int iter; + for (iter = 0xC03; iter <= 0xC1F; iter++) { + rvviRefCsrSetVolatile(0, iter); // HPMCOUNTERx + } + // Machine MHPMCOUNTER3 - MHPMCOUNTER31 + for (iter = 0xB03; iter <= 0xB1F; iter++) { + rvviRefCsrSetVolatile(0, iter); // MHPMCOUNTERx + } + // cannot predict this register due to latency between + // pending and taken + rvviRefCsrSetVolatile(0, 0x344); // MIP + rvviRefCsrSetVolatile(0, 0x144); // SIP + + // set bootrom and bootram as volatile memory + rvviRefMemorySetVolatile(0x1000, 0x1FFF); + rvviRefMemorySetVolatile(0x2000, 0x2FFF); + + // Privileges for PMA are set in the imperas.ic + // volatile (IO) regions are defined here + // only real ROM/RAM areas are BOOTROM and UNCORE_RAM + rvviRefMemorySetVolatile(0x2000000, 0x2000000 + 0xFFFF); + rvviRefMemorySetVolatile(0x10060000, 0x10060000 + 0xFF); + rvviRefMemorySetVolatile(0x10000000, 0x10000000 + 0x7); + rvviRefMemorySetVolatile(0x0C000000, 0x0C000000 + 0x03FFFFFF); + rvviRefMemorySetVolatile(0x00013000, 0x00013000 + 0x7F); + rvviRefMemorySetVolatile(0x10040000, 0x10040000 + 0xFFF); while(1) { //printf("listener: Waiting to recvfrom...\n"); From cccb40e4b50ba97eea872461892fdeeac40648fa Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 17 Jun 2024 09:16:24 -0700 Subject: [PATCH 43/95] Got the tracer not overrunning ethernet buffers so frames are not being dropped. --- src/rvvi/packetizer.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index f2c80d928..85e56beb1 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -100,7 +100,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, // at 20MHz 250 ms is 250e-3 / (1/20e6) = 5,000,000. counter #(32) rstcounter(m_axi_aclk, RstCountRst, RstCountEn, RstCount); assign CountFlag = RstCount == 32'd100000000; - assign DelayFlag = RstCount == 32'd48; + assign DelayFlag = RstCount == 32'd200; flopenr #(187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)) rvvireg(m_axi_aclk, ~m_axi_aresetn, valid, rvvi, rvviDelay); From 598770da518509f56131cb9f3141125777b26125 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 17 Jun 2024 12:37:10 -0700 Subject: [PATCH 44/95] Getting much closer to a working version. --- fpga/rvvidaemon/Makefile | 4 ++-- fpga/rvvidaemon/rvvidaemon.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/fpga/rvvidaemon/Makefile b/fpga/rvvidaemon/Makefile index d529a1212..4f048302d 100644 --- a/fpga/rvvidaemon/Makefile +++ b/fpga/rvvidaemon/Makefile @@ -1,10 +1,10 @@ all: rvvidaemon rvvidaemon: rvvidaemon.o - gcc $^ /opt/riscv/ImperasDV-OpenHW/Imperas/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model.so -o rvvidaemon + gcc $^ /opt/riscv/ImperasDV-OpenHW/Imperas/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model.so -o rvvidaemon %.o:%.c - gcc -c $^ -o $@ + gcc -I/opt/riscv/ImperasDV-OpenHW/Imperas/ImpProprietary/include/host -c $^ -o $@ clean: rm *.o rvvidaemon diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 7a33a00b5..bf875c771 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -95,6 +95,9 @@ typedef struct { void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *InstructionData); void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length); void PrintInstructionData(RequiredRVVI_t *InstructionData); +void ProcessRvviAll(RequiredRVVI_t *InstructionData); +void set_gpr(int hart, int reg, uint64_t value); +void set_fpr(int hart, int reg, uint64_t value); int main(int argc, char **argv){ @@ -207,6 +210,9 @@ int main(int argc, char **argv){ uint32_t insn; RequiredRVVI_t InstructionData; DecodeRVVI(buf + headerbytes, payloadbytes, &InstructionData); + // now let's drive IDV + // start simple just drive and compare PC. + ProcessRvviAll(&InstructionData); PrintInstructionData(&InstructionData); } } @@ -218,6 +224,28 @@ int main(int argc, char **argv){ return 0; } +void ProcessRvviAll(RequiredRVVI_t *InstructionData){ + long int found; + uint64_t time = InstructionData->Mcycle; + uint8_t trap = InstructionData->Trap; + uint64_t order = InstructionData->Minstret; + + if(InstructionData->GPREn) set_gpr(0, InstructionData->GPRReg, InstructionData->GPRValue); + if(InstructionData->FPREn) set_fpr(0, InstructionData->FPRReg, InstructionData->FPRValue); + // *** set is for nets like interrupts come back to this. + //found = rvviRefNetIndexGet("pc_rdata"); + //rvviRefNetSet(found, InstructionData->PC, time); + +} + +void set_gpr(int hart, int reg, uint64_t value){ + rvviDutGprSet(hart, reg, value); +} + +void set_fpr(int hart, int reg, uint64_t value){ + rvviDutFprSet(hart, reg, value); +} + void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *InstructionData){ // you know this actually easiser in assembly. :( uint8_t buf2[BUF_SIZ], buf3[BUF_SIZ]; From 93829ce509ac9204efb5cb52af5248b0c1a3f84d Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Mon, 17 Jun 2024 13:41:40 -0700 Subject: [PATCH 45/95] Success! We have some instructions comparing across the FPGA and IDV! However I'm still losing ethernet frames. --- fpga/rvvidaemon/rvvidaemon.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index bf875c771..074ffa21c 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -98,6 +98,7 @@ void PrintInstructionData(RequiredRVVI_t *InstructionData); void ProcessRvviAll(RequiredRVVI_t *InstructionData); void set_gpr(int hart, int reg, uint64_t value); void set_fpr(int hart, int reg, uint64_t value); +void state_compare(int hart, uint64_t Minstret); int main(int argc, char **argv){ @@ -232,12 +233,46 @@ void ProcessRvviAll(RequiredRVVI_t *InstructionData){ if(InstructionData->GPREn) set_gpr(0, InstructionData->GPRReg, InstructionData->GPRValue); if(InstructionData->FPREn) set_fpr(0, InstructionData->FPRReg, InstructionData->FPRValue); + + if (trap) { + rvviDutTrap(0, InstructionData->PC, InstructionData->insn); + } else { + rvviDutRetire(0, InstructionData->PC, InstructionData->insn, 0); + } + + if(!trap) state_compare(0, InstructionData->Minstret); + // *** set is for nets like interrupts come back to this. //found = rvviRefNetIndexGet("pc_rdata"); //rvviRefNetSet(found, InstructionData->PC, time); } +void state_compare(int hart, uint64_t Minstret){ + uint8_t result = 1; + uint8_t stepOk = 0; + char buf[80]; + rvviDutCycleCountSet(Minstret); + if(rvviRefEventStep(hart) != 0) { + stepOk = 1; + result &= rvviRefPcCompare(hart); + result &= rvviRefInsBinCompare(hart); + result &= rvviRefGprsCompare(hart); + result &= rvviRefFprsCompare(hart); + //result &= rvviRefCsrCompare(hart); + } else { + result = 0; + } + + if (result == 0) { + sprintf(buf, "MISMATCH @ instruction # %ld\n", Minstret); + idvMsgError(buf); + + //if (ON_MISMATCH_DUMP_STATE) dump_state(hart); + } + +} + void set_gpr(int hart, int reg, uint64_t value){ rvviDutGprSet(hart, reg, value); } From 00e0549c360dac4999d607376e1d512c164300bf Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 18 Jun 2024 07:44:19 -0700 Subject: [PATCH 46/95] I know what is wrong now. The ethernet device IP is not correctly generating the mii nibble stream. Some nibbles are dropped in each 4-byte word. The default input interface to the interface is 8-bit and I used 32-bit. I suspect there is a bug in the implementation for non-8-bit interfaces. --- src/rvvi/packetizer.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 85e56beb1..e2d8fc19c 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -100,7 +100,8 @@ module packetizer import cvw::*; #(parameter cvw_t P, // at 20MHz 250 ms is 250e-3 / (1/20e6) = 5,000,000. counter #(32) rstcounter(m_axi_aclk, RstCountRst, RstCountEn, RstCount); assign CountFlag = RstCount == 32'd100000000; - assign DelayFlag = RstCount == 32'd200; + //assign DelayFlag = RstCount == 32'd200; + assign DelayFlag = RstCount == 32'd0; flopenr #(187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)) rvvireg(m_axi_aclk, ~m_axi_aresetn, valid, rvvi, rvviDelay); From 2581ea0b748c23cd904f0d4463eaa4315cdec5f4 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 18 Jun 2024 16:48:49 -0700 Subject: [PATCH 47/95] Found the actual bug. Once the ethernet transmit fifo was full the rvvi packetizer was not correctly marking the end of the frame. First Last was held for too many cycles. Second it was assert on cycles when Valid was not high. Simulation reproduced the FPGA corrupted frames and then with the fix showed working frames. --- src/rvvi/packetizer.sv | 5 ++-- src/rvvi/rvvisynth.sv | 63 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index e2d8fc19c..8ccec184d 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -81,7 +81,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, else NextState = STATE_RDY; STATE_WAIT: if(TransReady) NextState = STATE_TRANS; else NextState = STATE_WAIT; - STATE_TRANS: if(BurstDone) NextState = STATE_TRANS_INSERT_DELAY; + STATE_TRANS: if(BurstDone & TransReady) NextState = STATE_TRANS_INSERT_DELAY; else NextState = STATE_TRANS; STATE_TRANS_INSERT_DELAY: if(DelayFlag) NextState = STATE_RDY; else NextState = STATE_TRANS_INSERT_DELAY; @@ -100,6 +100,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, // at 20MHz 250 ms is 250e-3 / (1/20e6) = 5,000,000. counter #(32) rstcounter(m_axi_aclk, RstCountRst, RstCountEn, RstCount); assign CountFlag = RstCount == 32'd100000000; + //assign CountFlag = RstCount == 32'd10; //assign DelayFlag = RstCount == 32'd200; assign DelayFlag = RstCount == 32'd0; @@ -128,7 +129,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign RvviAxiWdata = TotalFrameWords[WordCount]; assign RvviAxiWstrb = '1; - assign RvviAxiWlast = BurstDone; + assign RvviAxiWlast = BurstDone & (CurrState == STATE_TRANS); assign RvviAxiWvalid = (CurrState == STATE_TRANS); endmodule diff --git a/src/rvvi/rvvisynth.sv b/src/rvvi/rvvisynth.sv index df96ba446..16b214e18 100644 --- a/src/rvvi/rvvisynth.sv +++ b/src/rvvi/rvvisynth.sv @@ -27,6 +27,8 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// +`define FPGA 1 + module rvvisynth import cvw::*; #(parameter cvw_t P, parameter integer MAX_CSRS)( input logic clk, reset, @@ -62,6 +64,7 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, logic [MAX_CSRS*(P.XLEN+12)-1:0] CSRs; // get signals from the core. + if (`FPGA) begin assign StallE = fpgaTop.wallypipelinedsoc.core.StallE; assign StallM = fpgaTop.wallypipelinedsoc.core.StallM; assign StallW = fpgaTop.wallypipelinedsoc.core.StallW; @@ -120,6 +123,66 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, assign CSRArray[33] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 assign CSRArray[34] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 assign CSRArray[35] = {fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW, fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 + end else begin // if (`FPGA) + assign StallE = dut.core.StallE; + assign StallM = dut.core.StallM; + assign StallW = dut.core.StallW; + assign FlushE = dut.core.FlushE; + assign FlushM = dut.core.FlushM; + assign FlushW = dut.core.FlushW; + assign InstrValidM = dut.core.ieu.InstrValidM; + assign InstrRawD = dut.core.ifu.InstrRawD; + assign PCM = dut.core.ifu.PCM; + assign Mcycle = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; + assign Minstret = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; + assign TrapM = dut.core.TrapM; + assign PrivilegeModeW = dut.core.priv.priv.privmode.PrivilegeModeW; + assign GPRAddr = dut.core.ieu.dp.regf.a3; + assign GPRWen = dut.core.ieu.dp.regf.we3; + assign GPRValue = dut.core.ieu.dp.regf.wd3; + assign FPRAddr = dut.core.fpu.fpu.fregfile.a4; + assign FPRWen = dut.core.fpu.fpu.fregfile.we4; + assign FPRValue = dut.core.fpu.fpu.fregfile.wd4; + + assign CSRArray[0] = dut.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 + assign CSRArray[1] = dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 + assign CSRArray[2] = dut.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 + assign CSRArray[3] = dut.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 + assign CSRArray[4] = dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 + assign CSRArray[5] = dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 + assign CSRArray[6] = dut.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 + assign CSRArray[7] = dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 + assign CSRArray[8] = dut.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 + assign CSRArray[9] = dut.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 + assign CSRArray[10] = dut.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 + assign CSRArray[11] = dut.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A + assign CSRArray[12] = dut.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 + assign CSRArray[13] = dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 + assign CSRArray[14] = dut.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 + assign CSRArray[15] = dut.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 + assign CSRArray[16] = 0; // 12'hF11 + assign CSRArray[17] = 0; // 12'hF12 + assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 + assign CSRArray[19] = 0; // 12'hF15 + assign CSRArray[20] = 0; // 12'h34A + // supervisor CSRs + assign CSRArray[21] = dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 + assign CSRArray[22] = dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 + assign CSRArray[23] = dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 + assign CSRArray[24] = dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 + assign CSRArray[25] = dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 + assign CSRArray[26] = dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A + assign CSRArray[27] = dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 + assign CSRArray[28] = dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 + assign CSRArray[29] = dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 + assign CSRArray[30] = dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 + assign CSRArray[31] = dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 + assign CSRArray[32] = dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D + // user CSRs + assign CSRArray[33] = dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 + assign CSRArray[34] = dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 + assign CSRArray[35] = {dut.core.priv.priv.csr.csru.csru.FRM_REGW, dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 + end // assign XLENZeros = '0; From 1c6ebb86a313aaae24ce9b09090cdfbc7d0dd9d3 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 20 Jun 2024 12:54:12 -0700 Subject: [PATCH 48/95] Added some debug code to count frames sent to the ethernet mac and frames sent to the phy. Removed the external reset of the phy and now it always reliably starts in the same way. The first 0x117 frames are always captured. --- fpga/rvvidaemon/rvvidaemon.c | 2 +- fpga/src/fpgaTopArtyA7.sv | 5 +++-- src/rvvi/packetizer.sv | 10 +++++++--- testbench/testbench.sv | 9 ++++++++- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 074ffa21c..8a714dee0 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -213,8 +213,8 @@ int main(int argc, char **argv){ DecodeRVVI(buf + headerbytes, payloadbytes, &InstructionData); // now let's drive IDV // start simple just drive and compare PC. - ProcessRvviAll(&InstructionData); PrintInstructionData(&InstructionData); + ProcessRvviAll(&InstructionData); } } diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index 51de188db..f495e2568 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -1134,7 +1134,7 @@ module fpgaTop packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(CPUCLK), .m_axi_aresetn(~bus_struct_reset), .RVVIStall, .RvviAxiWdata, .RvviAxiWstrb, .RvviAxiWlast, .RvviAxiWvalid, .RvviAxiWready); - eth_mac_mii_fifo #(.TARGET("GENERIC"), .CLOCK_INPUT_STYLE("BUFG"), .AXIS_DATA_WIDTH(32), .TX_FIFO_DEPTH(1024)) ethernet(.rst(bus_struct_reset), .logic_clk(CPUCLK), .logic_rst(bus_struct_reset), + eth_mac_mii_fifo #(.TARGET("XILINX"), .CLOCK_INPUT_STYLE("BUFG"), .AXIS_DATA_WIDTH(32), .TX_FIFO_DEPTH(1024)) ethernet(.rst(bus_struct_reset), .logic_clk(CPUCLK), .logic_rst(bus_struct_reset), .tx_axis_tdata(RvviAxiWdata), .tx_axis_tkeep(RvviAxiWstrb), .tx_axis_tvalid(RvviAxiWvalid), .tx_axis_tready(RvviAxiWready), .tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), .rx_axis_tlast(), .rx_axis_tuser(), @@ -1155,7 +1155,8 @@ module fpgaTop .cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1) ); - assign phy_reset_n = ~bus_struct_reset; + //assign phy_reset_n = ~bus_struct_reset; + assign phy_reset_n = ~1'b0; endmodule diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 8ccec184d..e12e9cd7e 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -62,7 +62,8 @@ module packetizer import cvw::*; #(parameter cvw_t P, typedef enum {STATE_RST, STATE_COUNT, STATE_RDY, STATE_WAIT, STATE_TRANS, STATE_TRANS_INSERT_DELAY} statetype; (* mark_debug = "true" *) statetype CurrState, NextState; - logic [31:0] RstCount; + logic [31:0] RstCount; +(* mark_debug = "true" *) logic [31:0] FrameCount; logic RstCountRst, RstCountEn, CountFlag, DelayFlag; @@ -101,8 +102,11 @@ module packetizer import cvw::*; #(parameter cvw_t P, counter #(32) rstcounter(m_axi_aclk, RstCountRst, RstCountEn, RstCount); assign CountFlag = RstCount == 32'd100000000; //assign CountFlag = RstCount == 32'd10; - //assign DelayFlag = RstCount == 32'd200; - assign DelayFlag = RstCount == 32'd0; + assign DelayFlag = RstCount == 32'd200; + //assign DelayFlag = RstCount == 32'd0; + + counter #(32) framecounter(m_axi_aclk, ~m_axi_aresetn, (RvviAxiWready & RvviAxiWlast), FrameCount); + flopenr #(187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)) rvvireg(m_axi_aclk, ~m_axi_aresetn, valid, rvvi, rvviDelay); diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 399a5453d..098280423 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -633,7 +633,14 @@ module testbench; .rx_error_bad_fcs, .rx_fifo_overflow, .rx_fifo_bad_frame, .rx_fifo_good_frame, .cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1) ); - + + logic MiiTxEnDelay; + logic EthernetTXCounterEn; + logic [31:0] EthernetTXCount; + flopr #(1) txedgereg(clk, reset, mii_tx_en, MiiTxEnDelay); + assign EthernetTXCounterEn = ~mii_tx_en & MiiTxEnDelay; + counter #(32) ethernexttxcounter(clk, reset, EthernetTXCounterEn, EthernetTXCount); + end else begin assign RVVIStall = '0; end From 249d58244a3283236feed21ba21ad20f592201c5 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 20 Jun 2024 15:48:30 -0700 Subject: [PATCH 49/95] It's working!!!!!! --- fpga/rvvidaemon/rvviApi.h | 697 ++++++++++++++++++++++++++++++++++++++ src/rvvi/packetizer.sv | 2 +- 2 files changed, 698 insertions(+), 1 deletion(-) create mode 100644 fpga/rvvidaemon/rvviApi.h diff --git a/fpga/rvvidaemon/rvviApi.h b/fpga/rvvidaemon/rvviApi.h new file mode 100644 index 000000000..d37286781 --- /dev/null +++ b/fpga/rvvidaemon/rvviApi.h @@ -0,0 +1,697 @@ +/* + * Copyright (c) 2005-2023 Imperas Software Ltd., www.imperas.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#pragma once + +/*! \file rvviApi.h + * \brief RVVI interface, C API header. +**/ + +#include + +typedef uint32_t bool_t; + +#define RVVI_API_VERSION_MAJOR 1 +#define RVVI_API_VERSION_MINOR 34 +#define RVVI_TRUE 1 +#define RVVI_FALSE 0 +#define RVVI_INVALID_INDEX -1 +#define RVVI_MEMORY_PRIVILEGE_READ 1 +#define RVVI_MEMORY_PRIVILEGE_WRITE 2 +#define RVVI_MEMORY_PRIVILEGE_EXEC 4 +#define RVVI_API_VERSION ((RVVI_API_VERSION_MAJOR << 24) | RVVI_API_VERSION_MINOR) + +typedef enum { + RVVI_METRIC_RETIRES = 0, + RVVI_METRIC_TRAPS = 1, + RVVI_METRIC_MISMATCHES = 2, + RVVI_METRIC_COMPARISONS_PC = 3, + RVVI_METRIC_COMPARISONS_GPR = 4, + RVVI_METRIC_COMPARISONS_FPR = 5, + RVVI_METRIC_COMPARISONS_CSR = 6, + RVVI_METRIC_COMPARISONS_VR = 7, + RVVI_METRIC_COMPARISONS_INSBIN = 8, + RVVI_METRIC_CYCLES = 9, + RVVI_METRIC_ERRORS = 10, + RVVI_METRIC_WARNINGS = 11, + RVVI_METRIC_FATALS = 12, +} rvviMetricE; + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \brief Check the compiled RVVI API version. + * + * Makes sure the RVVI implementation linked with matches the versions defined in this header file. This should be called before any other RVVI API function. If this function returns RVVI_FALSE, no other RVVI API function should be called. + * + * \param version Should be set to RVVI_API_VERSION. + * + * \return RVVI_TRUE if versions matches otherwise RVVI_FALSE. +**/ +extern bool_t rvviVersionCheck( + uint32_t version); + +/*! \brief Initialize the DV reference model. + * + * \param programPath File path of the ELF file to be executed. This parameter can be NULL if required. + * + * \return RVVI_TRUE if the reference was initialized successfully else RVVI_FALSE. + * + * \note The reference model will begin execution from the entry point of the provided ELF file but can be overridden by the rvviRefPcSet() function. +**/ +extern bool_t rvviRefInit( + const char *programPath); + +/*! \brief Force the PC of the reference model to be particular value. + * + * \param hartId The hart to change the PC register of. + * \param address The address to change the PC register to. + * + * \return RVVI_TRUE on success else RVVI_FALSE. +**/ +extern bool_t rvviRefPcSet( + uint32_t hartId, + uint64_t address); + +/*! \brief Shutdown the reference module releasing any used resources. + * + * \return Returns RVVI_TRUE if shutdown was successful else RVVI_FALSE. +**/ +extern bool_t rvviRefShutdown(void); + +/*! \brief Notify the reference that a CSR is considered volatile. + * + * \param hartId The hart that will have its CSR made volatile. + * \param csrIndex Index of the CSR register to be considered volatile (0x0 to 0xfff). + * + * \return Returns RVVI_TRUE if operation was successful else RVVI_FALSE. +**/ +extern bool_t rvviRefCsrSetVolatile( + uint32_t hartId, + uint32_t csrIndex); + +/*! \brief Notify the reference that a memory region is volatile. + * + * \param addressLow Lower address of the volatile memory region + * \param addressHigh Upper address of the volatile memory region (inclusive) + * + * \return Returns RVVI_TRUE if operation was successful else RVVI_FALSE. +**/ +extern bool_t rvviRefMemorySetVolatile( + uint64_t addressLow, + uint64_t addressHigh); + +/*! \brief Lookup a net on the reference model and return its index. + * + * \param name The net name to locate. + * + * \return Unique index for this net or RVVI_INVALID_INDEX if it was not found. + * + * \note Please consult the model datasheet for a list of valid net names. + * \note See also, rvviRefNetSet(). +**/ +extern uint64_t rvviRefNetIndexGet( + const char *name); + +/*! \brief Extract a byte from the reference models vector register. + * + * \param hartId The hart to extract the vector register byte from. + * \param vrIndex The vector register index (0 to 31). + * \param byteIndex The byte offset into the vector register (note 0 is LSB). + * + * \return Byte that has been extracted from the vector register. +**/ +extern uint8_t rvviRefVrGet( + uint32_t hartId, + uint32_t vrIndex, + uint32_t byteIndex); + +/*! \brief Notify RVVI that a byte in the DUTs vector register has changed. + * + * \param hartId The hart that has updated its vector register. + * \param vrIndex The vector register index (0 to 31). + * \param byteIndex The byte offset into the vector register (note 0 is LSB). + * \param data New byte value in the DUTs vector register. +**/ +extern void rvviDutVrSet( + uint32_t hartId, + uint32_t vrIndex, + uint32_t byteIndex, + uint8_t data); + +/*! \brief Notify RVVI that a DUT floating point register has been written to. + * + * \param hartId The hart that has updated its FPR. + * \param fprIndex The FPR index within the register file (0 to 31). + * \param value The value that has been written. +**/ +extern void rvviDutFprSet( + uint32_t hartId, + uint32_t fprIndex, + uint64_t value); + +/*! \brief Notify RVVI that a DUT GPR has been written to. + * + * \param hartId The hart that has updated its GPR. + * \param gprIndex The GPR index within the register file. + * \param value The value that has been written. +**/ +extern void rvviDutGprSet( + uint32_t hartId, + uint32_t gprIndex, + uint64_t value); + +/*! \brief Notify RVVI that a DUT CSR has been written to. + * + * \param hartId The hart that has updated its CSR. + * \param csrIndex The CSR index (0x0 to 0xfff). + * \param value The value that has been written. +**/ +extern void rvviDutCsrSet( + uint32_t hartId, + uint32_t csrIndex, + uint64_t value); + +/*! \brief Place a net in a specific net group. + * + * \param netIndex The net index returned prior by rvviRefNetIndexGet(). + * \param group The group index to place this net into. +**/ +extern void rvviRefNetGroupSet( + uint64_t netIndex, + uint32_t group); + +/*! \brief Propagate a net change to the reference model. + * + * \param netIndex The net index returned prior by rvviRefNetIndexGet(). + * \param value The new value to set the net state to. + * \param when Time of arrival of this net, in simulation time. The `when` parameter may be measured in simulation time or cycles. It allows the RVVI-API to know which net changes have arrived at the same time. +**/ +extern void rvviRefNetSet( + uint64_t netIndex, + uint64_t value, + uint64_t when); + +/*! \brief Read the state of a net on the reference model. + * + * \param netIndex The net index returned prior by rvviRefNetIndexGet(). + * + * \return The value present on the specified net. +**/ +extern uint64_t rvviRefNetGet( + uint64_t netIndex); + +/*! \brief Notify the reference that a DUT instruction has retired. + * + * \param hartId The hart that has retired an instruction. + * \param dutPc The address of the instruction that has retired. + * \param dutInsBin The binary instruction representation. + * \param debugMode True if this instruction was executed in debug mode. +**/ +extern void rvviDutRetire( + uint32_t hartId, + uint64_t dutPc, + uint64_t dutInsBin, + bool_t debugMode); + +/*! \brief Notify the reference that the DUT received a trap. + * + * \param hartId The hart that has retired an instruction. + * \param dutPc The address of the instruction that has retired. + * \param dutInsBin The binary instruction representation. +**/ +extern void rvviDutTrap( + uint32_t hartId, + uint64_t dutPc, + uint64_t dutInsBin); + +/*! \brief Invalidate the reference models LR/SC reservation. + * + * \param hartId The hart of which the LR/SC reservation will be made invalid. +**/ +extern void rvviRefReservationInvalidate( + uint32_t hartId); + +/*! \brief Step the reference model until the next event. + * + * \param hartId The ID of the hart that is being stepped. + * + * \return Returns RVVI_TRUE if the step was successful else RVVI_FALSE. +**/ +extern bool_t rvviRefEventStep( + uint32_t hartId); + +/*! \brief Compare all GPR register values between reference and DUT. + * + * \param hartId The ID of the hart that is being compared. + * + * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. +**/ +extern bool_t rvviRefGprsCompare( + uint32_t hartId); + +/*! \brief Compare GPR registers that have been written to between the reference and DUT. This can be seen as a super set of the rvviRefGprsCompare function. This comparator will also flag differences in the set of registers that have been written to. + * + * \param hartId The ID of the hart that is being compared. + * \param ignoreX0 RVVI_TRUE to not compare writes to the x0 register, which may be treated as a special case, otherwise RVVI_FALSE. + * + * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. +**/ +extern bool_t rvviRefGprsCompareWritten( + uint32_t hartId, + bool_t ignoreX0); + +/*! \brief Compare retired instruction bytes between reference and DUT. + * + * \param hartId The ID of the hart that is being compared. + * + * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. +**/ +extern bool_t rvviRefInsBinCompare( + uint32_t hartId); + +/*! \brief Compare program counter for the retired instructions between DUT and the the reference model. + * + * \param hartId The ID of the hart that is being compared. + * + * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. +**/ +extern bool_t rvviRefPcCompare( + uint32_t hartId); + +/*! \brief Compare a CSR value between DUT and the the reference model. + * + * \param hartId The ID of the hart that is being compared. + * \param csrIndex The index of the CSR register being compared. + * + * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. +**/ +extern bool_t rvviRefCsrCompare( + uint32_t hartId, + uint32_t csrIndex); + +/*! \brief Enable or disable comparison of a specific CSR during rvviRefCsrsCompare. + * + * \param hartId The ID of the hart that this should apply to. + * \param csrIndex The index of the CSR to enable or disable comparison of. + * \param enableState RVVI_TRUE to enable comparison or RVVI_FALSE to disable. +**/ +extern void rvviRefCsrCompareEnable( + uint32_t hartId, + uint32_t csrIndex, + bool_t enableState); + +/*! \brief Specify a bitmask to direct bit level CSR comparisons. + * + * \param hartId The ID of the hart that this should apply to. + * \param csrIndex The index of the CSR to control the comparison of. + * \param mask Bitmask to enable or disable bits during CSR compare operations. Bits set to 1 will be compared and 0 bits are ignored. +**/ +extern void rvviRefCsrCompareMask( + uint32_t hartId, + uint32_t csrIndex, + uint64_t mask); + +/*! \brief Compare all CSR values between DUT and the the reference model. + * + * This function will compare the value of all CSRs between the reference and the DUT. Note that specific CSRs can be removed from this comparison by using the rvviRefCsrCompareEnable function. + * + * \param hartId The ID of the hart that is being compared. + * + * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. +**/ +extern bool_t rvviRefCsrsCompare( + uint32_t hartId); + +/*! \brief Compare all RVV vector register values between reference and DUT. + * + * \param hartId The ID of the hart that is being compared. + * + * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. +**/ +extern bool_t rvviRefVrsCompare( + uint32_t hartId); + +/*! \brief Compare all floating point register values between reference and DUT. + * + * \param hartId The ID of the hart that is being compared. + * + * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. +**/ +extern bool_t rvviRefFprsCompare( + uint32_t hartId); + +/*! \brief Write to the GPR of a hart in the reference model. + * + * \param hartId The hart to write the GPR of. + * \param gprIndex Index of the GPR register to write. + * \param gprValue Value to write into the GPR register. +**/ +extern void rvviRefGprSet( + uint32_t hartId, + uint32_t gprIndex, + uint64_t gprValue); + +/*! \brief Read a GPR value from a hart in the reference model. + * + * \param hartId The hart to retrieve the GPR from. + * \param gprIndex Index of the GPR register to read. + * + * \return GPR value read from the reference model. +**/ +extern uint64_t rvviRefGprGet( + uint32_t hartId, + uint32_t gprIndex); + +/*! \brief Read a GPR written mask from the last rvviRefEventStep. + * + * Each bit index in the mask returned indicates if the corresponding GPR has been written to by the reference model. Ie, if bit 3 is set, then X3 was written to. + * + * \param hartId The hart to retrieve the GPR written mask from. + * + * \return The GPR written mask. +**/ +extern uint32_t rvviRefGprsWrittenGet( + uint32_t hartId); + +/*! \brief Return the program counter of a hart in the reference model. + * + * \param hartId The hart to retrieve the PC from. + * + * \return The program counter of the specified hart. +**/ +extern uint64_t rvviRefPcGet( + uint32_t hartId); + +/*! \brief Read a CSR value from a hart in the reference model. + * + * \param hartId The hart to retrieve the CSR from. + * \param csrIndex Index of the CSR register to read (0x0 to 0xfff). + * + * \return The CSR register value read from the specified hart. +**/ +extern uint64_t rvviRefCsrGet( + uint32_t hartId, + uint32_t csrIndex); + +/*! \brief Return the binary representation of the previously retired instruction. + * + * \param hartId The hart to retrieve the instruction from. + * + * \return The instruction bytes. +**/ +extern uint64_t rvviRefInsBinGet( + uint32_t hartId); + +/*! \brief Write the value of a floating point register for a hart in the reference model. + * + * \param hartId The hart to retrieve the FPR register from. + * \param fprIndex Index of the floating point register to read. + * \param fprValue The bit pattern to be written into the floating point register. +**/ +extern void rvviRefFprSet( + uint32_t hartId, + uint32_t fprIndex, + uint64_t fprValue); + +/*! \brief Read a floating point register value from a hart in the reference model. + * + * \param hartId The hart to retrieve the FPR register from. + * \param fprIndex Index of the floating point register to read. + * + * \return The FPR register value read from the specified hart. +**/ +extern uint64_t rvviRefFprGet( + uint32_t hartId, + uint32_t fprIndex); + +/*! \brief Notify RVVI that the DUT has been written to memory. + * + * \param hartId The hart that issued the data bus write. + * \param address The address the hart is writing to. + * \param value The value placed on the data bus. + * \param byteEnableMask The byte enable mask provided for this write. + * + * \note Bus writes larger than 64bits should be reported using multiple calls to this function. + * \note byteEnableMask bit 0 corresponds to address+0, bEnMask bit 1 corresponds to address+1, etc. +**/ +extern void rvviDutBusWrite( + uint32_t hartId, + uint64_t address, + uint64_t value, + uint64_t byteEnableMask); + +/*! \brief Write data to the reference models physical memory space. + * + * \param hartId The hart to write from the perspective of. + * \param address The address being written to. + * \param data The data byte being written into memory. + * \param size Size of the data being written in bytes (1 to 8). +**/ +extern void rvviRefMemoryWrite( + uint32_t hartId, + uint64_t address, + uint64_t data, + uint32_t size); + +/*! \brief Read data from the reference models physical memory space. + * + * \param hartId The hart to read from the perspective of. + * \param address The address being read from. + * \param size Size of the data being read in bytes (1 to 8). + * + * \return The data that has been read from reference memory. +**/ +extern uint64_t rvviRefMemoryRead( + uint32_t hartId, + uint64_t address, + uint32_t size); + +/*! \brief Disassemble an arbitrary instruction encoding. + * + * \param hartId Hart with the ISA we are disassembling for. + * \param address Address of the instruction in memory. + * \param insBin The raw instruction that should be disassembled. + * + * \return Null terminated string containing the disassembly. +**/ +extern const char *rvviDasmInsBin( + uint32_t hartId, + uint64_t address, + uint64_t insBin); + +/*! \brief Return the name of a CSR in the reference model. + * + * \param hartId Hart with the CSR we are looking up the name of. + * \param csrIndex The index of the CSR we are looking up (0x0 to 0xfff inclusive). + * + * \return Null terminated string containing the CSR name. +**/ +extern const char *rvviRefCsrName( + uint32_t hartId, + uint32_t csrIndex); + +/*! \brief Return the ABI name of a GPR in the reference model. + * + * \param hartId Hart with the GPR we are looking up the name of. + * \param gprIndex The index of the GPR we are looking up (0 to 31 inclusive). + * + * \return Null terminated string containing the GPR ABI name. +**/ +extern const char *rvviRefGprName( + uint32_t hartId, + uint32_t gprIndex); + +/*! \brief Check if a CSR is present in the reference model. + * + * \param hartId Hart with the CSR we are checking the presence of. + * \param csrIndex The index of the CSR we are checking for (0x0 to 0xfff inclusive). + * + * \return RVVI_TRUE if the CSR is present in the reference model else RVVI_FALSE. +**/ +extern bool_t rvviRefCsrPresent( + uint32_t hartId, + uint32_t csrIndex); + +/*! \brief Check if floating point registers are present in the reference model. + * + * \param hartId Hart Id we are checking for the presence of floating point registers. + * + * \return RVVI_TRUE if the floating point registers are present in the reference model else RVVI_FALSE. +**/ +extern bool_t rvviRefFprsPresent( + uint32_t hartId); + +/*! \brief Check if vector registers are present in the reference model. + * + * \param hartId Hart Id we are checking for the presence of vector registers. + * + * \return RVVI_TRUE if the vector registers are present in the reference model else RVVI_FALSE. +**/ +extern bool_t rvviRefVrsPresent( + uint32_t hartId); + +/*! \brief Return the name of a FPR in the reference model. + * + * \param hartId Hart with the FPR we are looking up the name of. + * \param fprIndex The index of the FPR we are looking up (0 to 31 inclusive). + * + * \return Null terminated string containing the FPR name. +**/ +extern const char *rvviRefFprName( + uint32_t hartId, + uint32_t fprIndex); + +/*! \brief Return the name of a vector register in the reference model. + * + * \param hartId Hart with the VR we are looking up the name of. + * \param vrIndex The index of the VR we are looking up (0 to 31 inclusive). + * + * \return Null terminated string containing the VR name. +**/ +extern const char *rvviRefVrName( + uint32_t hartId, + uint32_t vrIndex); + +/*! \brief Return a string detailing the last RVVI-API error. + * + * \return The error string or an empty string if no error has occurred. +**/ +extern const char *rvviErrorGet(void); + +/*! \brief Query a verification metric from the reference model. + * + * \param metric An enumeration identifying the metric to query and return. + * + * \return The scalar quantity that has been queried. +**/ +extern uint64_t rvviRefMetricGet( + rvviMetricE metric); + +/*! \brief Set the value of a CSR in the reference model. + * + * \param hartId The hart which we are modifying the CSR of. + * \param csrIndex The index of the CSR we are modifying (0x0 to 0xfff inclusive). + * \param value The value to write into the CSR. +**/ +extern void rvviRefCsrSet( + uint32_t hartId, + uint32_t csrIndex, + uint64_t value); + +/*! \brief Dump the current register state of a hart in the reference model. + * + * \param hartId The hart which we should dump the register state of. +**/ +extern void rvviRefStateDump( + uint32_t hartId); + +/*! \brief Load an additional program into the address space of the processor. + * + * \param programPath File path of the ELF file to be loaded into memory. + * + * \return RVVI_TRUE if the program was loaded successfully otherwise RVVI_FALSE +**/ +extern bool_t rvviRefProgramLoad( + const char *programPath); + +/*! \brief Apply fine grain control over a CSRs volatility in the reference model. + * + * \param hartId The hart that will have its CSR volatility adjusted. + * \param csrIndex Index of the CSR register to have its volatility modified (0x0 to 0xfff). + * \param csrMask Bitmask specifying volatility, set bits will be treated as volatile, clear bits are not + * + * \return Returns RVVI_TRUE if operation was successful else RVVI_FALSE. +**/ +extern bool_t rvviRefCsrSetVolatileMask( + uint32_t hartId, + uint32_t csrIndex, + uint64_t csrMask); + +/*! \brief Pass the current testbench cycle count to the RVVI implementation. + * + * \param cycleCount The current cycle count of the DUT. This value is directly related to, and must be consistent with, the `when` parameter for rvviRefNetSet(). +**/ +extern void rvviDutCycleCountSet( + uint64_t cycleCount); + +/*! \brief Pass a vendor specific integer configuration parameter to the RVVI implementation. + * + * \param configParam The configuration option that is to have its associated value set. This is vendor specific and not defined as part of the RVVI-API. + * \param value An integer containing the data that should be passed to the configuration option. + * + * \return Returns RVVI_TRUE if operation was successful else RVVI_FALSE. +**/ +extern bool_t rvviRefConfigSetInt( + uint64_t configParam, + uint64_t value); + +/*! \brief Pass a vendor specific string configuration parameter to the RVVI implementation. + * + * \param configParam The configuration option that is to have its associated value set. This is vendor specific and not defined as part of the RVVI-API. + * \param value A string containing the data that should be passed to the configuration option. + * + * \return Returns RVVI_TRUE if operation was successful else RVVI_FALSE. +**/ +extern bool_t rvviRefConfigSetString( + uint64_t configParam, + const char *value); + +/*! \brief Given the name of a CSR, its unique index/address will be returned. + * + * \param hartId HartId of the hart containing the CSR we are looking up the index of. + * \param csrName The CSR name for which the CSR index should be retrieved. + * + * \return Returns the CSR index if the operation was successful else RVVI_INVALID_INDEX. +**/ +extern uint32_t rvviRefCsrIndex( + uint32_t hartId, + const char *csrName); + +/*! \brief Set the privilege mode for a region of the address space. + * + * \param addrLo Lower address defining the memory region. + * \param addrHi Upper address defining the memory region (inclusive). + * \param access Access flags for this memory region; a combination of RVVI_PRIV_... flags or 0. + * + * \return Returns RVVI_TRUE if operation was successful else RVVI_FALSE. +**/ +extern bool_t rvviRefMemorySetPrivilege( + uint64_t addrLo, + uint64_t addrHi, + uint32_t access); + +/*! \brief Update a byte in one of the reference models vector registers. + * + * \param hartId The hart that should have its vector register updated. + * \param vrIndex The vector register index (0 to 31). + * \param byteIndex The byte offset into the vector register (note 0 is LSB). + * \param data New byte value to be written into the vector register. +**/ +extern void rvviRefVrSet( + uint32_t hartId, + uint32_t vrIndex, + uint32_t byteIndex, + uint8_t data); + +#ifdef __cplusplus +} // extern "C" +#endif + diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index e12e9cd7e..1599c28a9 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -102,7 +102,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, counter #(32) rstcounter(m_axi_aclk, RstCountRst, RstCountEn, RstCount); assign CountFlag = RstCount == 32'd100000000; //assign CountFlag = RstCount == 32'd10; - assign DelayFlag = RstCount == 32'd200; + assign DelayFlag = RstCount == 32'd800; //assign DelayFlag = RstCount == 32'd0; counter #(32) framecounter(m_axi_aclk, ~m_axi_aresetn, (RvviAxiWready & RvviAxiWlast), FrameCount); From fa26c9a8b5382d2d94b8e17c15e54d7b3212710f Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 25 Jun 2024 13:07:46 -0700 Subject: [PATCH 50/95] Added pipe to vivado to create ila trigger from rvvidaemon. --- fpga/rvvidaemon/rvvidaemon.c | 46 +++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 8a714dee0..f6019dd19 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -66,6 +66,7 @@ //#define ETHER_TYPE 0x0000 // The type defined in packetizer.sv #define DEFAULT_IF "eno1" +FILE *VivadoPipeFP; typedef struct { uint64_t PC; @@ -95,10 +96,10 @@ typedef struct { void DecodeRVVI(uint8_t *payload, ssize_t payloadsize, RequiredRVVI_t *InstructionData); void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length); void PrintInstructionData(RequiredRVVI_t *InstructionData); -void ProcessRvviAll(RequiredRVVI_t *InstructionData); +int ProcessRvviAll(RequiredRVVI_t *InstructionData); void set_gpr(int hart, int reg, uint64_t value); void set_fpr(int hart, int reg, uint64_t value); -void state_compare(int hart, uint64_t Minstret); +int state_compare(int hart, uint64_t Minstret); int main(int argc, char **argv){ @@ -108,6 +109,24 @@ int main(int argc, char **argv){ return -1; } + // step 1 open a pipe to vivado + if (( VivadoPipeFP = popen("sort", "w")) == NULL){ + perror("popen"); + exit(1); + } + fputs("open_hw_manager\n", VivadoPipeFP); + fputs("connect_hw_server -url localhost:3121\n", VivadoPipeFP); + fputs("current_hw_target [get_hw_targets */xilinx_tcf/Digilent/*]\n", VivadoPipeFP); + fputs("open_hw_target\n", VivadoPipeFP); + fputs("set_property PARAM.FREQUENCY 7500000 [get_hw_targets localhost:3121/xilinx_tcf/Digilent/210319B7CA87A]\n", VivadoPipeFP); + + // *** bug these need to made relative paths. + fputs("set_property PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); + fputs("set_property FULL_PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); + fputs("set_property PROGRAM.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.bit} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); + fputs("refresh_hw_device [lindex [get_hw_devices xc7a100t_0] 0]\n", VivadoPipeFP); + fputs("[get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}]]\n", VivadoPipeFP); + int sockfd; uint8_t buf[BUF_SIZ]; int sockopt; @@ -198,6 +217,7 @@ int main(int argc, char **argv){ numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL); headerbytes = (sizeof(struct ether_header)); payloadbytes = numbytes - headerbytes; + int result; //printf("listener: got frame %lu bytes\n", numbytes); //printf("payload size: %lu bytes\n", payloadbytes); if (eh->ether_dhost[0] == DEST_MAC0 && @@ -214,10 +234,14 @@ int main(int argc, char **argv){ // now let's drive IDV // start simple just drive and compare PC. PrintInstructionData(&InstructionData); - ProcessRvviAll(&InstructionData); + result = ProcessRvviAll(&InstructionData); + if(result == -1) break; } } + printf("Simulation halted due to mismatch\n"); + + pclose(VivadoPipeFP); close(sockfd); @@ -225,12 +249,14 @@ int main(int argc, char **argv){ return 0; } -void ProcessRvviAll(RequiredRVVI_t *InstructionData){ +int ProcessRvviAll(RequiredRVVI_t *InstructionData){ long int found; uint64_t time = InstructionData->Mcycle; uint8_t trap = InstructionData->Trap; uint64_t order = InstructionData->Minstret; + int result; + result = 0; if(InstructionData->GPREn) set_gpr(0, InstructionData->GPRReg, InstructionData->GPRValue); if(InstructionData->FPREn) set_fpr(0, InstructionData->FPRReg, InstructionData->FPRValue); @@ -240,15 +266,15 @@ void ProcessRvviAll(RequiredRVVI_t *InstructionData){ rvviDutRetire(0, InstructionData->PC, InstructionData->insn, 0); } - if(!trap) state_compare(0, InstructionData->Minstret); - + if(!trap) result = state_compare(0, InstructionData->Minstret); // *** set is for nets like interrupts come back to this. //found = rvviRefNetIndexGet("pc_rdata"); //rvviRefNetSet(found, InstructionData->PC, time); + return result; } -void state_compare(int hart, uint64_t Minstret){ +int state_compare(int hart, uint64_t Minstret){ uint8_t result = 1; uint8_t stepOk = 0; char buf[80]; @@ -267,7 +293,11 @@ void state_compare(int hart, uint64_t Minstret){ if (result == 0) { sprintf(buf, "MISMATCH @ instruction # %ld\n", Minstret); idvMsgError(buf); - + fputs("run_hw_ila [get_hw_ilas -of_objects [get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}] -trigger_now\n", VivadoPipeFP); + fputs("current_hw_ila_data [upload_hw_ila_data hw_ila_1]\n", VivadoPipeFP); + fputs("display_hw_ila_data [current_hw_ila_data]\n", VivadoPipeFP); + fputs("write_hw_ila_data my_hw_ila_data [current_hw_ila_data]\n", VivadoPipeFP); + return -1; //if (ON_MISMATCH_DUMP_STATE) dump_state(hart); } From 74189e1e4b5c7633a5a29a4dad1198118bcc382a Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 25 Jun 2024 17:04:14 -0700 Subject: [PATCH 51/95] Have vivado triggering the ILA after the mismatch but the latency is way too long. --- fpga/rvvidaemon/rvvidaemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index f6019dd19..b2ccc2b63 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -110,7 +110,7 @@ int main(int argc, char **argv){ } // step 1 open a pipe to vivado - if (( VivadoPipeFP = popen("sort", "w")) == NULL){ + if (( VivadoPipeFP = popen("vivado -mode tcl", "w")) == NULL){ perror("popen"); exit(1); } From 612a281f62507bedd5b61f5f4ce24aa644cfd99c Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 26 Jun 2024 11:05:31 -0700 Subject: [PATCH 52/95] Added module to receive ethernet frame and trigger the ila. --- fpga/constraints/small-debug.xdc | 35 ++++++------ fpga/src/fpgaTopArtyA7.sv | 12 ++++- src/rvvi/triggergen.sv | 92 ++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 19 deletions(-) create mode 100644 src/rvvi/triggergen.sv diff --git a/fpga/constraints/small-debug.xdc b/fpga/constraints/small-debug.xdc index 62fcbe545..c2daf9fe1 100644 --- a/fpga/constraints/small-debug.xdc +++ b/fpga/constraints/small-debug.xdc @@ -3,8 +3,8 @@ create_debug_core u_ila_0 ila -set_property C_DATA_DEPTH 1024 [get_debug_cores u_ila_0] -set_property C_TRIGIN_EN false [get_debug_cores u_ila_0] +set_property C_DATA_DEPTH 8192 [get_debug_cores u_ila_0] +set_property C_TRIGIN_EN true [get_debug_cores u_ila_0] set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0] set_property C_ADV_TRIGGER false [get_debug_cores u_ila_0] set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0] @@ -19,14 +19,14 @@ set_property ALL_PROBE_SAME_MU_CNT 4 [get_debug_cores u_ila_0 ] endgroup connect_debug_port u_ila_0/clk [get_nets CPUCLK] -set_property port_width 64 [get_debug_ports u_ila_0/probe0] +set_property port_width 32 [get_debug_ports u_ila_0/probe0] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0] -connect_debug_port u_ila_0/probe0 [get_nets [list {wallypipelinedsoc/core/PCM[0]} {wallypipelinedsoc/core/PCM[1]} {wallypipelinedsoc/core/PCM[2]} {wallypipelinedsoc/core/PCM[3]} {wallypipelinedsoc/core/PCM[4]} {wallypipelinedsoc/core/PCM[5]} {wallypipelinedsoc/core/PCM[6]} {wallypipelinedsoc/core/PCM[7]} {wallypipelinedsoc/core/PCM[8]} {wallypipelinedsoc/core/PCM[9]} {wallypipelinedsoc/core/PCM[10]} {wallypipelinedsoc/core/PCM[11]} {wallypipelinedsoc/core/PCM[12]} {wallypipelinedsoc/core/PCM[13]} {wallypipelinedsoc/core/PCM[14]} {wallypipelinedsoc/core/PCM[15]} {wallypipelinedsoc/core/PCM[16]} {wallypipelinedsoc/core/PCM[17]} {wallypipelinedsoc/core/PCM[18]} {wallypipelinedsoc/core/PCM[19]} {wallypipelinedsoc/core/PCM[20]} {wallypipelinedsoc/core/PCM[21]} {wallypipelinedsoc/core/PCM[22]} {wallypipelinedsoc/core/PCM[23]} {wallypipelinedsoc/core/PCM[24]} {wallypipelinedsoc/core/PCM[25]} {wallypipelinedsoc/core/PCM[26]} {wallypipelinedsoc/core/PCM[27]} {wallypipelinedsoc/core/PCM[28]} {wallypipelinedsoc/core/PCM[29]} {wallypipelinedsoc/core/PCM[30]} {wallypipelinedsoc/core/PCM[31]} {wallypipelinedsoc/core/PCM[32]} {wallypipelinedsoc/core/PCM[33]} {wallypipelinedsoc/core/PCM[34]} {wallypipelinedsoc/core/PCM[35]} {wallypipelinedsoc/core/PCM[36]} {wallypipelinedsoc/core/PCM[37]} {wallypipelinedsoc/core/PCM[38]} {wallypipelinedsoc/core/PCM[39]} {wallypipelinedsoc/core/PCM[40]} {wallypipelinedsoc/core/PCM[41]} {wallypipelinedsoc/core/PCM[42]} {wallypipelinedsoc/core/PCM[43]} {wallypipelinedsoc/core/PCM[44]} {wallypipelinedsoc/core/PCM[45]} {wallypipelinedsoc/core/PCM[46]} {wallypipelinedsoc/core/PCM[47]} {wallypipelinedsoc/core/PCM[48]} {wallypipelinedsoc/core/PCM[49]} {wallypipelinedsoc/core/PCM[50]} {wallypipelinedsoc/core/PCM[51]} {wallypipelinedsoc/core/PCM[52]} {wallypipelinedsoc/core/PCM[53]} {wallypipelinedsoc/core/PCM[54]} {wallypipelinedsoc/core/PCM[55]} {wallypipelinedsoc/core/PCM[56]} {wallypipelinedsoc/core/PCM[57]} {wallypipelinedsoc/core/PCM[58]} {wallypipelinedsoc/core/PCM[59]} {wallypipelinedsoc/core/PCM[60]} {wallypipelinedsoc/core/PCM[61]} {wallypipelinedsoc/core/PCM[62]} {wallypipelinedsoc/core/PCM[63]} ]] +connect_debug_port u_ila_0/probe0 [get_nets [list {RvviAxiWdata[0]} {RvviAxiWdata[1]} {RvviAxiWdata[2]} {RvviAxiWdata[3]} {RvviAxiWdata[4]} {RvviAxiWdata[5]} {RvviAxiWdata[6]} {RvviAxiWdata[7]} {RvviAxiWdata[8]} {RvviAxiWdata[9]} {RvviAxiWdata[10]} {RvviAxiWdata[11]} {RvviAxiWdata[12]} {RvviAxiWdata[13]} {RvviAxiWdata[14]} {RvviAxiWdata[15]} {RvviAxiWdata[16]} {RvviAxiWdata[17]} {RvviAxiWdata[18]} {RvviAxiWdata[19]} {RvviAxiWdata[20]} {RvviAxiWdata[21]} {RvviAxiWdata[22]} {RvviAxiWdata[23]} {RvviAxiWdata[24]} {RvviAxiWdata[25]} {RvviAxiWdata[26]} {RvviAxiWdata[27]} {RvviAxiWdata[28]} {RvviAxiWdata[29]} {RvviAxiWdata[30]} {RvviAxiWdata[31]} ]] create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe1] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe1] -connect_debug_port u_ila_0/probe1 [get_nets [list wallypipelinedsoc/core/TrapM ]] +connect_debug_port u_ila_0/probe1 [get_nets [list RvviAxiWlast ]] create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe2] @@ -34,29 +34,29 @@ set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe2] connect_debug_port u_ila_0/probe2 [get_nets [list wallypipelinedsoc/core/InstrValidM ]] create_debug_port u_ila_0 probe -set_property port_width 32 [get_debug_ports u_ila_0/probe3] +set_property port_width 4 [get_debug_ports u_ila_0/probe3] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe3] -connect_debug_port u_ila_0/probe3 [get_nets [list {wallypipelinedsoc/core/InstrM[0]} {wallypipelinedsoc/core/InstrM[1]} {wallypipelinedsoc/core/InstrM[2]} {wallypipelinedsoc/core/InstrM[3]} {wallypipelinedsoc/core/InstrM[4]} {wallypipelinedsoc/core/InstrM[5]} {wallypipelinedsoc/core/InstrM[6]} {wallypipelinedsoc/core/InstrM[7]} {wallypipelinedsoc/core/InstrM[8]} {wallypipelinedsoc/core/InstrM[9]} {wallypipelinedsoc/core/InstrM[10]} {wallypipelinedsoc/core/InstrM[11]} {wallypipelinedsoc/core/InstrM[12]} {wallypipelinedsoc/core/InstrM[13]} {wallypipelinedsoc/core/InstrM[14]} {wallypipelinedsoc/core/InstrM[15]} {wallypipelinedsoc/core/InstrM[16]} {wallypipelinedsoc/core/InstrM[17]} {wallypipelinedsoc/core/InstrM[18]} {wallypipelinedsoc/core/InstrM[19]} {wallypipelinedsoc/core/InstrM[20]} {wallypipelinedsoc/core/InstrM[21]} {wallypipelinedsoc/core/InstrM[22]} {wallypipelinedsoc/core/InstrM[23]} {wallypipelinedsoc/core/InstrM[24]} {wallypipelinedsoc/core/InstrM[25]} {wallypipelinedsoc/core/InstrM[26]} {wallypipelinedsoc/core/InstrM[27]} {wallypipelinedsoc/core/InstrM[28]} {wallypipelinedsoc/core/InstrM[29]} {wallypipelinedsoc/core/InstrM[30]} {wallypipelinedsoc/core/InstrM[31]} ]] +connect_debug_port u_ila_0/probe3 [get_nets [list {ethernet/eth_mac_1g_mii_inst/mii_phy_if_inst/mac_mii_txd[0]} {ethernet/eth_mac_1g_mii_inst/mii_phy_if_inst/mac_mii_txd[1]} {ethernet/eth_mac_1g_mii_inst/mii_phy_if_inst/mac_mii_txd[2]} {ethernet/eth_mac_1g_mii_inst/mii_phy_if_inst/mac_mii_txd[3]} ]] create_debug_port u_ila_0 probe -set_property port_width 2 [get_debug_ports u_ila_0/probe4] +set_property port_width 4 [get_debug_ports u_ila_0/probe4] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe4] -connect_debug_port u_ila_0/probe4 [get_nets [list {wallypipelinedsoc/core/lsu/MemRWM[0]} {wallypipelinedsoc/core/lsu/MemRWM[1]} ]] +connect_debug_port u_ila_0/probe4 [get_nets [list {packetizer/CurrState[0]} {packetizer/CurrState[1]} {packetizer/CurrState[2]} {packetizer/CurrState[3]}]] create_debug_port u_ila_0 probe -set_property port_width 64 [get_debug_ports u_ila_0/probe5] +set_property port_width 1 [get_debug_ports u_ila_0/probe5] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe5] -connect_debug_port u_ila_0/probe5 [get_nets [list {wallypipelinedsoc/core/lsu/IEUAdrM[0]} {wallypipelinedsoc/core/lsu/IEUAdrM[1]} {wallypipelinedsoc/core/lsu/IEUAdrM[2]} {wallypipelinedsoc/core/lsu/IEUAdrM[3]} {wallypipelinedsoc/core/lsu/IEUAdrM[4]} {wallypipelinedsoc/core/lsu/IEUAdrM[5]} {wallypipelinedsoc/core/lsu/IEUAdrM[6]} {wallypipelinedsoc/core/lsu/IEUAdrM[7]} {wallypipelinedsoc/core/lsu/IEUAdrM[8]} {wallypipelinedsoc/core/lsu/IEUAdrM[9]} {wallypipelinedsoc/core/lsu/IEUAdrM[10]} {wallypipelinedsoc/core/lsu/IEUAdrM[11]} {wallypipelinedsoc/core/lsu/IEUAdrM[12]} {wallypipelinedsoc/core/lsu/IEUAdrM[13]} {wallypipelinedsoc/core/lsu/IEUAdrM[14]} {wallypipelinedsoc/core/lsu/IEUAdrM[15]} {wallypipelinedsoc/core/lsu/IEUAdrM[16]} {wallypipelinedsoc/core/lsu/IEUAdrM[17]} {wallypipelinedsoc/core/lsu/IEUAdrM[18]} {wallypipelinedsoc/core/lsu/IEUAdrM[19]} {wallypipelinedsoc/core/lsu/IEUAdrM[20]} {wallypipelinedsoc/core/lsu/IEUAdrM[21]} {wallypipelinedsoc/core/lsu/IEUAdrM[22]} {wallypipelinedsoc/core/lsu/IEUAdrM[23]} {wallypipelinedsoc/core/lsu/IEUAdrM[24]} {wallypipelinedsoc/core/lsu/IEUAdrM[25]} {wallypipelinedsoc/core/lsu/IEUAdrM[26]} {wallypipelinedsoc/core/lsu/IEUAdrM[27]} {wallypipelinedsoc/core/lsu/IEUAdrM[28]} {wallypipelinedsoc/core/lsu/IEUAdrM[29]} {wallypipelinedsoc/core/lsu/IEUAdrM[30]} {wallypipelinedsoc/core/lsu/IEUAdrM[31]} {wallypipelinedsoc/core/lsu/IEUAdrM[32]} {wallypipelinedsoc/core/lsu/IEUAdrM[33]} {wallypipelinedsoc/core/lsu/IEUAdrM[34]} {wallypipelinedsoc/core/lsu/IEUAdrM[35]} {wallypipelinedsoc/core/lsu/IEUAdrM[36]} {wallypipelinedsoc/core/lsu/IEUAdrM[37]} {wallypipelinedsoc/core/lsu/IEUAdrM[38]} {wallypipelinedsoc/core/lsu/IEUAdrM[39]} {wallypipelinedsoc/core/lsu/IEUAdrM[40]} {wallypipelinedsoc/core/lsu/IEUAdrM[41]} {wallypipelinedsoc/core/lsu/IEUAdrM[42]} {wallypipelinedsoc/core/lsu/IEUAdrM[43]} {wallypipelinedsoc/core/lsu/IEUAdrM[44]} {wallypipelinedsoc/core/lsu/IEUAdrM[45]} {wallypipelinedsoc/core/lsu/IEUAdrM[46]} {wallypipelinedsoc/core/lsu/IEUAdrM[47]} {wallypipelinedsoc/core/lsu/IEUAdrM[48]} {wallypipelinedsoc/core/lsu/IEUAdrM[49]} {wallypipelinedsoc/core/lsu/IEUAdrM[50]} {wallypipelinedsoc/core/lsu/IEUAdrM[51]} {wallypipelinedsoc/core/lsu/IEUAdrM[52]} {wallypipelinedsoc/core/lsu/IEUAdrM[53]} {wallypipelinedsoc/core/lsu/IEUAdrM[54]} {wallypipelinedsoc/core/lsu/IEUAdrM[55]} {wallypipelinedsoc/core/lsu/IEUAdrM[56]} {wallypipelinedsoc/core/lsu/IEUAdrM[57]} {wallypipelinedsoc/core/lsu/IEUAdrM[58]} {wallypipelinedsoc/core/lsu/IEUAdrM[59]} {wallypipelinedsoc/core/lsu/IEUAdrM[60]} {wallypipelinedsoc/core/lsu/IEUAdrM[61]} {wallypipelinedsoc/core/lsu/IEUAdrM[62]} {wallypipelinedsoc/core/lsu/IEUAdrM[63]} ]] +connect_debug_port u_ila_0/probe5 [get_nets [list {ethernet/eth_mac_1g_mii_inst/mii_phy_if_inst/mac_mii_tx_en} ]] create_debug_port u_ila_0 probe set_property port_width 64 [get_debug_ports u_ila_0/probe6] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6] -connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/lsu/ReadDataM[0]} {wallypipelinedsoc/core/lsu/ReadDataM[1]} {wallypipelinedsoc/core/lsu/ReadDataM[2]} {wallypipelinedsoc/core/lsu/ReadDataM[3]} {wallypipelinedsoc/core/lsu/ReadDataM[4]} {wallypipelinedsoc/core/lsu/ReadDataM[5]} {wallypipelinedsoc/core/lsu/ReadDataM[6]} {wallypipelinedsoc/core/lsu/ReadDataM[7]} {wallypipelinedsoc/core/lsu/ReadDataM[8]} {wallypipelinedsoc/core/lsu/ReadDataM[9]} {wallypipelinedsoc/core/lsu/ReadDataM[10]} {wallypipelinedsoc/core/lsu/ReadDataM[11]} {wallypipelinedsoc/core/lsu/ReadDataM[12]} {wallypipelinedsoc/core/lsu/ReadDataM[13]} {wallypipelinedsoc/core/lsu/ReadDataM[14]} {wallypipelinedsoc/core/lsu/ReadDataM[15]} {wallypipelinedsoc/core/lsu/ReadDataM[16]} {wallypipelinedsoc/core/lsu/ReadDataM[17]} {wallypipelinedsoc/core/lsu/ReadDataM[18]} {wallypipelinedsoc/core/lsu/ReadDataM[19]} {wallypipelinedsoc/core/lsu/ReadDataM[20]} {wallypipelinedsoc/core/lsu/ReadDataM[21]} {wallypipelinedsoc/core/lsu/ReadDataM[22]} {wallypipelinedsoc/core/lsu/ReadDataM[23]} {wallypipelinedsoc/core/lsu/ReadDataM[24]} {wallypipelinedsoc/core/lsu/ReadDataM[25]} {wallypipelinedsoc/core/lsu/ReadDataM[26]} {wallypipelinedsoc/core/lsu/ReadDataM[27]} {wallypipelinedsoc/core/lsu/ReadDataM[28]} {wallypipelinedsoc/core/lsu/ReadDataM[29]} {wallypipelinedsoc/core/lsu/ReadDataM[30]} {wallypipelinedsoc/core/lsu/ReadDataM[31]} {wallypipelinedsoc/core/lsu/ReadDataM[32]} {wallypipelinedsoc/core/lsu/ReadDataM[33]} {wallypipelinedsoc/core/lsu/ReadDataM[34]} {wallypipelinedsoc/core/lsu/ReadDataM[35]} {wallypipelinedsoc/core/lsu/ReadDataM[36]} {wallypipelinedsoc/core/lsu/ReadDataM[37]} {wallypipelinedsoc/core/lsu/ReadDataM[38]} {wallypipelinedsoc/core/lsu/ReadDataM[39]} {wallypipelinedsoc/core/lsu/ReadDataM[40]} {wallypipelinedsoc/core/lsu/ReadDataM[41]} {wallypipelinedsoc/core/lsu/ReadDataM[42]} {wallypipelinedsoc/core/lsu/ReadDataM[43]} {wallypipelinedsoc/core/lsu/ReadDataM[44]} {wallypipelinedsoc/core/lsu/ReadDataM[45]} {wallypipelinedsoc/core/lsu/ReadDataM[46]} {wallypipelinedsoc/core/lsu/ReadDataM[47]} {wallypipelinedsoc/core/lsu/ReadDataM[48]} {wallypipelinedsoc/core/lsu/ReadDataM[49]} {wallypipelinedsoc/core/lsu/ReadDataM[50]} {wallypipelinedsoc/core/lsu/ReadDataM[51]} {wallypipelinedsoc/core/lsu/ReadDataM[52]} {wallypipelinedsoc/core/lsu/ReadDataM[53]} {wallypipelinedsoc/core/lsu/ReadDataM[54]} {wallypipelinedsoc/core/lsu/ReadDataM[55]} {wallypipelinedsoc/core/lsu/ReadDataM[56]} {wallypipelinedsoc/core/lsu/ReadDataM[57]} {wallypipelinedsoc/core/lsu/ReadDataM[58]} {wallypipelinedsoc/core/lsu/ReadDataM[59]} {wallypipelinedsoc/core/lsu/ReadDataM[60]} {wallypipelinedsoc/core/lsu/ReadDataM[61]} {wallypipelinedsoc/core/lsu/ReadDataM[62]} {wallypipelinedsoc/core/lsu/ReadDataM[63]} ]] +connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/PCM[0]} {wallypipelinedsoc/core/PCM[1]} {wallypipelinedsoc/core/PCM[2]} {wallypipelinedsoc/core/PCM[3]} {wallypipelinedsoc/core/PCM[4]} {wallypipelinedsoc/core/PCM[5]} {wallypipelinedsoc/core/PCM[6]} {wallypipelinedsoc/core/PCM[7]} {wallypipelinedsoc/core/PCM[8]} {wallypipelinedsoc/core/PCM[9]} {wallypipelinedsoc/core/PCM[10]} {wallypipelinedsoc/core/PCM[11]} {wallypipelinedsoc/core/PCM[12]} {wallypipelinedsoc/core/PCM[13]} {wallypipelinedsoc/core/PCM[14]} {wallypipelinedsoc/core/PCM[15]} {wallypipelinedsoc/core/PCM[16]} {wallypipelinedsoc/core/PCM[17]} {wallypipelinedsoc/core/PCM[18]} {wallypipelinedsoc/core/PCM[19]} {wallypipelinedsoc/core/PCM[20]} {wallypipelinedsoc/core/PCM[21]} {wallypipelinedsoc/core/PCM[22]} {wallypipelinedsoc/core/PCM[23]} {wallypipelinedsoc/core/PCM[24]} {wallypipelinedsoc/core/PCM[25]} {wallypipelinedsoc/core/PCM[26]} {wallypipelinedsoc/core/PCM[27]} {wallypipelinedsoc/core/PCM[28]} {wallypipelinedsoc/core/PCM[29]} {wallypipelinedsoc/core/PCM[30]} {wallypipelinedsoc/core/PCM[31]} {wallypipelinedsoc/core/PCM[32]} {wallypipelinedsoc/core/PCM[33]} {wallypipelinedsoc/core/PCM[34]} {wallypipelinedsoc/core/PCM[35]} {wallypipelinedsoc/core/PCM[36]} {wallypipelinedsoc/core/PCM[37]} {wallypipelinedsoc/core/PCM[38]} {wallypipelinedsoc/core/PCM[39]} {wallypipelinedsoc/core/PCM[40]} {wallypipelinedsoc/core/PCM[41]} {wallypipelinedsoc/core/PCM[42]} {wallypipelinedsoc/core/PCM[43]} {wallypipelinedsoc/core/PCM[44]} {wallypipelinedsoc/core/PCM[45]} {wallypipelinedsoc/core/PCM[46]} {wallypipelinedsoc/core/PCM[47]} {wallypipelinedsoc/core/PCM[48]} {wallypipelinedsoc/core/PCM[49]} {wallypipelinedsoc/core/PCM[50]} {wallypipelinedsoc/core/PCM[51]} {wallypipelinedsoc/core/PCM[52]} {wallypipelinedsoc/core/PCM[53]} {wallypipelinedsoc/core/PCM[54]} {wallypipelinedsoc/core/PCM[55]} {wallypipelinedsoc/core/PCM[56]} {wallypipelinedsoc/core/PCM[57]} {wallypipelinedsoc/core/PCM[58]} {wallypipelinedsoc/core/PCM[59]} {wallypipelinedsoc/core/PCM[60]} {wallypipelinedsoc/core/PCM[61]} {wallypipelinedsoc/core/PCM[62]} {wallypipelinedsoc/core/PCM[63]} ]] create_debug_port u_ila_0 probe -set_property port_width 64 [get_debug_ports u_ila_0/probe7] +set_property port_width 32 [get_debug_ports u_ila_0/probe7] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7] -connect_debug_port u_ila_0/probe7 [get_nets [list {wallypipelinedsoc/core/lsu/WriteDataM[0]} {wallypipelinedsoc/core/lsu/WriteDataM[1]} {wallypipelinedsoc/core/lsu/WriteDataM[2]} {wallypipelinedsoc/core/lsu/WriteDataM[3]} {wallypipelinedsoc/core/lsu/WriteDataM[4]} {wallypipelinedsoc/core/lsu/WriteDataM[5]} {wallypipelinedsoc/core/lsu/WriteDataM[6]} {wallypipelinedsoc/core/lsu/WriteDataM[7]} {wallypipelinedsoc/core/lsu/WriteDataM[8]} {wallypipelinedsoc/core/lsu/WriteDataM[9]} {wallypipelinedsoc/core/lsu/WriteDataM[10]} {wallypipelinedsoc/core/lsu/WriteDataM[11]} {wallypipelinedsoc/core/lsu/WriteDataM[12]} {wallypipelinedsoc/core/lsu/WriteDataM[13]} {wallypipelinedsoc/core/lsu/WriteDataM[14]} {wallypipelinedsoc/core/lsu/WriteDataM[15]} {wallypipelinedsoc/core/lsu/WriteDataM[16]} {wallypipelinedsoc/core/lsu/WriteDataM[17]} {wallypipelinedsoc/core/lsu/WriteDataM[18]} {wallypipelinedsoc/core/lsu/WriteDataM[19]} {wallypipelinedsoc/core/lsu/WriteDataM[20]} {wallypipelinedsoc/core/lsu/WriteDataM[21]} {wallypipelinedsoc/core/lsu/WriteDataM[22]} {wallypipelinedsoc/core/lsu/WriteDataM[23]} {wallypipelinedsoc/core/lsu/WriteDataM[24]} {wallypipelinedsoc/core/lsu/WriteDataM[25]} {wallypipelinedsoc/core/lsu/WriteDataM[26]} {wallypipelinedsoc/core/lsu/WriteDataM[27]} {wallypipelinedsoc/core/lsu/WriteDataM[28]} {wallypipelinedsoc/core/lsu/WriteDataM[29]} {wallypipelinedsoc/core/lsu/WriteDataM[30]} {wallypipelinedsoc/core/lsu/WriteDataM[31]} {wallypipelinedsoc/core/lsu/WriteDataM[32]} {wallypipelinedsoc/core/lsu/WriteDataM[33]} {wallypipelinedsoc/core/lsu/WriteDataM[34]} {wallypipelinedsoc/core/lsu/WriteDataM[35]} {wallypipelinedsoc/core/lsu/WriteDataM[36]} {wallypipelinedsoc/core/lsu/WriteDataM[37]} {wallypipelinedsoc/core/lsu/WriteDataM[38]} {wallypipelinedsoc/core/lsu/WriteDataM[39]} {wallypipelinedsoc/core/lsu/WriteDataM[40]} {wallypipelinedsoc/core/lsu/WriteDataM[41]} {wallypipelinedsoc/core/lsu/WriteDataM[42]} {wallypipelinedsoc/core/lsu/WriteDataM[43]} {wallypipelinedsoc/core/lsu/WriteDataM[44]} {wallypipelinedsoc/core/lsu/WriteDataM[45]} {wallypipelinedsoc/core/lsu/WriteDataM[46]} {wallypipelinedsoc/core/lsu/WriteDataM[47]} {wallypipelinedsoc/core/lsu/WriteDataM[48]} {wallypipelinedsoc/core/lsu/WriteDataM[49]} {wallypipelinedsoc/core/lsu/WriteDataM[50]} {wallypipelinedsoc/core/lsu/WriteDataM[51]} {wallypipelinedsoc/core/lsu/WriteDataM[52]} {wallypipelinedsoc/core/lsu/WriteDataM[53]} {wallypipelinedsoc/core/lsu/WriteDataM[54]} {wallypipelinedsoc/core/lsu/WriteDataM[55]} {wallypipelinedsoc/core/lsu/WriteDataM[56]} {wallypipelinedsoc/core/lsu/WriteDataM[57]} {wallypipelinedsoc/core/lsu/WriteDataM[58]} {wallypipelinedsoc/core/lsu/WriteDataM[59]} {wallypipelinedsoc/core/lsu/WriteDataM[60]} {wallypipelinedsoc/core/lsu/WriteDataM[61]} {wallypipelinedsoc/core/lsu/WriteDataM[62]} {wallypipelinedsoc/core/lsu/WriteDataM[63]} ]] +connect_debug_port u_ila_0/probe7 [get_nets [list {packetizer/FrameCount[0]} {packetizer/FrameCount[1]} {packetizer/FrameCount[2]} {packetizer/FrameCount[3]} {packetizer/FrameCount[4]} {packetizer/FrameCount[5]} {packetizer/FrameCount[6]} {packetizer/FrameCount[7]} {packetizer/FrameCount[8]} {packetizer/FrameCount[9]} {packetizer/FrameCount[10]} {packetizer/FrameCount[11]} {packetizer/FrameCount[12]} {packetizer/FrameCount[13]} {packetizer/FrameCount[14]} {packetizer/FrameCount[15]} {packetizer/FrameCount[16]} {packetizer/FrameCount[17]} {packetizer/FrameCount[18]} {packetizer/FrameCount[19]} {packetizer/FrameCount[20]} {packetizer/FrameCount[21]} {packetizer/FrameCount[22]} {packetizer/FrameCount[23]} {packetizer/FrameCount[24]} {packetizer/FrameCount[25]} {packetizer/FrameCount[26]} {packetizer/FrameCount[27]} {packetizer/FrameCount[28]} {packetizer/FrameCount[29]} {packetizer/FrameCount[30]} {packetizer/FrameCount[31]} ]] create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe8] @@ -78,11 +78,10 @@ set_property port_width 1 [get_debug_ports u_ila_0/probe11] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe11] connect_debug_port u_ila_0/probe11 [get_nets [list {RvviAxiWvalid}]] -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe12] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe12] -connect_debug_port u_ila_0/probe12 [get_nets [list {bus_struct_reset}]] # the debug hub has issues with the clocks from the mmcm so lets give up an connect to the 100Mhz input clock. #connect_debug_port dbg_hub/clk [get_nets default_100mhz_clk] connect_debug_port dbg_hub/clk [get_nets CPUCLK] + +# connect the trig_in in of the ila to the +connect_debug_port u_ila_0/trig_in [get_nets [list {IlaTrigger}]] diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index f495e2568..811d32e4f 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -1128,6 +1128,14 @@ module fpgaTop (* mark_debug = "true" *) logic RvviAxiWvalid; (* mark_debug = "true" *) logic RvviAxiWready; + logic RvviAxiRdata [31:0]; + logic RvviAxiRstrb [3:0]; + logic RvviAxiRlast; + logic RvviAxiRvalid; +(* mark_debug = "true" *) logic IlaTrigger; + + + logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; @@ -1139,7 +1147,6 @@ module fpgaTop .tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), .rx_axis_tlast(), .rx_axis_tuser(), - // *** update these .mii_rx_clk(phy_rx_clk), .mii_rxd(phy_rxd), .mii_rx_dv(phy_rx_dv), @@ -1155,6 +1162,9 @@ module fpgaTop .cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1) ); + triggergen triggergen(.clk(CPUCLK), .reset(bus_struct_reset), .RvviAxiRdata, + .RvviAxiRstrb, .RvviAxiRlast, .RvviAxiRvalid, .IlaTrigger) + //assign phy_reset_n = ~bus_struct_reset; assign phy_reset_n = ~1'b0; diff --git a/src/rvvi/triggergen.sv b/src/rvvi/triggergen.sv new file mode 100644 index 000000000..f8dc4ba8d --- /dev/null +++ b/src/rvvi/triggergen.sv @@ -0,0 +1,92 @@ +/////////////////////////////////////////// +// triggergen.sv +// +// Written: Rose Thompson ross1728@gmail.com +// Created: June 26, 2024 +// Modified: June 26, 2024 +// +// Purpose: Scans for specific ethernet frame to generate an ila trigger. +// +// Documentation: +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module triggergen import cvw::*; ( + input logic clk, reset, + input logic [31:0] RvviAxiRdata, + input logic [3:0] RvviAxiRstrb, + input logic RvviAxiRlast, + input logic RvviAxiRvalid, + output logic IlaTrigger); + + typedef enum {STATE_RST, STATE_COMPARE, STATE_MISMATCH, STATE_TRIGGER, STATE_TRIGGER_DONE} statetype; +(* mark_debug = "true" *) statetype CurrState, NextState; + + logic [31:0] mem [4:0]; + logic [2:0] Counter; + logic CounterEn, CounterRst; + logic [31:0] RvviAxiRdataDelay; + logic [3:0] RvviAxiRstrbDelay; + logic RvviAxiRvalidDelay; + logic Match, Overflow, Mismatch, Threshold; + + assign mem[0] = 32'h0000_1654; // src mac [31:0] + assign mem[1] = 32'h6843_8F54; // dst mac [15:0], src mac [47:32] + assign mem[2] = 32'h4502_1111; // dst mac [47:16] + assign mem[3] = 32'h7274_005c; // "rt", ether type 005c + assign mem[4] = 32'h6e69_6769; // "igin" (trigin) + + flopenr #(32) rvviaxirdatareg(clk, reset, RvviAxiRvalid, RvviAxiRdata, RvviAxiRdataDelay); + flopenr #(4) rvviaxirstrbreg(clk, reset, RvviAxiRvalid, RvviAxiRstrb, RvviAxiRstrbDelay); + flopr #(1) rvviaxirvalidreg(clk, reset, RvviAxiRvalid, RvviAxiRvalidDelay); + + counter #(3) counter(clk, CounterRst, CounterEn, Counter); + + always_ff @(posedge clk) begin + if(reset) CurrState <= STATE_RST; + else CurrState <= NextState; + end + + always_comb begin + case(CurrState) + STATE_RST: if(RvviAxiRvalid) NextState = STATE_COMPARE; + else NextState = STATE_RST; + STATE_COMPARE: if(RvviAxiRlast) NextState = STATE_RST; + else if(Mismatch | Overflow) NextState = STATE_MISMATCH; + else if(Threshold & Match) NextState = STATE_TRIGGER; + else NextState = STATE_COMPARE; + STATE_MISMATCH: if(RvviAxiRlast) NextState = STATE_RST; + else NextState = STATE_MISMATCH; + STATE_TRIGGER: if(RvviAxiRlast) NextState = STATE_RST; + else NextState = STATE_TRIGGER_DONE; + STATE_TRIGGER_DONE: if(RvviAxiRlast) NextState = STATE_RST; + else NextState = STATE_TRIGGER_DONE; + default: NextState = STATE_RST; + endcase + end + + assign Match = (mem[Counter] == RvviAxiRdataDelay) & (CurrState == STATE_COMPARE) & RvviAxiRvalidDelay; + assign Overflow = Counter > 4'd4; + assign Threshold = Counter >= 4'd4; + assign Mismatch = (mem[Counter] != RvviAxiRdataDelay) & (CurrState == STATE_COMPARE) & RvviAxiRvalidDelay; + assign IlaTrigger = CurrState == STATE_TRIGGER; + assign CounterRst = CurrState == STATE_RST; + assign CounterEn = RvviAxiRvalid; + +endmodule From ccf4bb8ddc292fb9bbfe006452b3a3c5a8a38f2a Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 26 Jun 2024 16:15:46 -0700 Subject: [PATCH 53/95] Maybe have the incircuit trigger working. --- fpga/constraints/small-debug.xdc | 31 ++++++++++++++----------------- fpga/src/fpgaTopArtyA7.sv | 8 ++++---- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/fpga/constraints/small-debug.xdc b/fpga/constraints/small-debug.xdc index c2daf9fe1..b244a1747 100644 --- a/fpga/constraints/small-debug.xdc +++ b/fpga/constraints/small-debug.xdc @@ -1,22 +1,20 @@ create_debug_core u_ila_0 ila - - - - set_property C_DATA_DEPTH 8192 [get_debug_cores u_ila_0] set_property C_TRIGIN_EN true [get_debug_cores u_ila_0] set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0] -set_property C_ADV_TRIGGER false [get_debug_cores u_ila_0] set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0] -set_property C_EN_STRG_QUAL false [get_debug_cores u_ila_0] set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0] -set_property ALL_PROBE_SAME_MU_CNT 1 [get_debug_cores u_ila_0] -startgroup set_property C_EN_STRG_QUAL true [get_debug_cores u_ila_0 ] set_property C_ADV_TRIGGER true [get_debug_cores u_ila_0 ] set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0 ] set_property ALL_PROBE_SAME_MU_CNT 4 [get_debug_cores u_ila_0 ] -endgroup +create_debug_port u_ila_0 trig_in +create_debug_port u_ila_0 trig_in_ack +#set_property port_width 1 [get_debug_ports u_ila_0/trig_in] +#set_property port_width 1 [get_debug_ports u_ila_0/trig_in_ack] +#set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/trig_in] +connect_debug_port u_ila_0/trig_in [get_nets IlaTrigger] +#connect_debug_port u_ila_0/trig_in_ack [get_nets IlaTriggerAck] connect_debug_port u_ila_0/clk [get_nets CPUCLK] set_property port_width 32 [get_debug_ports u_ila_0/probe0] @@ -53,10 +51,15 @@ set_property port_width 64 [get_debug_ports u_ila_0/probe6] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6] connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/PCM[0]} {wallypipelinedsoc/core/PCM[1]} {wallypipelinedsoc/core/PCM[2]} {wallypipelinedsoc/core/PCM[3]} {wallypipelinedsoc/core/PCM[4]} {wallypipelinedsoc/core/PCM[5]} {wallypipelinedsoc/core/PCM[6]} {wallypipelinedsoc/core/PCM[7]} {wallypipelinedsoc/core/PCM[8]} {wallypipelinedsoc/core/PCM[9]} {wallypipelinedsoc/core/PCM[10]} {wallypipelinedsoc/core/PCM[11]} {wallypipelinedsoc/core/PCM[12]} {wallypipelinedsoc/core/PCM[13]} {wallypipelinedsoc/core/PCM[14]} {wallypipelinedsoc/core/PCM[15]} {wallypipelinedsoc/core/PCM[16]} {wallypipelinedsoc/core/PCM[17]} {wallypipelinedsoc/core/PCM[18]} {wallypipelinedsoc/core/PCM[19]} {wallypipelinedsoc/core/PCM[20]} {wallypipelinedsoc/core/PCM[21]} {wallypipelinedsoc/core/PCM[22]} {wallypipelinedsoc/core/PCM[23]} {wallypipelinedsoc/core/PCM[24]} {wallypipelinedsoc/core/PCM[25]} {wallypipelinedsoc/core/PCM[26]} {wallypipelinedsoc/core/PCM[27]} {wallypipelinedsoc/core/PCM[28]} {wallypipelinedsoc/core/PCM[29]} {wallypipelinedsoc/core/PCM[30]} {wallypipelinedsoc/core/PCM[31]} {wallypipelinedsoc/core/PCM[32]} {wallypipelinedsoc/core/PCM[33]} {wallypipelinedsoc/core/PCM[34]} {wallypipelinedsoc/core/PCM[35]} {wallypipelinedsoc/core/PCM[36]} {wallypipelinedsoc/core/PCM[37]} {wallypipelinedsoc/core/PCM[38]} {wallypipelinedsoc/core/PCM[39]} {wallypipelinedsoc/core/PCM[40]} {wallypipelinedsoc/core/PCM[41]} {wallypipelinedsoc/core/PCM[42]} {wallypipelinedsoc/core/PCM[43]} {wallypipelinedsoc/core/PCM[44]} {wallypipelinedsoc/core/PCM[45]} {wallypipelinedsoc/core/PCM[46]} {wallypipelinedsoc/core/PCM[47]} {wallypipelinedsoc/core/PCM[48]} {wallypipelinedsoc/core/PCM[49]} {wallypipelinedsoc/core/PCM[50]} {wallypipelinedsoc/core/PCM[51]} {wallypipelinedsoc/core/PCM[52]} {wallypipelinedsoc/core/PCM[53]} {wallypipelinedsoc/core/PCM[54]} {wallypipelinedsoc/core/PCM[55]} {wallypipelinedsoc/core/PCM[56]} {wallypipelinedsoc/core/PCM[57]} {wallypipelinedsoc/core/PCM[58]} {wallypipelinedsoc/core/PCM[59]} {wallypipelinedsoc/core/PCM[60]} {wallypipelinedsoc/core/PCM[61]} {wallypipelinedsoc/core/PCM[62]} {wallypipelinedsoc/core/PCM[63]} ]] +#create_debug_port u_ila_0 probe +#set_property port_width 1 [get_debug_ports u_ila_0/probe7] +#set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7] +#connect_debug_port u_ila_0/probe7 [get_nets [list {IlaTrigger} ]] + create_debug_port u_ila_0 probe -set_property port_width 32 [get_debug_ports u_ila_0/probe7] +set_property port_width 1 [get_debug_ports u_ila_0/probe7] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7] -connect_debug_port u_ila_0/probe7 [get_nets [list {packetizer/FrameCount[0]} {packetizer/FrameCount[1]} {packetizer/FrameCount[2]} {packetizer/FrameCount[3]} {packetizer/FrameCount[4]} {packetizer/FrameCount[5]} {packetizer/FrameCount[6]} {packetizer/FrameCount[7]} {packetizer/FrameCount[8]} {packetizer/FrameCount[9]} {packetizer/FrameCount[10]} {packetizer/FrameCount[11]} {packetizer/FrameCount[12]} {packetizer/FrameCount[13]} {packetizer/FrameCount[14]} {packetizer/FrameCount[15]} {packetizer/FrameCount[16]} {packetizer/FrameCount[17]} {packetizer/FrameCount[18]} {packetizer/FrameCount[19]} {packetizer/FrameCount[20]} {packetizer/FrameCount[21]} {packetizer/FrameCount[22]} {packetizer/FrameCount[23]} {packetizer/FrameCount[24]} {packetizer/FrameCount[25]} {packetizer/FrameCount[26]} {packetizer/FrameCount[27]} {packetizer/FrameCount[28]} {packetizer/FrameCount[29]} {packetizer/FrameCount[30]} {packetizer/FrameCount[31]} ]] +connect_debug_port u_ila_0/probe7 [get_nets [list {RvviAxiWvalid}]] create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe8] @@ -73,15 +76,9 @@ set_property port_width 1 [get_debug_ports u_ila_0/probe10] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe10] connect_debug_port u_ila_0/probe10 [get_nets [list {RvviAxiWready}]] -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe11] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe11] -connect_debug_port u_ila_0/probe11 [get_nets [list {RvviAxiWvalid}]] # the debug hub has issues with the clocks from the mmcm so lets give up an connect to the 100Mhz input clock. #connect_debug_port dbg_hub/clk [get_nets default_100mhz_clk] connect_debug_port dbg_hub/clk [get_nets CPUCLK] -# connect the trig_in in of the ila to the -connect_debug_port u_ila_0/trig_in [get_nets [list {IlaTrigger}]] diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index 811d32e4f..8202d735f 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -1128,8 +1128,8 @@ module fpgaTop (* mark_debug = "true" *) logic RvviAxiWvalid; (* mark_debug = "true" *) logic RvviAxiWready; - logic RvviAxiRdata [31:0]; - logic RvviAxiRstrb [3:0]; + logic [31:0] RvviAxiRdata; + logic [3:0] RvviAxiRstrb; logic RvviAxiRlast; logic RvviAxiRvalid; (* mark_debug = "true" *) logic IlaTrigger; @@ -1163,8 +1163,8 @@ module fpgaTop ); triggergen triggergen(.clk(CPUCLK), .reset(bus_struct_reset), .RvviAxiRdata, - .RvviAxiRstrb, .RvviAxiRlast, .RvviAxiRvalid, .IlaTrigger) - + .RvviAxiRstrb, .RvviAxiRlast, .RvviAxiRvalid, .IlaTrigger); + //assign phy_reset_n = ~bus_struct_reset; assign phy_reset_n = ~1'b0; From dc97ee5f8255740a9aadd206ae64da8e72c0000a Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 2 Jul 2024 09:12:34 -0700 Subject: [PATCH 54/95] Have some sample code which I know works transmisting a packet. --- fpga/rvvidaemon/rvvidaemon.c | 136 +++++++++++++++++++++++++++++------ fpga/rvvidaemon/send-copy.c | 112 +++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+), 23 deletions(-) create mode 100644 fpga/rvvidaemon/send-copy.c diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index b2ccc2b63..9876ebc20 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -41,9 +41,11 @@ #include #include #include +#include #include "rvviApi.h" // *** bug fix me when this file gets included into the correct directory. #include "idv/idv.h" +#include #define DEST_MAC0 0x43 #define DEST_MAC1 0x68 @@ -67,6 +69,8 @@ #define DEFAULT_IF "eno1" FILE *VivadoPipeFP; +int sockfd; +struct ifreq ifopts, if_mac; /* set promiscuous mode */ typedef struct { uint64_t PC; @@ -100,6 +104,7 @@ int ProcessRvviAll(RequiredRVVI_t *InstructionData); void set_gpr(int hart, int reg, uint64_t value); void set_fpr(int hart, int reg, uint64_t value); int state_compare(int hart, uint64_t Minstret); +void SendILATrigger(); int main(int argc, char **argv){ @@ -109,40 +114,57 @@ int main(int argc, char **argv){ return -1; } - // step 1 open a pipe to vivado - if (( VivadoPipeFP = popen("vivado -mode tcl", "w")) == NULL){ - perror("popen"); - exit(1); - } - fputs("open_hw_manager\n", VivadoPipeFP); - fputs("connect_hw_server -url localhost:3121\n", VivadoPipeFP); - fputs("current_hw_target [get_hw_targets */xilinx_tcf/Digilent/*]\n", VivadoPipeFP); - fputs("open_hw_target\n", VivadoPipeFP); - fputs("set_property PARAM.FREQUENCY 7500000 [get_hw_targets localhost:3121/xilinx_tcf/Digilent/210319B7CA87A]\n", VivadoPipeFP); + /* // step 1 open a pipe to vivado */ + /* if (( VivadoPipeFP = popen("vivado -mode tcl", "w")) == NULL){ */ + /* perror("popen"); */ + /* exit(1); */ + /* } */ + /* fputs("open_hw_manager\n", VivadoPipeFP); */ + /* fputs("connect_hw_server -url localhost:3121\n", VivadoPipeFP); */ + /* fputs("current_hw_target [get_hw_targets *\/xilinx_tcf/Digilent/\*]\n", VivadoPipeFP); */ + /* fputs("open_hw_target\n", VivadoPipeFP); */ + /* fputs("set_property PARAM.FREQUENCY 7500000 [get_hw_targets localhost:3121/xilinx_tcf/Digilent/210319B7CA87A]\n", VivadoPipeFP); */ - // *** bug these need to made relative paths. - fputs("set_property PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); - fputs("set_property FULL_PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); - fputs("set_property PROGRAM.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.bit} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); - fputs("refresh_hw_device [lindex [get_hw_devices xc7a100t_0] 0]\n", VivadoPipeFP); - fputs("[get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}]]\n", VivadoPipeFP); + /* // *** bug these need to made relative paths. */ + /* fputs("set_property PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); */ + /* fputs("set_property FULL_PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); */ + /* fputs("set_property PROGRAM.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.bit} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); */ + /* fputs("refresh_hw_device [lindex [get_hw_devices xc7a100t_0] 0]\n", VivadoPipeFP); */ + /* fputs("[get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}]]\n", VivadoPipeFP); */ + /* fflush(VivadoPipeFP); */ - int sockfd; uint8_t buf[BUF_SIZ]; int sockopt; - struct ifreq ifopts; /* set promiscuous mode */ struct ether_header *eh = (struct ether_header *) buf; ssize_t headerbytes, numbytes, payloadbytes; + /* Open RAW socket to receive frames */ if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) { + // *** remove. This is not the problem + //if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) { perror("socket"); } + printf("sockfd %x\n", sockfd); printf("Here 0\n"); /* Set interface to promiscuous mode - do we need to do this every time? */ + memset(&ifopts, 0, sizeof(struct ifreq)); strncpy(ifopts.ifr_name, argv[1], IFNAMSIZ-1); ioctl(sockfd, SIOCGIFFLAGS, &ifopts); + + /* Get the index of the interface to send on */ + //memset(&if_idx, 0, sizeof(struct ifreq)); + //strncpy(if_idx.ifr_name, argv[1], IFNAMSIZ-1); + if (ioctl(sockfd, SIOCGIFINDEX, &ifopts) < 0) + perror("SIOCGIFINDEX"); + + /* Get the MAC address of the interface to send on */ + memset(&if_mac, 0, sizeof(struct ifreq)); + strncpy(if_mac.ifr_name, argv[1], IFNAMSIZ-1); + if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0) + perror("SIOCGIFHWADDR"); + printf("Here 1\n"); ifopts.ifr_flags |= IFF_PROMISC; ioctl(sockfd, SIOCSIFFLAGS, &ifopts); @@ -163,6 +185,8 @@ int main(int argc, char **argv){ exit(EXIT_FAILURE); } printf("Here 4\n"); + SendILATrigger(); + exit(0); if(!rvviVersionCheck(RVVI_API_VERSION)){ printf("Bad RVVI_API_VERSION\n"); @@ -241,7 +265,8 @@ int main(int argc, char **argv){ printf("Simulation halted due to mismatch\n"); - pclose(VivadoPipeFP); + //pclose(VivadoPipeFP); + printf("closed pipe to vivado\n"); close(sockfd); @@ -291,18 +316,82 @@ int state_compare(int hart, uint64_t Minstret){ } if (result == 0) { + SendILATrigger(); sprintf(buf, "MISMATCH @ instruction # %ld\n", Minstret); idvMsgError(buf); - fputs("run_hw_ila [get_hw_ilas -of_objects [get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}] -trigger_now\n", VivadoPipeFP); - fputs("current_hw_ila_data [upload_hw_ila_data hw_ila_1]\n", VivadoPipeFP); - fputs("display_hw_ila_data [current_hw_ila_data]\n", VivadoPipeFP); - fputs("write_hw_ila_data my_hw_ila_data [current_hw_ila_data]\n", VivadoPipeFP); + /* fputs("run_hw_ila [get_hw_ilas -of_objects [get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}] -trigger_now\n", VivadoPipeFP); */ + /* fputs("current_hw_ila_data [upload_hw_ila_data hw_ila_1]\n", VivadoPipeFP); */ + /* fputs("display_hw_ila_data [current_hw_ila_data]\n", VivadoPipeFP); */ + /* fputs("write_hw_ila_data -force my_hw_ila_data [current_hw_ila_data]\n", VivadoPipeFP); */ + /* fflush(VivadoPipeFP); */ return -1; //if (ON_MISMATCH_DUMP_STATE) dump_state(hart); } } +void SendILATrigger(){ + uint8_t buf[BUF_SIZ]; + struct ether_header *eh = (struct ether_header *) buf; + int crc32; + struct sockaddr_ll socket_address; + + eh->ether_dhost[0] = DEST_MAC0; + eh->ether_dhost[1] = DEST_MAC1; + eh->ether_dhost[2] = DEST_MAC2; + eh->ether_dhost[3] = DEST_MAC3; + eh->ether_dhost[4] = DEST_MAC4; + eh->ether_dhost[5] = DEST_MAC5; + //c8:4b:d6:5f:89:25 is the real source mac for this laptop. I don't think it needs to be correct. + /* eh->ether_shost[0] = SRC_MAC0; */ + /* eh->ether_shost[1] = SRC_MAC1; */ + /* eh->ether_shost[2] = SRC_MAC2; */ + /* eh->ether_shost[3] = SRC_MAC3; */ + /* eh->ether_shost[4] = SRC_MAC4; */ + /* eh->ether_shost[5] = SRC_MAC5; */ + eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0]; + eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1]; + eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2]; + eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3]; + eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4]; + eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5]; + eh->ether_type = htons(ETH_P_IP); + //buf[12] = (ETHER_TYPE) >> 8; + //buf[13] = (ETHER_TYPE) && 0xFF; // *** does not work for some reason + buf[13] = 0; + buf[14] = 't'; + buf[15] = 'r'; + buf[16] = 'i'; + buf[17] = 'g'; + buf[18] = 'i'; + buf[19] = 'n'; + memset(&buf[20], 0, 40); // fill 36 bytes of 0 + int i; + printf("buffer: "); + for(i = 0; i < 60; i++){ + printf("%02x ", buf[i]); + } + printf("\n"); + //if (sendto(sockfd, buf, 60, 0, NULL, 0)) { + printf("sockfd %x\n", sockfd); + /* Index of the network device */ + socket_address.sll_ifindex = ifopts.ifr_ifindex; + /* Address length*/ + socket_address.sll_halen = ETH_ALEN; + /* Destination MAC */ + socket_address.sll_addr[0] = DEST_MAC0; + socket_address.sll_addr[1] = DEST_MAC1; + socket_address.sll_addr[2] = DEST_MAC2; + socket_address.sll_addr[3] = DEST_MAC3; + socket_address.sll_addr[4] = DEST_MAC4; + socket_address.sll_addr[5] = DEST_MAC5; + if (sendto(sockfd, buf, 60, MSG_DONTROUTE, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0) { + perror("ugh why???????????????????? sendto()"); + exit(3); + } +} + + void set_gpr(int hart, int reg, uint64_t value){ rvviDutGprSet(hart, reg, value); } @@ -465,3 +554,4 @@ void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length){ byte1 = byte1 >> ShiftAmount; dst[Length-1] = byte1; } + diff --git a/fpga/rvvidaemon/send-copy.c b/fpga/rvvidaemon/send-copy.c new file mode 100644 index 000000000..598e90f45 --- /dev/null +++ b/fpga/rvvidaemon/send-copy.c @@ -0,0 +1,112 @@ + +/* + * This program is free software: 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEST_MAC0 0x43 +#define DEST_MAC1 0x68 +#define DEST_MAC2 0x11 +#define DEST_MAC3 0x11 +#define DEST_MAC4 0x02 +#define DEST_MAC5 0x45 + +#define DEFAULT_IF "eth0" +#define BUF_SIZ 1024 + +int main(int argc, char *argv[]) +{ + int sockfd; + struct ifreq if_idx; + struct ifreq if_mac; + int tx_len = 0; + char sendbuf[BUF_SIZ]; + struct ether_header *eh = (struct ether_header *) sendbuf; + struct iphdr *iph = (struct iphdr *) (sendbuf + sizeof(struct ether_header)); + struct sockaddr_ll socket_address; + char ifName[IFNAMSIZ]; + + /* Get interface name */ + if (argc > 1) + strcpy(ifName, argv[1]); + else + strcpy(ifName, DEFAULT_IF); + + /* Open RAW socket to send on */ + if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) { + perror("socket"); + } + + /* Get the index of the interface to send on */ + memset(&if_idx, 0, sizeof(struct ifreq)); + strncpy(if_idx.ifr_name, ifName, IFNAMSIZ-1); + if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) + perror("SIOCGIFINDEX"); + /* Get the MAC address of the interface to send on */ + memset(&if_mac, 0, sizeof(struct ifreq)); + strncpy(if_mac.ifr_name, ifName, IFNAMSIZ-1); + if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0) + perror("SIOCGIFHWADDR"); + + /* Construct the Ethernet header */ + memset(sendbuf, 0, BUF_SIZ); + /* Ethernet header */ + eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0]; + eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1]; + eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2]; + eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3]; + eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4]; + eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5]; + eh->ether_dhost[0] = DEST_MAC0; + eh->ether_dhost[1] = DEST_MAC1; + eh->ether_dhost[2] = DEST_MAC2; + eh->ether_dhost[3] = DEST_MAC3; + eh->ether_dhost[4] = DEST_MAC4; + eh->ether_dhost[5] = DEST_MAC5; + /* Ethertype field */ + eh->ether_type = htons(ETH_P_IP); + tx_len += sizeof(struct ether_header); + + /* Packet data */ + sendbuf[tx_len++] = 0xde; + sendbuf[tx_len++] = 0xad; + sendbuf[tx_len++] = 0xbe; + sendbuf[tx_len++] = 0xef; + + /* Index of the network device */ + socket_address.sll_ifindex = if_idx.ifr_ifindex; + /* Address length*/ + socket_address.sll_halen = ETH_ALEN; + /* Destination MAC */ + socket_address.sll_addr[0] = DEST_MAC0; + socket_address.sll_addr[1] = DEST_MAC1; + socket_address.sll_addr[2] = DEST_MAC2; + socket_address.sll_addr[3] = DEST_MAC3; + socket_address.sll_addr[4] = DEST_MAC4; + socket_address.sll_addr[5] = DEST_MAC5; + + int i; + printf("buffer: "); + for(i=0;i Date: Tue, 9 Jul 2024 12:30:18 -0500 Subject: [PATCH 55/95] Updated to use the newest imperasDV. --- fpga/rvvidaemon/Makefile | 4 +- fpga/rvvidaemon/rvviApi.h | 697 ----------------------------------- fpga/rvvidaemon/rvvidaemon.c | 136 ++----- 3 files changed, 25 insertions(+), 812 deletions(-) delete mode 100644 fpga/rvvidaemon/rvviApi.h diff --git a/fpga/rvvidaemon/Makefile b/fpga/rvvidaemon/Makefile index 4f048302d..26f705a20 100644 --- a/fpga/rvvidaemon/Makefile +++ b/fpga/rvvidaemon/Makefile @@ -1,10 +1,10 @@ all: rvvidaemon rvvidaemon: rvvidaemon.o - gcc $^ /opt/riscv/ImperasDV-OpenHW/Imperas/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model.so -o rvvidaemon + gcc $^ /opt/riscv/ImperasDV-OpenHW/lib/Linux64/ImperasLib/imperas.com/verification/riscv/1.0/model.so -o rvvidaemon %.o:%.c - gcc -I/opt/riscv/ImperasDV-OpenHW/Imperas/ImpProprietary/include/host -c $^ -o $@ + gcc -I/opt/riscv/ImperasDV-OpenHW/ImpProprietary/include/host -I/opt/riscv/ImperasDV-OpenHW/ImpPublic/include/host/rvvi/ -c $^ -o $@ clean: rm *.o rvvidaemon diff --git a/fpga/rvvidaemon/rvviApi.h b/fpga/rvvidaemon/rvviApi.h deleted file mode 100644 index d37286781..000000000 --- a/fpga/rvvidaemon/rvviApi.h +++ /dev/null @@ -1,697 +0,0 @@ -/* - * Copyright (c) 2005-2023 Imperas Software Ltd., www.imperas.com - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. - * - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#pragma once - -/*! \file rvviApi.h - * \brief RVVI interface, C API header. -**/ - -#include - -typedef uint32_t bool_t; - -#define RVVI_API_VERSION_MAJOR 1 -#define RVVI_API_VERSION_MINOR 34 -#define RVVI_TRUE 1 -#define RVVI_FALSE 0 -#define RVVI_INVALID_INDEX -1 -#define RVVI_MEMORY_PRIVILEGE_READ 1 -#define RVVI_MEMORY_PRIVILEGE_WRITE 2 -#define RVVI_MEMORY_PRIVILEGE_EXEC 4 -#define RVVI_API_VERSION ((RVVI_API_VERSION_MAJOR << 24) | RVVI_API_VERSION_MINOR) - -typedef enum { - RVVI_METRIC_RETIRES = 0, - RVVI_METRIC_TRAPS = 1, - RVVI_METRIC_MISMATCHES = 2, - RVVI_METRIC_COMPARISONS_PC = 3, - RVVI_METRIC_COMPARISONS_GPR = 4, - RVVI_METRIC_COMPARISONS_FPR = 5, - RVVI_METRIC_COMPARISONS_CSR = 6, - RVVI_METRIC_COMPARISONS_VR = 7, - RVVI_METRIC_COMPARISONS_INSBIN = 8, - RVVI_METRIC_CYCLES = 9, - RVVI_METRIC_ERRORS = 10, - RVVI_METRIC_WARNINGS = 11, - RVVI_METRIC_FATALS = 12, -} rvviMetricE; - -#ifdef __cplusplus -extern "C" { -#endif - -/*! \brief Check the compiled RVVI API version. - * - * Makes sure the RVVI implementation linked with matches the versions defined in this header file. This should be called before any other RVVI API function. If this function returns RVVI_FALSE, no other RVVI API function should be called. - * - * \param version Should be set to RVVI_API_VERSION. - * - * \return RVVI_TRUE if versions matches otherwise RVVI_FALSE. -**/ -extern bool_t rvviVersionCheck( - uint32_t version); - -/*! \brief Initialize the DV reference model. - * - * \param programPath File path of the ELF file to be executed. This parameter can be NULL if required. - * - * \return RVVI_TRUE if the reference was initialized successfully else RVVI_FALSE. - * - * \note The reference model will begin execution from the entry point of the provided ELF file but can be overridden by the rvviRefPcSet() function. -**/ -extern bool_t rvviRefInit( - const char *programPath); - -/*! \brief Force the PC of the reference model to be particular value. - * - * \param hartId The hart to change the PC register of. - * \param address The address to change the PC register to. - * - * \return RVVI_TRUE on success else RVVI_FALSE. -**/ -extern bool_t rvviRefPcSet( - uint32_t hartId, - uint64_t address); - -/*! \brief Shutdown the reference module releasing any used resources. - * - * \return Returns RVVI_TRUE if shutdown was successful else RVVI_FALSE. -**/ -extern bool_t rvviRefShutdown(void); - -/*! \brief Notify the reference that a CSR is considered volatile. - * - * \param hartId The hart that will have its CSR made volatile. - * \param csrIndex Index of the CSR register to be considered volatile (0x0 to 0xfff). - * - * \return Returns RVVI_TRUE if operation was successful else RVVI_FALSE. -**/ -extern bool_t rvviRefCsrSetVolatile( - uint32_t hartId, - uint32_t csrIndex); - -/*! \brief Notify the reference that a memory region is volatile. - * - * \param addressLow Lower address of the volatile memory region - * \param addressHigh Upper address of the volatile memory region (inclusive) - * - * \return Returns RVVI_TRUE if operation was successful else RVVI_FALSE. -**/ -extern bool_t rvviRefMemorySetVolatile( - uint64_t addressLow, - uint64_t addressHigh); - -/*! \brief Lookup a net on the reference model and return its index. - * - * \param name The net name to locate. - * - * \return Unique index for this net or RVVI_INVALID_INDEX if it was not found. - * - * \note Please consult the model datasheet for a list of valid net names. - * \note See also, rvviRefNetSet(). -**/ -extern uint64_t rvviRefNetIndexGet( - const char *name); - -/*! \brief Extract a byte from the reference models vector register. - * - * \param hartId The hart to extract the vector register byte from. - * \param vrIndex The vector register index (0 to 31). - * \param byteIndex The byte offset into the vector register (note 0 is LSB). - * - * \return Byte that has been extracted from the vector register. -**/ -extern uint8_t rvviRefVrGet( - uint32_t hartId, - uint32_t vrIndex, - uint32_t byteIndex); - -/*! \brief Notify RVVI that a byte in the DUTs vector register has changed. - * - * \param hartId The hart that has updated its vector register. - * \param vrIndex The vector register index (0 to 31). - * \param byteIndex The byte offset into the vector register (note 0 is LSB). - * \param data New byte value in the DUTs vector register. -**/ -extern void rvviDutVrSet( - uint32_t hartId, - uint32_t vrIndex, - uint32_t byteIndex, - uint8_t data); - -/*! \brief Notify RVVI that a DUT floating point register has been written to. - * - * \param hartId The hart that has updated its FPR. - * \param fprIndex The FPR index within the register file (0 to 31). - * \param value The value that has been written. -**/ -extern void rvviDutFprSet( - uint32_t hartId, - uint32_t fprIndex, - uint64_t value); - -/*! \brief Notify RVVI that a DUT GPR has been written to. - * - * \param hartId The hart that has updated its GPR. - * \param gprIndex The GPR index within the register file. - * \param value The value that has been written. -**/ -extern void rvviDutGprSet( - uint32_t hartId, - uint32_t gprIndex, - uint64_t value); - -/*! \brief Notify RVVI that a DUT CSR has been written to. - * - * \param hartId The hart that has updated its CSR. - * \param csrIndex The CSR index (0x0 to 0xfff). - * \param value The value that has been written. -**/ -extern void rvviDutCsrSet( - uint32_t hartId, - uint32_t csrIndex, - uint64_t value); - -/*! \brief Place a net in a specific net group. - * - * \param netIndex The net index returned prior by rvviRefNetIndexGet(). - * \param group The group index to place this net into. -**/ -extern void rvviRefNetGroupSet( - uint64_t netIndex, - uint32_t group); - -/*! \brief Propagate a net change to the reference model. - * - * \param netIndex The net index returned prior by rvviRefNetIndexGet(). - * \param value The new value to set the net state to. - * \param when Time of arrival of this net, in simulation time. The `when` parameter may be measured in simulation time or cycles. It allows the RVVI-API to know which net changes have arrived at the same time. -**/ -extern void rvviRefNetSet( - uint64_t netIndex, - uint64_t value, - uint64_t when); - -/*! \brief Read the state of a net on the reference model. - * - * \param netIndex The net index returned prior by rvviRefNetIndexGet(). - * - * \return The value present on the specified net. -**/ -extern uint64_t rvviRefNetGet( - uint64_t netIndex); - -/*! \brief Notify the reference that a DUT instruction has retired. - * - * \param hartId The hart that has retired an instruction. - * \param dutPc The address of the instruction that has retired. - * \param dutInsBin The binary instruction representation. - * \param debugMode True if this instruction was executed in debug mode. -**/ -extern void rvviDutRetire( - uint32_t hartId, - uint64_t dutPc, - uint64_t dutInsBin, - bool_t debugMode); - -/*! \brief Notify the reference that the DUT received a trap. - * - * \param hartId The hart that has retired an instruction. - * \param dutPc The address of the instruction that has retired. - * \param dutInsBin The binary instruction representation. -**/ -extern void rvviDutTrap( - uint32_t hartId, - uint64_t dutPc, - uint64_t dutInsBin); - -/*! \brief Invalidate the reference models LR/SC reservation. - * - * \param hartId The hart of which the LR/SC reservation will be made invalid. -**/ -extern void rvviRefReservationInvalidate( - uint32_t hartId); - -/*! \brief Step the reference model until the next event. - * - * \param hartId The ID of the hart that is being stepped. - * - * \return Returns RVVI_TRUE if the step was successful else RVVI_FALSE. -**/ -extern bool_t rvviRefEventStep( - uint32_t hartId); - -/*! \brief Compare all GPR register values between reference and DUT. - * - * \param hartId The ID of the hart that is being compared. - * - * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. -**/ -extern bool_t rvviRefGprsCompare( - uint32_t hartId); - -/*! \brief Compare GPR registers that have been written to between the reference and DUT. This can be seen as a super set of the rvviRefGprsCompare function. This comparator will also flag differences in the set of registers that have been written to. - * - * \param hartId The ID of the hart that is being compared. - * \param ignoreX0 RVVI_TRUE to not compare writes to the x0 register, which may be treated as a special case, otherwise RVVI_FALSE. - * - * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. -**/ -extern bool_t rvviRefGprsCompareWritten( - uint32_t hartId, - bool_t ignoreX0); - -/*! \brief Compare retired instruction bytes between reference and DUT. - * - * \param hartId The ID of the hart that is being compared. - * - * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. -**/ -extern bool_t rvviRefInsBinCompare( - uint32_t hartId); - -/*! \brief Compare program counter for the retired instructions between DUT and the the reference model. - * - * \param hartId The ID of the hart that is being compared. - * - * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. -**/ -extern bool_t rvviRefPcCompare( - uint32_t hartId); - -/*! \brief Compare a CSR value between DUT and the the reference model. - * - * \param hartId The ID of the hart that is being compared. - * \param csrIndex The index of the CSR register being compared. - * - * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. -**/ -extern bool_t rvviRefCsrCompare( - uint32_t hartId, - uint32_t csrIndex); - -/*! \brief Enable or disable comparison of a specific CSR during rvviRefCsrsCompare. - * - * \param hartId The ID of the hart that this should apply to. - * \param csrIndex The index of the CSR to enable or disable comparison of. - * \param enableState RVVI_TRUE to enable comparison or RVVI_FALSE to disable. -**/ -extern void rvviRefCsrCompareEnable( - uint32_t hartId, - uint32_t csrIndex, - bool_t enableState); - -/*! \brief Specify a bitmask to direct bit level CSR comparisons. - * - * \param hartId The ID of the hart that this should apply to. - * \param csrIndex The index of the CSR to control the comparison of. - * \param mask Bitmask to enable or disable bits during CSR compare operations. Bits set to 1 will be compared and 0 bits are ignored. -**/ -extern void rvviRefCsrCompareMask( - uint32_t hartId, - uint32_t csrIndex, - uint64_t mask); - -/*! \brief Compare all CSR values between DUT and the the reference model. - * - * This function will compare the value of all CSRs between the reference and the DUT. Note that specific CSRs can be removed from this comparison by using the rvviRefCsrCompareEnable function. - * - * \param hartId The ID of the hart that is being compared. - * - * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. -**/ -extern bool_t rvviRefCsrsCompare( - uint32_t hartId); - -/*! \brief Compare all RVV vector register values between reference and DUT. - * - * \param hartId The ID of the hart that is being compared. - * - * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. -**/ -extern bool_t rvviRefVrsCompare( - uint32_t hartId); - -/*! \brief Compare all floating point register values between reference and DUT. - * - * \param hartId The ID of the hart that is being compared. - * - * \return RVVI_FALSE if there are any mismatches, otherwise RVVI_TRUE. -**/ -extern bool_t rvviRefFprsCompare( - uint32_t hartId); - -/*! \brief Write to the GPR of a hart in the reference model. - * - * \param hartId The hart to write the GPR of. - * \param gprIndex Index of the GPR register to write. - * \param gprValue Value to write into the GPR register. -**/ -extern void rvviRefGprSet( - uint32_t hartId, - uint32_t gprIndex, - uint64_t gprValue); - -/*! \brief Read a GPR value from a hart in the reference model. - * - * \param hartId The hart to retrieve the GPR from. - * \param gprIndex Index of the GPR register to read. - * - * \return GPR value read from the reference model. -**/ -extern uint64_t rvviRefGprGet( - uint32_t hartId, - uint32_t gprIndex); - -/*! \brief Read a GPR written mask from the last rvviRefEventStep. - * - * Each bit index in the mask returned indicates if the corresponding GPR has been written to by the reference model. Ie, if bit 3 is set, then X3 was written to. - * - * \param hartId The hart to retrieve the GPR written mask from. - * - * \return The GPR written mask. -**/ -extern uint32_t rvviRefGprsWrittenGet( - uint32_t hartId); - -/*! \brief Return the program counter of a hart in the reference model. - * - * \param hartId The hart to retrieve the PC from. - * - * \return The program counter of the specified hart. -**/ -extern uint64_t rvviRefPcGet( - uint32_t hartId); - -/*! \brief Read a CSR value from a hart in the reference model. - * - * \param hartId The hart to retrieve the CSR from. - * \param csrIndex Index of the CSR register to read (0x0 to 0xfff). - * - * \return The CSR register value read from the specified hart. -**/ -extern uint64_t rvviRefCsrGet( - uint32_t hartId, - uint32_t csrIndex); - -/*! \brief Return the binary representation of the previously retired instruction. - * - * \param hartId The hart to retrieve the instruction from. - * - * \return The instruction bytes. -**/ -extern uint64_t rvviRefInsBinGet( - uint32_t hartId); - -/*! \brief Write the value of a floating point register for a hart in the reference model. - * - * \param hartId The hart to retrieve the FPR register from. - * \param fprIndex Index of the floating point register to read. - * \param fprValue The bit pattern to be written into the floating point register. -**/ -extern void rvviRefFprSet( - uint32_t hartId, - uint32_t fprIndex, - uint64_t fprValue); - -/*! \brief Read a floating point register value from a hart in the reference model. - * - * \param hartId The hart to retrieve the FPR register from. - * \param fprIndex Index of the floating point register to read. - * - * \return The FPR register value read from the specified hart. -**/ -extern uint64_t rvviRefFprGet( - uint32_t hartId, - uint32_t fprIndex); - -/*! \brief Notify RVVI that the DUT has been written to memory. - * - * \param hartId The hart that issued the data bus write. - * \param address The address the hart is writing to. - * \param value The value placed on the data bus. - * \param byteEnableMask The byte enable mask provided for this write. - * - * \note Bus writes larger than 64bits should be reported using multiple calls to this function. - * \note byteEnableMask bit 0 corresponds to address+0, bEnMask bit 1 corresponds to address+1, etc. -**/ -extern void rvviDutBusWrite( - uint32_t hartId, - uint64_t address, - uint64_t value, - uint64_t byteEnableMask); - -/*! \brief Write data to the reference models physical memory space. - * - * \param hartId The hart to write from the perspective of. - * \param address The address being written to. - * \param data The data byte being written into memory. - * \param size Size of the data being written in bytes (1 to 8). -**/ -extern void rvviRefMemoryWrite( - uint32_t hartId, - uint64_t address, - uint64_t data, - uint32_t size); - -/*! \brief Read data from the reference models physical memory space. - * - * \param hartId The hart to read from the perspective of. - * \param address The address being read from. - * \param size Size of the data being read in bytes (1 to 8). - * - * \return The data that has been read from reference memory. -**/ -extern uint64_t rvviRefMemoryRead( - uint32_t hartId, - uint64_t address, - uint32_t size); - -/*! \brief Disassemble an arbitrary instruction encoding. - * - * \param hartId Hart with the ISA we are disassembling for. - * \param address Address of the instruction in memory. - * \param insBin The raw instruction that should be disassembled. - * - * \return Null terminated string containing the disassembly. -**/ -extern const char *rvviDasmInsBin( - uint32_t hartId, - uint64_t address, - uint64_t insBin); - -/*! \brief Return the name of a CSR in the reference model. - * - * \param hartId Hart with the CSR we are looking up the name of. - * \param csrIndex The index of the CSR we are looking up (0x0 to 0xfff inclusive). - * - * \return Null terminated string containing the CSR name. -**/ -extern const char *rvviRefCsrName( - uint32_t hartId, - uint32_t csrIndex); - -/*! \brief Return the ABI name of a GPR in the reference model. - * - * \param hartId Hart with the GPR we are looking up the name of. - * \param gprIndex The index of the GPR we are looking up (0 to 31 inclusive). - * - * \return Null terminated string containing the GPR ABI name. -**/ -extern const char *rvviRefGprName( - uint32_t hartId, - uint32_t gprIndex); - -/*! \brief Check if a CSR is present in the reference model. - * - * \param hartId Hart with the CSR we are checking the presence of. - * \param csrIndex The index of the CSR we are checking for (0x0 to 0xfff inclusive). - * - * \return RVVI_TRUE if the CSR is present in the reference model else RVVI_FALSE. -**/ -extern bool_t rvviRefCsrPresent( - uint32_t hartId, - uint32_t csrIndex); - -/*! \brief Check if floating point registers are present in the reference model. - * - * \param hartId Hart Id we are checking for the presence of floating point registers. - * - * \return RVVI_TRUE if the floating point registers are present in the reference model else RVVI_FALSE. -**/ -extern bool_t rvviRefFprsPresent( - uint32_t hartId); - -/*! \brief Check if vector registers are present in the reference model. - * - * \param hartId Hart Id we are checking for the presence of vector registers. - * - * \return RVVI_TRUE if the vector registers are present in the reference model else RVVI_FALSE. -**/ -extern bool_t rvviRefVrsPresent( - uint32_t hartId); - -/*! \brief Return the name of a FPR in the reference model. - * - * \param hartId Hart with the FPR we are looking up the name of. - * \param fprIndex The index of the FPR we are looking up (0 to 31 inclusive). - * - * \return Null terminated string containing the FPR name. -**/ -extern const char *rvviRefFprName( - uint32_t hartId, - uint32_t fprIndex); - -/*! \brief Return the name of a vector register in the reference model. - * - * \param hartId Hart with the VR we are looking up the name of. - * \param vrIndex The index of the VR we are looking up (0 to 31 inclusive). - * - * \return Null terminated string containing the VR name. -**/ -extern const char *rvviRefVrName( - uint32_t hartId, - uint32_t vrIndex); - -/*! \brief Return a string detailing the last RVVI-API error. - * - * \return The error string or an empty string if no error has occurred. -**/ -extern const char *rvviErrorGet(void); - -/*! \brief Query a verification metric from the reference model. - * - * \param metric An enumeration identifying the metric to query and return. - * - * \return The scalar quantity that has been queried. -**/ -extern uint64_t rvviRefMetricGet( - rvviMetricE metric); - -/*! \brief Set the value of a CSR in the reference model. - * - * \param hartId The hart which we are modifying the CSR of. - * \param csrIndex The index of the CSR we are modifying (0x0 to 0xfff inclusive). - * \param value The value to write into the CSR. -**/ -extern void rvviRefCsrSet( - uint32_t hartId, - uint32_t csrIndex, - uint64_t value); - -/*! \brief Dump the current register state of a hart in the reference model. - * - * \param hartId The hart which we should dump the register state of. -**/ -extern void rvviRefStateDump( - uint32_t hartId); - -/*! \brief Load an additional program into the address space of the processor. - * - * \param programPath File path of the ELF file to be loaded into memory. - * - * \return RVVI_TRUE if the program was loaded successfully otherwise RVVI_FALSE -**/ -extern bool_t rvviRefProgramLoad( - const char *programPath); - -/*! \brief Apply fine grain control over a CSRs volatility in the reference model. - * - * \param hartId The hart that will have its CSR volatility adjusted. - * \param csrIndex Index of the CSR register to have its volatility modified (0x0 to 0xfff). - * \param csrMask Bitmask specifying volatility, set bits will be treated as volatile, clear bits are not - * - * \return Returns RVVI_TRUE if operation was successful else RVVI_FALSE. -**/ -extern bool_t rvviRefCsrSetVolatileMask( - uint32_t hartId, - uint32_t csrIndex, - uint64_t csrMask); - -/*! \brief Pass the current testbench cycle count to the RVVI implementation. - * - * \param cycleCount The current cycle count of the DUT. This value is directly related to, and must be consistent with, the `when` parameter for rvviRefNetSet(). -**/ -extern void rvviDutCycleCountSet( - uint64_t cycleCount); - -/*! \brief Pass a vendor specific integer configuration parameter to the RVVI implementation. - * - * \param configParam The configuration option that is to have its associated value set. This is vendor specific and not defined as part of the RVVI-API. - * \param value An integer containing the data that should be passed to the configuration option. - * - * \return Returns RVVI_TRUE if operation was successful else RVVI_FALSE. -**/ -extern bool_t rvviRefConfigSetInt( - uint64_t configParam, - uint64_t value); - -/*! \brief Pass a vendor specific string configuration parameter to the RVVI implementation. - * - * \param configParam The configuration option that is to have its associated value set. This is vendor specific and not defined as part of the RVVI-API. - * \param value A string containing the data that should be passed to the configuration option. - * - * \return Returns RVVI_TRUE if operation was successful else RVVI_FALSE. -**/ -extern bool_t rvviRefConfigSetString( - uint64_t configParam, - const char *value); - -/*! \brief Given the name of a CSR, its unique index/address will be returned. - * - * \param hartId HartId of the hart containing the CSR we are looking up the index of. - * \param csrName The CSR name for which the CSR index should be retrieved. - * - * \return Returns the CSR index if the operation was successful else RVVI_INVALID_INDEX. -**/ -extern uint32_t rvviRefCsrIndex( - uint32_t hartId, - const char *csrName); - -/*! \brief Set the privilege mode for a region of the address space. - * - * \param addrLo Lower address defining the memory region. - * \param addrHi Upper address defining the memory region (inclusive). - * \param access Access flags for this memory region; a combination of RVVI_PRIV_... flags or 0. - * - * \return Returns RVVI_TRUE if operation was successful else RVVI_FALSE. -**/ -extern bool_t rvviRefMemorySetPrivilege( - uint64_t addrLo, - uint64_t addrHi, - uint32_t access); - -/*! \brief Update a byte in one of the reference models vector registers. - * - * \param hartId The hart that should have its vector register updated. - * \param vrIndex The vector register index (0 to 31). - * \param byteIndex The byte offset into the vector register (note 0 is LSB). - * \param data New byte value to be written into the vector register. -**/ -extern void rvviRefVrSet( - uint32_t hartId, - uint32_t vrIndex, - uint32_t byteIndex, - uint8_t data); - -#ifdef __cplusplus -} // extern "C" -#endif - diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 9876ebc20..b2ccc2b63 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -41,11 +41,9 @@ #include #include #include -#include #include "rvviApi.h" // *** bug fix me when this file gets included into the correct directory. #include "idv/idv.h" -#include #define DEST_MAC0 0x43 #define DEST_MAC1 0x68 @@ -69,8 +67,6 @@ #define DEFAULT_IF "eno1" FILE *VivadoPipeFP; -int sockfd; -struct ifreq ifopts, if_mac; /* set promiscuous mode */ typedef struct { uint64_t PC; @@ -104,7 +100,6 @@ int ProcessRvviAll(RequiredRVVI_t *InstructionData); void set_gpr(int hart, int reg, uint64_t value); void set_fpr(int hart, int reg, uint64_t value); int state_compare(int hart, uint64_t Minstret); -void SendILATrigger(); int main(int argc, char **argv){ @@ -114,57 +109,40 @@ int main(int argc, char **argv){ return -1; } - /* // step 1 open a pipe to vivado */ - /* if (( VivadoPipeFP = popen("vivado -mode tcl", "w")) == NULL){ */ - /* perror("popen"); */ - /* exit(1); */ - /* } */ - /* fputs("open_hw_manager\n", VivadoPipeFP); */ - /* fputs("connect_hw_server -url localhost:3121\n", VivadoPipeFP); */ - /* fputs("current_hw_target [get_hw_targets *\/xilinx_tcf/Digilent/\*]\n", VivadoPipeFP); */ - /* fputs("open_hw_target\n", VivadoPipeFP); */ - /* fputs("set_property PARAM.FREQUENCY 7500000 [get_hw_targets localhost:3121/xilinx_tcf/Digilent/210319B7CA87A]\n", VivadoPipeFP); */ + // step 1 open a pipe to vivado + if (( VivadoPipeFP = popen("vivado -mode tcl", "w")) == NULL){ + perror("popen"); + exit(1); + } + fputs("open_hw_manager\n", VivadoPipeFP); + fputs("connect_hw_server -url localhost:3121\n", VivadoPipeFP); + fputs("current_hw_target [get_hw_targets */xilinx_tcf/Digilent/*]\n", VivadoPipeFP); + fputs("open_hw_target\n", VivadoPipeFP); + fputs("set_property PARAM.FREQUENCY 7500000 [get_hw_targets localhost:3121/xilinx_tcf/Digilent/210319B7CA87A]\n", VivadoPipeFP); - /* // *** bug these need to made relative paths. */ - /* fputs("set_property PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); */ - /* fputs("set_property FULL_PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); */ - /* fputs("set_property PROGRAM.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.bit} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); */ - /* fputs("refresh_hw_device [lindex [get_hw_devices xc7a100t_0] 0]\n", VivadoPipeFP); */ - /* fputs("[get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}]]\n", VivadoPipeFP); */ - /* fflush(VivadoPipeFP); */ + // *** bug these need to made relative paths. + fputs("set_property PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); + fputs("set_property FULL_PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); + fputs("set_property PROGRAM.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.bit} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); + fputs("refresh_hw_device [lindex [get_hw_devices xc7a100t_0] 0]\n", VivadoPipeFP); + fputs("[get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}]]\n", VivadoPipeFP); + int sockfd; uint8_t buf[BUF_SIZ]; int sockopt; + struct ifreq ifopts; /* set promiscuous mode */ struct ether_header *eh = (struct ether_header *) buf; ssize_t headerbytes, numbytes, payloadbytes; - /* Open RAW socket to receive frames */ if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) { - // *** remove. This is not the problem - //if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) { perror("socket"); } - printf("sockfd %x\n", sockfd); printf("Here 0\n"); /* Set interface to promiscuous mode - do we need to do this every time? */ - memset(&ifopts, 0, sizeof(struct ifreq)); strncpy(ifopts.ifr_name, argv[1], IFNAMSIZ-1); ioctl(sockfd, SIOCGIFFLAGS, &ifopts); - - /* Get the index of the interface to send on */ - //memset(&if_idx, 0, sizeof(struct ifreq)); - //strncpy(if_idx.ifr_name, argv[1], IFNAMSIZ-1); - if (ioctl(sockfd, SIOCGIFINDEX, &ifopts) < 0) - perror("SIOCGIFINDEX"); - - /* Get the MAC address of the interface to send on */ - memset(&if_mac, 0, sizeof(struct ifreq)); - strncpy(if_mac.ifr_name, argv[1], IFNAMSIZ-1); - if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0) - perror("SIOCGIFHWADDR"); - printf("Here 1\n"); ifopts.ifr_flags |= IFF_PROMISC; ioctl(sockfd, SIOCSIFFLAGS, &ifopts); @@ -185,8 +163,6 @@ int main(int argc, char **argv){ exit(EXIT_FAILURE); } printf("Here 4\n"); - SendILATrigger(); - exit(0); if(!rvviVersionCheck(RVVI_API_VERSION)){ printf("Bad RVVI_API_VERSION\n"); @@ -265,8 +241,7 @@ int main(int argc, char **argv){ printf("Simulation halted due to mismatch\n"); - //pclose(VivadoPipeFP); - printf("closed pipe to vivado\n"); + pclose(VivadoPipeFP); close(sockfd); @@ -316,82 +291,18 @@ int state_compare(int hart, uint64_t Minstret){ } if (result == 0) { - SendILATrigger(); sprintf(buf, "MISMATCH @ instruction # %ld\n", Minstret); idvMsgError(buf); - /* fputs("run_hw_ila [get_hw_ilas -of_objects [get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}] -trigger_now\n", VivadoPipeFP); */ - /* fputs("current_hw_ila_data [upload_hw_ila_data hw_ila_1]\n", VivadoPipeFP); */ - /* fputs("display_hw_ila_data [current_hw_ila_data]\n", VivadoPipeFP); */ - /* fputs("write_hw_ila_data -force my_hw_ila_data [current_hw_ila_data]\n", VivadoPipeFP); */ - /* fflush(VivadoPipeFP); */ + fputs("run_hw_ila [get_hw_ilas -of_objects [get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}] -trigger_now\n", VivadoPipeFP); + fputs("current_hw_ila_data [upload_hw_ila_data hw_ila_1]\n", VivadoPipeFP); + fputs("display_hw_ila_data [current_hw_ila_data]\n", VivadoPipeFP); + fputs("write_hw_ila_data my_hw_ila_data [current_hw_ila_data]\n", VivadoPipeFP); return -1; //if (ON_MISMATCH_DUMP_STATE) dump_state(hart); } } -void SendILATrigger(){ - uint8_t buf[BUF_SIZ]; - struct ether_header *eh = (struct ether_header *) buf; - int crc32; - struct sockaddr_ll socket_address; - - eh->ether_dhost[0] = DEST_MAC0; - eh->ether_dhost[1] = DEST_MAC1; - eh->ether_dhost[2] = DEST_MAC2; - eh->ether_dhost[3] = DEST_MAC3; - eh->ether_dhost[4] = DEST_MAC4; - eh->ether_dhost[5] = DEST_MAC5; - //c8:4b:d6:5f:89:25 is the real source mac for this laptop. I don't think it needs to be correct. - /* eh->ether_shost[0] = SRC_MAC0; */ - /* eh->ether_shost[1] = SRC_MAC1; */ - /* eh->ether_shost[2] = SRC_MAC2; */ - /* eh->ether_shost[3] = SRC_MAC3; */ - /* eh->ether_shost[4] = SRC_MAC4; */ - /* eh->ether_shost[5] = SRC_MAC5; */ - eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0]; - eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1]; - eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2]; - eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3]; - eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4]; - eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5]; - eh->ether_type = htons(ETH_P_IP); - //buf[12] = (ETHER_TYPE) >> 8; - //buf[13] = (ETHER_TYPE) && 0xFF; // *** does not work for some reason - buf[13] = 0; - buf[14] = 't'; - buf[15] = 'r'; - buf[16] = 'i'; - buf[17] = 'g'; - buf[18] = 'i'; - buf[19] = 'n'; - memset(&buf[20], 0, 40); // fill 36 bytes of 0 - int i; - printf("buffer: "); - for(i = 0; i < 60; i++){ - printf("%02x ", buf[i]); - } - printf("\n"); - //if (sendto(sockfd, buf, 60, 0, NULL, 0)) { - printf("sockfd %x\n", sockfd); - /* Index of the network device */ - socket_address.sll_ifindex = ifopts.ifr_ifindex; - /* Address length*/ - socket_address.sll_halen = ETH_ALEN; - /* Destination MAC */ - socket_address.sll_addr[0] = DEST_MAC0; - socket_address.sll_addr[1] = DEST_MAC1; - socket_address.sll_addr[2] = DEST_MAC2; - socket_address.sll_addr[3] = DEST_MAC3; - socket_address.sll_addr[4] = DEST_MAC4; - socket_address.sll_addr[5] = DEST_MAC5; - if (sendto(sockfd, buf, 60, MSG_DONTROUTE, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0) { - perror("ugh why???????????????????? sendto()"); - exit(3); - } -} - - void set_gpr(int hart, int reg, uint64_t value){ rvviDutGprSet(hart, reg, value); } @@ -554,4 +465,3 @@ void BitShiftArray(uint8_t *dst, uint8_t *src, uint8_t ShiftAmount, int Length){ byte1 = byte1 >> ShiftAmount; dst[Length-1] = byte1; } - From fd170a6583a22893ec2720ecba3a1f9c6c85c8e4 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 9 Jul 2024 14:09:56 -0500 Subject: [PATCH 56/95] Getting closer. --- fpga/rvvidaemon/rvvidaemon.c | 91 ++++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 20 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index b2ccc2b63..27e70a1bf 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -67,6 +67,10 @@ #define DEFAULT_IF "eno1" FILE *VivadoPipeFP; +struct sockaddr_ll socket_address; +uint8_t sendbuf[BUF_SIZ]; +struct ether_header *sendeh = (struct ether_header *) sendbuf; +int tx_len = 0; typedef struct { uint64_t PC; @@ -110,22 +114,22 @@ int main(int argc, char **argv){ } // step 1 open a pipe to vivado - if (( VivadoPipeFP = popen("vivado -mode tcl", "w")) == NULL){ - perror("popen"); - exit(1); - } - fputs("open_hw_manager\n", VivadoPipeFP); - fputs("connect_hw_server -url localhost:3121\n", VivadoPipeFP); - fputs("current_hw_target [get_hw_targets */xilinx_tcf/Digilent/*]\n", VivadoPipeFP); - fputs("open_hw_target\n", VivadoPipeFP); - fputs("set_property PARAM.FREQUENCY 7500000 [get_hw_targets localhost:3121/xilinx_tcf/Digilent/210319B7CA87A]\n", VivadoPipeFP); + /* if (( VivadoPipeFP = popen("vivado -mode tcl", "w")) == NULL){ */ + /* perror("popen"); */ + /* exit(1); */ + /* } */ + /* fputs("open_hw_manager\n", VivadoPipeFP); */ + /* fputs("connect_hw_server -url localhost:3121\n", VivadoPipeFP); */ + /* fputs("current_hw_target [get_hw_targets *\/xilinx_tcf/Digilent/\*]\n", VivadoPipeFP); */ + /* fputs("open_hw_target\n", VivadoPipeFP); */ + /* fputs("set_property PARAM.FREQUENCY 7500000 [get_hw_targets localhost:3121/xilinx_tcf/Digilent/210319B7CA87A]\n", VivadoPipeFP); */ - // *** bug these need to made relative paths. - fputs("set_property PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); - fputs("set_property FULL_PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); - fputs("set_property PROGRAM.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.bit} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); - fputs("refresh_hw_device [lindex [get_hw_devices xc7a100t_0] 0]\n", VivadoPipeFP); - fputs("[get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}]]\n", VivadoPipeFP); + /* // *** bug these need to made relative paths. */ + /* fputs("set_property PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); */ + /* fputs("set_property FULL_PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); */ + /* fputs("set_property PROGRAM.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.bit} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); */ + /* fputs("refresh_hw_device [lindex [get_hw_devices xc7a100t_0] 0]\n", VivadoPipeFP); */ + /* fputs("[get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}]]\n", VivadoPipeFP); */ int sockfd; uint8_t buf[BUF_SIZ]; @@ -147,6 +151,8 @@ int main(int argc, char **argv){ ifopts.ifr_flags |= IFF_PROMISC; ioctl(sockfd, SIOCSIFFLAGS, &ifopts); printf("Here 2\n"); + if (ioctl(sockfd, SIOCGIFINDEX, &ifopts) < 0) + perror("SIOCGIFINDEX"); /* Allow the socket to be reused - incase connection is closed prematurely */ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) { @@ -168,12 +174,57 @@ int main(int argc, char **argv){ printf("Bad RVVI_API_VERSION\n"); } + /* Construct the Ethernet header */ + memset(sendbuf, 0, BUF_SIZ); + /* Ethernet header */ + sendeh->ether_shost[0] = SRC_MAC0; + sendeh->ether_shost[1] = SRC_MAC1; + sendeh->ether_shost[2] = SRC_MAC2; + sendeh->ether_shost[3] = SRC_MAC3; + sendeh->ether_shost[4] = SRC_MAC4; + sendeh->ether_shost[5] = SRC_MAC5; + sendeh->ether_dhost[0] = DEST_MAC0; + sendeh->ether_dhost[1] = DEST_MAC1; + sendeh->ether_dhost[2] = DEST_MAC2; + sendeh->ether_dhost[3] = DEST_MAC3; + sendeh->ether_dhost[4] = DEST_MAC4; + sendeh->ether_dhost[5] = DEST_MAC5; + /* Ethertype field */ + //eh->ether_type = htons(ETH_P_IP); + sendeh->ether_type = htons(ETHER_TYPE); + tx_len += sizeof(struct ether_header); + /* Packet data */ + sendbuf[tx_len++] = 0xde; + sendbuf[tx_len++] = 0xad; + sendbuf[tx_len++] = 0xbe; + sendbuf[tx_len++] = 0xef; + rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"); rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME,"riscv"); rvviRefConfigSetString(IDV_CONFIG_MODEL_VARIANT, "RV64GC"); rvviRefConfigSetInt(IDV_CONFIG_MODEL_ADDRESS_BUS_WIDTH, 56); rvviRefConfigSetInt(IDV_CONFIG_MAX_NET_LATENCY_RETIREMENTS, 6); + /* Index of the network device */ + socket_address.sll_ifindex = ifopts.ifr_ifindex; + /* Address length*/ + socket_address.sll_halen = ETH_ALEN; + /* Destination MAC */ + socket_address.sll_addr[0] = DEST_MAC0; + socket_address.sll_addr[1] = DEST_MAC1; + socket_address.sll_addr[2] = DEST_MAC2; + socket_address.sll_addr[3] = DEST_MAC3; + socket_address.sll_addr[4] = DEST_MAC4; + socket_address.sll_addr[5] = DEST_MAC5; + + int i; + printf("buffer: "); + for(i=0;i Date: Tue, 9 Jul 2024 14:16:13 -0500 Subject: [PATCH 57/95] Correctly sending the ethernet frame on a mismatch. Now just need to get vivado to actually trigger. --- fpga/rvvidaemon/rvvidaemon.c | 11 ++++++++-- fpga/rvvidaemon/send-copy.c | 39 +++++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 27e70a1bf..f31393e60 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -71,6 +71,7 @@ struct sockaddr_ll socket_address; uint8_t sendbuf[BUF_SIZ]; struct ether_header *sendeh = (struct ether_header *) sendbuf; int tx_len = 0; +int sockfd; typedef struct { uint64_t PC; @@ -131,7 +132,6 @@ int main(int argc, char **argv){ /* fputs("refresh_hw_device [lindex [get_hw_devices xc7a100t_0] 0]\n", VivadoPipeFP); */ /* fputs("[get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}]]\n", VivadoPipeFP); */ - int sockfd; uint8_t buf[BUF_SIZ]; int sockopt; struct ifreq ifopts; /* set promiscuous mode */ @@ -224,7 +224,7 @@ int main(int argc, char **argv){ } printf("\n"); printf("sockfd %x\n", sockfd); - + // eventually we want to put the elffiles here rvviRefInit(NULL); rvviRefPcSet(0, 0x1000); @@ -342,6 +342,13 @@ int state_compare(int hart, uint64_t Minstret){ } if (result == 0) { + /* Send packet */ + if (sendto(sockfd, sendbuf, tx_len, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0){ + printf("Send failed\n"); + }else { + printf("send success!\n"); + } + sprintf(buf, "MISMATCH @ instruction # %ld\n", Minstret); idvMsgError(buf); /* fputs("run_hw_ila [get_hw_ilas -of_objects [get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}] -trigger_now\n", VivadoPipeFP); */ diff --git a/fpga/rvvidaemon/send-copy.c b/fpga/rvvidaemon/send-copy.c index 598e90f45..5d7f85ee8 100644 --- a/fpga/rvvidaemon/send-copy.c +++ b/fpga/rvvidaemon/send-copy.c @@ -15,6 +15,7 @@ #include #include #include +#include #define DEST_MAC0 0x43 #define DEST_MAC1 0x68 @@ -23,8 +24,16 @@ #define DEST_MAC4 0x02 #define DEST_MAC5 0x45 +#define SRC_MAC0 0x54 +#define SRC_MAC1 0x16 +#define SRC_MAC2 0x00 +#define SRC_MAC3 0x00 +#define SRC_MAC4 0x54 +#define SRC_MAC5 0x8F + #define DEFAULT_IF "eth0" #define BUF_SIZ 1024 +#define ETHER_TYPE 0x5c00 // The type defined in packetizer.sv int main(int argc, char *argv[]) { @@ -45,7 +54,8 @@ int main(int argc, char *argv[]) strcpy(ifName, DEFAULT_IF); /* Open RAW socket to send on */ - if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) { + //if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) { + if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) { perror("socket"); } @@ -63,12 +73,18 @@ int main(int argc, char *argv[]) /* Construct the Ethernet header */ memset(sendbuf, 0, BUF_SIZ); /* Ethernet header */ - eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0]; - eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1]; - eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2]; - eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3]; - eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4]; - eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5]; + /* eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0]; */ + /* eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1]; */ + /* eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2]; */ + /* eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3]; */ + /* eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4]; */ + /* eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5]; */ + eh->ether_shost[0] = SRC_MAC0; + eh->ether_shost[1] = SRC_MAC1; + eh->ether_shost[2] = SRC_MAC2; + eh->ether_shost[3] = SRC_MAC3; + eh->ether_shost[4] = SRC_MAC4; + eh->ether_shost[5] = SRC_MAC5; eh->ether_dhost[0] = DEST_MAC0; eh->ether_dhost[1] = DEST_MAC1; eh->ether_dhost[2] = DEST_MAC2; @@ -76,7 +92,8 @@ int main(int argc, char *argv[]) eh->ether_dhost[4] = DEST_MAC4; eh->ether_dhost[5] = DEST_MAC5; /* Ethertype field */ - eh->ether_type = htons(ETH_P_IP); + //eh->ether_type = htons(ETH_P_IP); + eh->ether_type = htons(ETHER_TYPE); tx_len += sizeof(struct ether_header); /* Packet data */ @@ -103,10 +120,14 @@ int main(int argc, char *argv[]) printf("%02hhx ", sendbuf[i]); } printf("\n"); + printf("sockfd %x\n", sockfd); /* Send packet */ - if (sendto(sockfd, sendbuf, tx_len, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0) + if (sendto(sockfd, sendbuf, tx_len, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0){ printf("Send failed\n"); + }else { printf("send success!\n"); + } + close(sockfd); return 0; } From e0a1f0e39f5519e02c3ced8691062f5458aba9b1 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 9 Jul 2024 14:21:43 -0500 Subject: [PATCH 58/95] Really close now. --- fpga/rvvidaemon/rvvidaemon.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index f31393e60..b5438590f 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -194,10 +194,12 @@ int main(int argc, char **argv){ sendeh->ether_type = htons(ETHER_TYPE); tx_len += sizeof(struct ether_header); /* Packet data */ - sendbuf[tx_len++] = 0xde; - sendbuf[tx_len++] = 0xad; - sendbuf[tx_len++] = 0xbe; - sendbuf[tx_len++] = 0xef; + sendbuf[tx_len++] = 't'; + sendbuf[tx_len++] = 'r'; + sendbuf[tx_len++] = 'i'; + sendbuf[tx_len++] = 'g'; + sendbuf[tx_len++] = 'i'; + sendbuf[tx_len++] = 'n'; rvviRefConfigSetString(IDV_CONFIG_MODEL_VENDOR, "riscv.ovpworld.org"); rvviRefConfigSetString(IDV_CONFIG_MODEL_NAME,"riscv"); From 67346853330d994552c81b01b942158e8e0f19f2 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 9 Jul 2024 19:04:18 -0500 Subject: [PATCH 59/95] Fixed connection bugs in the top level fpga which preventing sending ethernet frames back to the trigger in unit. --- fpga/src/fpgaTopArtyA7.sv | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index 8202d735f..e5a706d0d 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -1128,10 +1128,10 @@ module fpgaTop (* mark_debug = "true" *) logic RvviAxiWvalid; (* mark_debug = "true" *) logic RvviAxiWready; - logic [31:0] RvviAxiRdata; +(* mark_debug = "true" *) logic [31:0] RvviAxiRdata; logic [3:0] RvviAxiRstrb; - logic RvviAxiRlast; - logic RvviAxiRvalid; +(* mark_debug = "true" *) logic RvviAxiRlast; +(* mark_debug = "true" *) logic RvviAxiRvalid; (* mark_debug = "true" *) logic IlaTrigger; @@ -1144,8 +1144,9 @@ module fpgaTop eth_mac_mii_fifo #(.TARGET("XILINX"), .CLOCK_INPUT_STYLE("BUFG"), .AXIS_DATA_WIDTH(32), .TX_FIFO_DEPTH(1024)) ethernet(.rst(bus_struct_reset), .logic_clk(CPUCLK), .logic_rst(bus_struct_reset), .tx_axis_tdata(RvviAxiWdata), .tx_axis_tkeep(RvviAxiWstrb), .tx_axis_tvalid(RvviAxiWvalid), .tx_axis_tready(RvviAxiWready), - .tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), - .rx_axis_tlast(), .rx_axis_tuser(), + .tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(RvviAxiRdata), + .rx_axis_tkeep(RvviAxiRstrb), .rx_axis_tvalid(RvviAxiRvalid), .rx_axis_tready(1'b1), + .rx_axis_tlast(RvviAxiRlast), .rx_axis_tuser(), .mii_rx_clk(phy_rx_clk), .mii_rxd(phy_rxd), From cf986b5fb853d4351ebb232c4867353d01116fde Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Tue, 9 Jul 2024 19:04:51 -0500 Subject: [PATCH 60/95] Really close to having the trigger in module work. Can trigger on the data of the correct frame, but trigger in is still not working. --- fpga/rvvidaemon/rvvidaemon.c | 37 ++++++++++++++++++++++++------------ src/rvvi/triggergen.sv | 6 +++--- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index b5438590f..6642afe28 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -176,19 +176,32 @@ int main(int argc, char **argv){ /* Construct the Ethernet header */ memset(sendbuf, 0, BUF_SIZ); + sendbuf[0] = DEST_MAC0; + sendbuf[1] = DEST_MAC1; + sendbuf[2] = DEST_MAC2; + sendbuf[3] = DEST_MAC3; + sendbuf[4] = DEST_MAC4; + sendbuf[5] = DEST_MAC5; + sendbuf[6] = SRC_MAC0; + sendbuf[7] = SRC_MAC1; + sendbuf[8] = SRC_MAC2; + sendbuf[9] = SRC_MAC3; + sendbuf[10] = SRC_MAC4; + sendbuf[11] = SRC_MAC5; + /* Ethernet header */ - sendeh->ether_shost[0] = SRC_MAC0; - sendeh->ether_shost[1] = SRC_MAC1; - sendeh->ether_shost[2] = SRC_MAC2; - sendeh->ether_shost[3] = SRC_MAC3; - sendeh->ether_shost[4] = SRC_MAC4; - sendeh->ether_shost[5] = SRC_MAC5; - sendeh->ether_dhost[0] = DEST_MAC0; - sendeh->ether_dhost[1] = DEST_MAC1; - sendeh->ether_dhost[2] = DEST_MAC2; - sendeh->ether_dhost[3] = DEST_MAC3; - sendeh->ether_dhost[4] = DEST_MAC4; - sendeh->ether_dhost[5] = DEST_MAC5; + /* sendeh->ether_shost[0] = SRC_MAC0; */ + /* sendeh->ether_shost[1] = SRC_MAC1; */ + /* sendeh->ether_shost[2] = SRC_MAC2; */ + /* sendeh->ether_shost[3] = SRC_MAC3; */ + /* sendeh->ether_shost[4] = SRC_MAC4; */ + /* sendeh->ether_shost[5] = SRC_MAC5; */ + /* sendeh->ether_dhost[0] = DEST_MAC0; */ + /* sendeh->ether_dhost[1] = DEST_MAC1; */ + /* sendeh->ether_dhost[2] = DEST_MAC2; */ + /* sendeh->ether_dhost[3] = DEST_MAC3; */ + /* sendeh->ether_dhost[4] = DEST_MAC4; */ + /* sendeh->ether_dhost[5] = DEST_MAC5; */ /* Ethertype field */ //eh->ether_type = htons(ETH_P_IP); sendeh->ether_type = htons(ETHER_TYPE); diff --git a/src/rvvi/triggergen.sv b/src/rvvi/triggergen.sv index f8dc4ba8d..76d166380 100644 --- a/src/rvvi/triggergen.sv +++ b/src/rvvi/triggergen.sv @@ -46,9 +46,9 @@ module triggergen import cvw::*; ( logic RvviAxiRvalidDelay; logic Match, Overflow, Mismatch, Threshold; - assign mem[0] = 32'h0000_1654; // src mac [31:0] - assign mem[1] = 32'h6843_8F54; // dst mac [15:0], src mac [47:32] - assign mem[2] = 32'h4502_1111; // dst mac [47:16] + assign mem[0] = 32'h1111_6843; // dst mac [31:0] + assign mem[1] = 32'h1654_4502; // src mac [15:0], dst mac [47:32] + assign mem[2] = 32'h8f54_0000; // src mac [47:16] assign mem[3] = 32'h7274_005c; // "rt", ether type 005c assign mem[4] = 32'h6e69_6769; // "igin" (trigin) From e6dc962d114f1d9c27d6f6859fccfe04ea478f85 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 10 Jul 2024 12:05:10 -0500 Subject: [PATCH 61/95] Yay! the trigger is correctly working now! --- fpga/constraints/small-debug.xdc | 36 +++++++++++++++++++++++++++++++- src/rvvi/triggergen.sv | 19 ++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/fpga/constraints/small-debug.xdc b/fpga/constraints/small-debug.xdc index b244a1747..44151c6bf 100644 --- a/fpga/constraints/small-debug.xdc +++ b/fpga/constraints/small-debug.xdc @@ -19,7 +19,7 @@ connect_debug_port u_ila_0/clk [get_nets CPUCLK] set_property port_width 32 [get_debug_ports u_ila_0/probe0] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0] -connect_debug_port u_ila_0/probe0 [get_nets [list {RvviAxiWdata[0]} {RvviAxiWdata[1]} {RvviAxiWdata[2]} {RvviAxiWdata[3]} {RvviAxiWdata[4]} {RvviAxiWdata[5]} {RvviAxiWdata[6]} {RvviAxiWdata[7]} {RvviAxiWdata[8]} {RvviAxiWdata[9]} {RvviAxiWdata[10]} {RvviAxiWdata[11]} {RvviAxiWdata[12]} {RvviAxiWdata[13]} {RvviAxiWdata[14]} {RvviAxiWdata[15]} {RvviAxiWdata[16]} {RvviAxiWdata[17]} {RvviAxiWdata[18]} {RvviAxiWdata[19]} {RvviAxiWdata[20]} {RvviAxiWdata[21]} {RvviAxiWdata[22]} {RvviAxiWdata[23]} {RvviAxiWdata[24]} {RvviAxiWdata[25]} {RvviAxiWdata[26]} {RvviAxiWdata[27]} {RvviAxiWdata[28]} {RvviAxiWdata[29]} {RvviAxiWdata[30]} {RvviAxiWdata[31]} ]] +connect_debug_port u_ila_0/probe0 [get_nets [list {RvviAxiRdata[0]} {RvviAxiRdata[1]} {RvviAxiRdata[2]} {RvviAxiRdata[3]} {RvviAxiRdata[4]} {RvviAxiRdata[5]} {RvviAxiRdata[6]} {RvviAxiRdata[7]} {RvviAxiRdata[8]} {RvviAxiRdata[9]} {RvviAxiRdata[10]} {RvviAxiRdata[11]} {RvviAxiRdata[12]} {RvviAxiRdata[13]} {RvviAxiRdata[14]} {RvviAxiRdata[15]} {RvviAxiRdata[16]} {RvviAxiRdata[17]} {RvviAxiRdata[18]} {RvviAxiRdata[19]} {RvviAxiRdata[20]} {RvviAxiRdata[21]} {RvviAxiRdata[22]} {RvviAxiRdata[23]} {RvviAxiRdata[24]} {RvviAxiRdata[25]} {RvviAxiRdata[26]} {RvviAxiRdata[27]} {RvviAxiRdata[28]} {RvviAxiRdata[29]} {RvviAxiRdata[30]} {RvviAxiRdata[31]} ]] create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe1] @@ -76,6 +76,40 @@ set_property port_width 1 [get_debug_ports u_ila_0/probe10] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe10] connect_debug_port u_ila_0/probe10 [get_nets [list {RvviAxiWready}]] +create_debug_port u_ila_0 probe +set_property port_width 3 [get_debug_ports u_ila_0/probe11] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe11] +connect_debug_port u_ila_0/probe11 [get_nets [list {triggergen/CurrState[0]} {triggergen/CurrState[1]} {triggergen/CurrState[2]}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe12] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe12] +connect_debug_port u_ila_0/probe12 [get_nets [list {RvviAxiRlast}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe13] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe13] +connect_debug_port u_ila_0/probe13 [get_nets [list {RvviAxiRvalid}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe14] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe14] +connect_debug_port u_ila_0/probe14 [get_nets [list {triggergen/IlaTriggerOneCycle}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe15] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe15] +connect_debug_port u_ila_0/probe15 [get_nets [list {triggergen/TriggerReset}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe16] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe16] +connect_debug_port u_ila_0/probe16 [get_nets [list {triggergen/TriggerEn}]] + +create_debug_port u_ila_0 probe +set_property port_width 4 [get_debug_ports u_ila_0/probe17] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe17] +connect_debug_port u_ila_0/probe17 [get_nets [list {triggergen/TriggerCount[0]} {triggergen/TriggerCount[1]} {triggergen/TriggerCount[2]} {triggergen/TriggerCount[3]}]] # the debug hub has issues with the clocks from the mmcm so lets give up an connect to the 100Mhz input clock. diff --git a/src/rvvi/triggergen.sv b/src/rvvi/triggergen.sv index 76d166380..1b7e3ef4f 100644 --- a/src/rvvi/triggergen.sv +++ b/src/rvvi/triggergen.sv @@ -45,6 +45,7 @@ module triggergen import cvw::*; ( logic [3:0] RvviAxiRstrbDelay; logic RvviAxiRvalidDelay; logic Match, Overflow, Mismatch, Threshold; +(* mark_debug = "true" *) logic IlaTriggerOneCycle; assign mem[0] = 32'h1111_6843; // dst mac [31:0] assign mem[1] = 32'h1654_4502; // src mac [15:0], dst mac [47:32] @@ -85,8 +86,24 @@ module triggergen import cvw::*; ( assign Overflow = Counter > 4'd4; assign Threshold = Counter >= 4'd4; assign Mismatch = (mem[Counter] != RvviAxiRdataDelay) & (CurrState == STATE_COMPARE) & RvviAxiRvalidDelay; - assign IlaTrigger = CurrState == STATE_TRIGGER; + assign IlaTriggerOneCycle = CurrState == STATE_TRIGGER; assign CounterRst = CurrState == STATE_RST; assign CounterEn = RvviAxiRvalid; +/* -----\/----- EXCLUDED -----\/----- + always_ff @(posedge clk) begin + if(reset) IlaTrigger <= '0; + else if (IlaTriggerOneCycle) IlaTrigger <= '1; + else if (IlaTriggerAck) IlaTrigger <= '0; + else IlaTrigger <= IlaTrigger; + end + -----/\----- EXCLUDED -----/\----- */ + +(* mark_debug = "true" *) logic [3:0] TriggerCount; +(* mark_debug = "true" *) logic TriggerReset, TriggerEn; + counter #(4) triggercounter(clk, reset | TriggerReset, TriggerEn, TriggerCount); + assign TriggerReset = TriggerCount == 4'd10; + assign TriggerEn = IlaTriggerOneCycle | (TriggerCount != 4'd0 & TriggerCount < 4'd10); + assign IlaTrigger = TriggerEn; + endmodule From f0096f5a4329df743cf07f568a59938cc0f25984 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Wed, 10 Jul 2024 15:10:37 -0500 Subject: [PATCH 62/95] Yay. It's actually working! The FPGA/ImperasDV hybrid is working. --- fpga/constraints/marked_debug.txt | 1 + fpga/constraints/small-debug.xdc | 22 +--------------------- src/rvvi/triggergen.sv | 15 ++++++++------- 3 files changed, 10 insertions(+), 28 deletions(-) diff --git a/fpga/constraints/marked_debug.txt b/fpga/constraints/marked_debug.txt index 5217067eb..afed3dd23 100644 --- a/fpga/constraints/marked_debug.txt +++ b/fpga/constraints/marked_debug.txt @@ -7,3 +7,4 @@ lsu/lsu.sv: logic PAdrM lsu/lsu.sv: logic ReadDataM lsu/lsu.sv: logic WriteDataM lsu/lsu.sv: logic MemRWM +privileged/csrc.sv: logic HPMCOUNTER_REGW diff --git a/fpga/constraints/small-debug.xdc b/fpga/constraints/small-debug.xdc index 44151c6bf..10d64c126 100644 --- a/fpga/constraints/small-debug.xdc +++ b/fpga/constraints/small-debug.xdc @@ -19,7 +19,7 @@ connect_debug_port u_ila_0/clk [get_nets CPUCLK] set_property port_width 32 [get_debug_ports u_ila_0/probe0] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0] -connect_debug_port u_ila_0/probe0 [get_nets [list {RvviAxiRdata[0]} {RvviAxiRdata[1]} {RvviAxiRdata[2]} {RvviAxiRdata[3]} {RvviAxiRdata[4]} {RvviAxiRdata[5]} {RvviAxiRdata[6]} {RvviAxiRdata[7]} {RvviAxiRdata[8]} {RvviAxiRdata[9]} {RvviAxiRdata[10]} {RvviAxiRdata[11]} {RvviAxiRdata[12]} {RvviAxiRdata[13]} {RvviAxiRdata[14]} {RvviAxiRdata[15]} {RvviAxiRdata[16]} {RvviAxiRdata[17]} {RvviAxiRdata[18]} {RvviAxiRdata[19]} {RvviAxiRdata[20]} {RvviAxiRdata[21]} {RvviAxiRdata[22]} {RvviAxiRdata[23]} {RvviAxiRdata[24]} {RvviAxiRdata[25]} {RvviAxiRdata[26]} {RvviAxiRdata[27]} {RvviAxiRdata[28]} {RvviAxiRdata[29]} {RvviAxiRdata[30]} {RvviAxiRdata[31]} ]] +connect_debug_port u_ila_0/probe0 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][0]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][1]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][2]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][3]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][4]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][5]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][6]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][7]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][8]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][9]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][10]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][11]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][12]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][13]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][14]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][15]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][16]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][17]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][18]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][19]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][20]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][21]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][22]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][23]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][24]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][25]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][26]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][27]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][28]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][29]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][30]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][31]} ]] create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe1] @@ -91,26 +91,6 @@ set_property port_width 1 [get_debug_ports u_ila_0/probe13] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe13] connect_debug_port u_ila_0/probe13 [get_nets [list {RvviAxiRvalid}]] -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe14] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe14] -connect_debug_port u_ila_0/probe14 [get_nets [list {triggergen/IlaTriggerOneCycle}]] - -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe15] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe15] -connect_debug_port u_ila_0/probe15 [get_nets [list {triggergen/TriggerReset}]] - -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe16] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe16] -connect_debug_port u_ila_0/probe16 [get_nets [list {triggergen/TriggerEn}]] - -create_debug_port u_ila_0 probe -set_property port_width 4 [get_debug_ports u_ila_0/probe17] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe17] -connect_debug_port u_ila_0/probe17 [get_nets [list {triggergen/TriggerCount[0]} {triggergen/TriggerCount[1]} {triggergen/TriggerCount[2]} {triggergen/TriggerCount[3]}]] - # the debug hub has issues with the clocks from the mmcm so lets give up an connect to the 100Mhz input clock. #connect_debug_port dbg_hub/clk [get_nets default_100mhz_clk] diff --git a/src/rvvi/triggergen.sv b/src/rvvi/triggergen.sv index 1b7e3ef4f..0a4269024 100644 --- a/src/rvvi/triggergen.sv +++ b/src/rvvi/triggergen.sv @@ -45,7 +45,7 @@ module triggergen import cvw::*; ( logic [3:0] RvviAxiRstrbDelay; logic RvviAxiRvalidDelay; logic Match, Overflow, Mismatch, Threshold; -(* mark_debug = "true" *) logic IlaTriggerOneCycle; + logic IlaTriggerOneCycle; assign mem[0] = 32'h1111_6843; // dst mac [31:0] assign mem[1] = 32'h1654_4502; // src mac [15:0], dst mac [47:32] @@ -99,11 +99,12 @@ module triggergen import cvw::*; ( end -----/\----- EXCLUDED -----/\----- */ -(* mark_debug = "true" *) logic [3:0] TriggerCount; -(* mark_debug = "true" *) logic TriggerReset, TriggerEn; - counter #(4) triggercounter(clk, reset | TriggerReset, TriggerEn, TriggerCount); - assign TriggerReset = TriggerCount == 4'd10; - assign TriggerEn = IlaTriggerOneCycle | (TriggerCount != 4'd0 & TriggerCount < 4'd10); - assign IlaTrigger = TriggerEn; + // this is a bit hacky, but it works! + logic [3:0] TriggerCount; + logic TriggerReset, TriggerEn; + counter #(4) triggercounter(clk, reset | TriggerReset, TriggerEn, TriggerCount); + assign TriggerReset = TriggerCount == 4'd10; + assign TriggerEn = IlaTriggerOneCycle | (TriggerCount != 4'd0 & TriggerCount < 4'd10); + assign IlaTrigger = TriggerEn; endmodule From abf9da01ab9f07815b526f25b3b883fea40b0ef9 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 11 Jul 2024 10:41:34 -0500 Subject: [PATCH 63/95] code cleanup. --- fpga/rvvidaemon/rvvidaemon.c | 40 ------------------------------------ 1 file changed, 40 deletions(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index 6642afe28..deccb1880 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -66,7 +66,6 @@ //#define ETHER_TYPE 0x0000 // The type defined in packetizer.sv #define DEFAULT_IF "eno1" -FILE *VivadoPipeFP; struct sockaddr_ll socket_address; uint8_t sendbuf[BUF_SIZ]; struct ether_header *sendeh = (struct ether_header *) sendbuf; @@ -114,24 +113,6 @@ int main(int argc, char **argv){ return -1; } - // step 1 open a pipe to vivado - /* if (( VivadoPipeFP = popen("vivado -mode tcl", "w")) == NULL){ */ - /* perror("popen"); */ - /* exit(1); */ - /* } */ - /* fputs("open_hw_manager\n", VivadoPipeFP); */ - /* fputs("connect_hw_server -url localhost:3121\n", VivadoPipeFP); */ - /* fputs("current_hw_target [get_hw_targets *\/xilinx_tcf/Digilent/\*]\n", VivadoPipeFP); */ - /* fputs("open_hw_target\n", VivadoPipeFP); */ - /* fputs("set_property PARAM.FREQUENCY 7500000 [get_hw_targets localhost:3121/xilinx_tcf/Digilent/210319B7CA87A]\n", VivadoPipeFP); */ - - /* // *** bug these need to made relative paths. */ - /* fputs("set_property PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); */ - /* fputs("set_property FULL_PROBES.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.ltx} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); */ - /* fputs("set_property PROGRAM.FILE {/home/ross/repos/cvw/fpga/generator/WallyFPGA.runs/impl_1/fpgaTop.bit} [get_hw_devices xc7a100t_0]\n", VivadoPipeFP); */ - /* fputs("refresh_hw_device [lindex [get_hw_devices xc7a100t_0] 0]\n", VivadoPipeFP); */ - /* fputs("[get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}]]\n", VivadoPipeFP); */ - uint8_t buf[BUF_SIZ]; int sockopt; struct ifreq ifopts; /* set promiscuous mode */ @@ -189,21 +170,6 @@ int main(int argc, char **argv){ sendbuf[10] = SRC_MAC4; sendbuf[11] = SRC_MAC5; - /* Ethernet header */ - /* sendeh->ether_shost[0] = SRC_MAC0; */ - /* sendeh->ether_shost[1] = SRC_MAC1; */ - /* sendeh->ether_shost[2] = SRC_MAC2; */ - /* sendeh->ether_shost[3] = SRC_MAC3; */ - /* sendeh->ether_shost[4] = SRC_MAC4; */ - /* sendeh->ether_shost[5] = SRC_MAC5; */ - /* sendeh->ether_dhost[0] = DEST_MAC0; */ - /* sendeh->ether_dhost[1] = DEST_MAC1; */ - /* sendeh->ether_dhost[2] = DEST_MAC2; */ - /* sendeh->ether_dhost[3] = DEST_MAC3; */ - /* sendeh->ether_dhost[4] = DEST_MAC4; */ - /* sendeh->ether_dhost[5] = DEST_MAC5; */ - /* Ethertype field */ - //eh->ether_type = htons(ETH_P_IP); sendeh->ether_type = htons(ETHER_TYPE); tx_len += sizeof(struct ether_header); /* Packet data */ @@ -307,7 +273,6 @@ int main(int argc, char **argv){ printf("Simulation halted due to mismatch\n"); - //pclose(VivadoPipeFP); close(sockfd); @@ -366,12 +331,7 @@ int state_compare(int hart, uint64_t Minstret){ sprintf(buf, "MISMATCH @ instruction # %ld\n", Minstret); idvMsgError(buf); - /* fputs("run_hw_ila [get_hw_ilas -of_objects [get_hw_devices xc7a100t_0] -filter {CELL_NAME=~\"u_ila_0\"}] -trigger_now\n", VivadoPipeFP); */ - /* fputs("current_hw_ila_data [upload_hw_ila_data hw_ila_1]\n", VivadoPipeFP); */ - /* fputs("display_hw_ila_data [current_hw_ila_data]\n", VivadoPipeFP); */ - /* fputs("write_hw_ila_data my_hw_ila_data [current_hw_ila_data]\n", VivadoPipeFP); */ return -1; - //if (ON_MISMATCH_DUMP_STATE) dump_state(hart); } } From c72f0fd504590abd29c40954754b65bbc1ebac12 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 11 Jul 2024 10:49:06 -0500 Subject: [PATCH 64/95] Added csr comparison. --- fpga/rvvidaemon/rvvidaemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fpga/rvvidaemon/rvvidaemon.c b/fpga/rvvidaemon/rvvidaemon.c index deccb1880..1e9d17f66 100644 --- a/fpga/rvvidaemon/rvvidaemon.c +++ b/fpga/rvvidaemon/rvvidaemon.c @@ -316,7 +316,7 @@ int state_compare(int hart, uint64_t Minstret){ result &= rvviRefInsBinCompare(hart); result &= rvviRefGprsCompare(hart); result &= rvviRefFprsCompare(hart); - //result &= rvviRefCsrCompare(hart); + result &= rvviRefCsrsCompare(hart); } else { result = 0; } From 79d0cb96c2074393efc624dc256cc8dbfb15f14e Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Thu, 18 Jul 2024 18:22:26 -0500 Subject: [PATCH 65/95] Added verilog-ethernet as a submodule. Hoping we can make use of sparse-checkout as there are so many files in this repo. --- .gitmodules | 4 ++++ addins/verilog-ethernet | 1 + 2 files changed, 5 insertions(+) create mode 160000 addins/verilog-ethernet diff --git a/.gitmodules b/.gitmodules index 4717e75eb..4368f3f07 100644 --- a/.gitmodules +++ b/.gitmodules @@ -29,3 +29,7 @@ [submodule "addins/ahbsdc"] path = addins/ahbsdc url = http://github.com/JacobPease/ahbsdc.git +[submodule "addins/verilog-ethernet"] + sparseCheckout = true + path = addins/verilog-ethernet + url = https://github.com/ross144/verilog-ethernet.git diff --git a/addins/verilog-ethernet b/addins/verilog-ethernet new file mode 160000 index 000000000..baac5f8d8 --- /dev/null +++ b/addins/verilog-ethernet @@ -0,0 +1 @@ +Subproject commit baac5f8d811d43853d59d69957975ead8bbed088 From 9c1779a2d5ab986990be71e65e4f1cb3fff50ae0 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 19 Jul 2024 13:11:48 -0500 Subject: [PATCH 66/95] Added some documenation about sparse-checkout for verilog-ethernet submodule. --- addins/README.md | 3 +++ addins/sparse-checkout | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 addins/README.md create mode 100644 addins/sparse-checkout diff --git a/addins/README.md b/addins/README.md new file mode 100644 index 000000000..ba04e05eb --- /dev/null +++ b/addins/README.md @@ -0,0 +1,3 @@ +verilog-ethernet contains many ethernet devices. Wally's synthesizable RVVI interface only requires a small subset of these files. +To do a sparse checkout of this repo copy sparse-checkout to cvw/.git/modules/addins/verilog-ethernet/info +This will make the working directory only contain the necessary files. diff --git a/addins/sparse-checkout b/addins/sparse-checkout new file mode 100644 index 000000000..76eadb284 --- /dev/null +++ b/addins/sparse-checkout @@ -0,0 +1,16 @@ +rtl/eth_mac_mii_fifo.v +rtl/eth_mac_mii.v +rtl/mii_phy_if.v +rtl/ssio_ddr_in.v +rtl/eth_mac_1g.v +rtl/axis_gmii_rx.v +rtl/lfsr.v +rtl/eth_axis_tx.v +rtl/mac_ctrl_tx.v +rtl/axis_gmii_tx.v +rtl/mac_ctrl_rx.v +rtl/mac_pause_ctrl_tx.v +rtl/mac_pause_ctrl_rx.v +lib/axis/rtl/axis_async_fifo_adapter.v +lib/axis/rtl/axis_adapter.v +lib/axis/rtl/axis_async_fifo.v From a324e79b6f1386b856ca0be6eadc894f9d809f68 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 19 Jul 2024 13:12:13 -0500 Subject: [PATCH 67/95] Updated the ethernet frame gap for a faster computer. --- src/rvvi/packetizer.sv | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 1599c28a9..0d33947c1 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -102,7 +102,8 @@ module packetizer import cvw::*; #(parameter cvw_t P, counter #(32) rstcounter(m_axi_aclk, RstCountRst, RstCountEn, RstCount); assign CountFlag = RstCount == 32'd100000000; //assign CountFlag = RstCount == 32'd10; - assign DelayFlag = RstCount == 32'd800; + //assign DelayFlag = RstCount == 32'd800; + assign DelayFlag = RstCount == 32'd350; //assign DelayFlag = RstCount == 32'd0; counter #(32) framecounter(m_axi_aclk, ~m_axi_aresetn, (RvviAxiWready & RvviAxiWlast), FrameCount); From ce2cc486424f25d5738d2f195ef6debc6698a8d1 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 19 Jul 2024 13:36:26 -0500 Subject: [PATCH 68/95] Updated verilog-ethernet to be compatible with wally. --- addins/sparse-checkout | 32 ++++++++++++++++---------------- addins/verilog-ethernet | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/addins/sparse-checkout b/addins/sparse-checkout index 76eadb284..f1743725c 100644 --- a/addins/sparse-checkout +++ b/addins/sparse-checkout @@ -1,16 +1,16 @@ -rtl/eth_mac_mii_fifo.v -rtl/eth_mac_mii.v -rtl/mii_phy_if.v -rtl/ssio_ddr_in.v -rtl/eth_mac_1g.v -rtl/axis_gmii_rx.v -rtl/lfsr.v -rtl/eth_axis_tx.v -rtl/mac_ctrl_tx.v -rtl/axis_gmii_tx.v -rtl/mac_ctrl_rx.v -rtl/mac_pause_ctrl_tx.v -rtl/mac_pause_ctrl_rx.v -lib/axis/rtl/axis_async_fifo_adapter.v -lib/axis/rtl/axis_adapter.v -lib/axis/rtl/axis_async_fifo.v +rtl/eth_mac_mii_fifo.sv +rtl/eth_mac_mii.sv +rtl/mii_phy_if.sv +rtl/ssio_ddr_in.sv +rtl/eth_mac_1g.sv +rtl/axis_gmii_rx.sv +rtl/lfsr.sv +rtl/eth_axis_tx.sv +rtl/mac_ctrl_tx.sv +rtl/axis_gmii_tx.sv +rtl/mac_ctrl_rx.sv +rtl/mac_pause_ctrl_tx.sv +rtl/mac_pause_ctrl_rx.sv +lib/axis/rtl/axis_async_fifo_adapter.sv +lib/axis/rtl/axis_adapter.sv +lib/axis/rtl/axis_async_fifo.sv diff --git a/addins/verilog-ethernet b/addins/verilog-ethernet index baac5f8d8..13c33ff1a 160000 --- a/addins/verilog-ethernet +++ b/addins/verilog-ethernet @@ -1 +1 @@ -Subproject commit baac5f8d811d43853d59d69957975ead8bbed088 +Subproject commit 13c33ff1a82348691a40d78cf2bab10cbf4f76b2 From 0d40b8c933d47d33ffe1d3575e143296d4752f72 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 19 Jul 2024 15:48:20 -0500 Subject: [PATCH 69/95] Cleanup in prep to merge the rvvi branch into main. --- addins/sparse-checkout | 1 + addins/verilog-ethernet | 2 +- fpga/constraints/small-debug.xdc | 27 +- fpga/generator/Makefile | 2 + src/rvvi/axis_adapter.sv | 324 ---------- src/rvvi/axis_async_fifo.sv | 909 ---------------------------- src/rvvi/axis_async_fifo_adapter.sv | 377 ------------ src/rvvi/axis_gmii_rx.sv | 357 ----------- src/rvvi/axis_gmii_tx.sv | 457 -------------- src/rvvi/eth_axis_tx.sv | 408 ------------- src/rvvi/eth_mac_1g.sv | 643 -------------------- src/rvvi/eth_mac_mii.sv | 175 ------ src/rvvi/eth_mac_mii_fifo.sv | 339 ----------- src/rvvi/lfsr.sv | 446 -------------- src/rvvi/mac_ctrl_rx.sv | 447 -------------- src/rvvi/mac_ctrl_tx.sv | 420 ------------- src/rvvi/mac_pause_ctrl_rx.sv | 220 ------- src/rvvi/mac_pause_ctrl_tx.sv | 312 ---------- src/rvvi/mii_phy_if.sv | 140 ----- src/rvvi/ssio_ddr_in.sv | 150 ----- src/rvvi/ssio_sdr_in.sv | 166 ----- 21 files changed, 10 insertions(+), 6312 deletions(-) delete mode 100644 src/rvvi/axis_adapter.sv delete mode 100644 src/rvvi/axis_async_fifo.sv delete mode 100644 src/rvvi/axis_async_fifo_adapter.sv delete mode 100644 src/rvvi/axis_gmii_rx.sv delete mode 100644 src/rvvi/axis_gmii_tx.sv delete mode 100644 src/rvvi/eth_axis_tx.sv delete mode 100644 src/rvvi/eth_mac_1g.sv delete mode 100644 src/rvvi/eth_mac_mii.sv delete mode 100644 src/rvvi/eth_mac_mii_fifo.sv delete mode 100644 src/rvvi/lfsr.sv delete mode 100644 src/rvvi/mac_ctrl_rx.sv delete mode 100644 src/rvvi/mac_ctrl_tx.sv delete mode 100644 src/rvvi/mac_pause_ctrl_rx.sv delete mode 100644 src/rvvi/mac_pause_ctrl_tx.sv delete mode 100644 src/rvvi/mii_phy_if.sv delete mode 100644 src/rvvi/ssio_ddr_in.sv delete mode 100644 src/rvvi/ssio_sdr_in.sv diff --git a/addins/sparse-checkout b/addins/sparse-checkout index f1743725c..74cc3f25a 100644 --- a/addins/sparse-checkout +++ b/addins/sparse-checkout @@ -2,6 +2,7 @@ rtl/eth_mac_mii_fifo.sv rtl/eth_mac_mii.sv rtl/mii_phy_if.sv rtl/ssio_ddr_in.sv +rtl/ssio_sdr_in.sv rtl/eth_mac_1g.sv rtl/axis_gmii_rx.sv rtl/lfsr.sv diff --git a/addins/verilog-ethernet b/addins/verilog-ethernet index 13c33ff1a..43990ab4f 160000 --- a/addins/verilog-ethernet +++ b/addins/verilog-ethernet @@ -1 +1 @@ -Subproject commit 13c33ff1a82348691a40d78cf2bab10cbf4f76b2 +Subproject commit 43990ab4fd0c8d34dbc1be5cd8d4f3ed3e33f853 diff --git a/fpga/constraints/small-debug.xdc b/fpga/constraints/small-debug.xdc index 10d64c126..ce824620b 100644 --- a/fpga/constraints/small-debug.xdc +++ b/fpga/constraints/small-debug.xdc @@ -32,30 +32,25 @@ set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe2] connect_debug_port u_ila_0/probe2 [get_nets [list wallypipelinedsoc/core/InstrValidM ]] create_debug_port u_ila_0 probe -set_property port_width 4 [get_debug_ports u_ila_0/probe3] +set_property port_width 1 [get_debug_ports u_ila_0/probe3] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe3] -connect_debug_port u_ila_0/probe3 [get_nets [list {ethernet/eth_mac_1g_mii_inst/mii_phy_if_inst/mac_mii_txd[0]} {ethernet/eth_mac_1g_mii_inst/mii_phy_if_inst/mac_mii_txd[1]} {ethernet/eth_mac_1g_mii_inst/mii_phy_if_inst/mac_mii_txd[2]} {ethernet/eth_mac_1g_mii_inst/mii_phy_if_inst/mac_mii_txd[3]} ]] +connect_debug_port u_ila_0/probe3 [get_nets [list {RvviAxiRlast}]] create_debug_port u_ila_0 probe -set_property port_width 4 [get_debug_ports u_ila_0/probe4] +set_property port_width 1 [get_debug_ports u_ila_0/probe4] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe4] -connect_debug_port u_ila_0/probe4 [get_nets [list {packetizer/CurrState[0]} {packetizer/CurrState[1]} {packetizer/CurrState[2]} {packetizer/CurrState[3]}]] +connect_debug_port u_ila_0/probe4 [get_nets [list {RvviAxiRvalid}]] create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe5] +set_property port_width 4 [get_debug_ports u_ila_0/probe5] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe5] -connect_debug_port u_ila_0/probe5 [get_nets [list {ethernet/eth_mac_1g_mii_inst/mii_phy_if_inst/mac_mii_tx_en} ]] +connect_debug_port u_ila_0/probe5 [get_nets [list {packetizer/CurrState[0]} {packetizer/CurrState[1]} {packetizer/CurrState[2]} {packetizer/CurrState[3]}]] create_debug_port u_ila_0 probe set_property port_width 64 [get_debug_ports u_ila_0/probe6] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6] connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/PCM[0]} {wallypipelinedsoc/core/PCM[1]} {wallypipelinedsoc/core/PCM[2]} {wallypipelinedsoc/core/PCM[3]} {wallypipelinedsoc/core/PCM[4]} {wallypipelinedsoc/core/PCM[5]} {wallypipelinedsoc/core/PCM[6]} {wallypipelinedsoc/core/PCM[7]} {wallypipelinedsoc/core/PCM[8]} {wallypipelinedsoc/core/PCM[9]} {wallypipelinedsoc/core/PCM[10]} {wallypipelinedsoc/core/PCM[11]} {wallypipelinedsoc/core/PCM[12]} {wallypipelinedsoc/core/PCM[13]} {wallypipelinedsoc/core/PCM[14]} {wallypipelinedsoc/core/PCM[15]} {wallypipelinedsoc/core/PCM[16]} {wallypipelinedsoc/core/PCM[17]} {wallypipelinedsoc/core/PCM[18]} {wallypipelinedsoc/core/PCM[19]} {wallypipelinedsoc/core/PCM[20]} {wallypipelinedsoc/core/PCM[21]} {wallypipelinedsoc/core/PCM[22]} {wallypipelinedsoc/core/PCM[23]} {wallypipelinedsoc/core/PCM[24]} {wallypipelinedsoc/core/PCM[25]} {wallypipelinedsoc/core/PCM[26]} {wallypipelinedsoc/core/PCM[27]} {wallypipelinedsoc/core/PCM[28]} {wallypipelinedsoc/core/PCM[29]} {wallypipelinedsoc/core/PCM[30]} {wallypipelinedsoc/core/PCM[31]} {wallypipelinedsoc/core/PCM[32]} {wallypipelinedsoc/core/PCM[33]} {wallypipelinedsoc/core/PCM[34]} {wallypipelinedsoc/core/PCM[35]} {wallypipelinedsoc/core/PCM[36]} {wallypipelinedsoc/core/PCM[37]} {wallypipelinedsoc/core/PCM[38]} {wallypipelinedsoc/core/PCM[39]} {wallypipelinedsoc/core/PCM[40]} {wallypipelinedsoc/core/PCM[41]} {wallypipelinedsoc/core/PCM[42]} {wallypipelinedsoc/core/PCM[43]} {wallypipelinedsoc/core/PCM[44]} {wallypipelinedsoc/core/PCM[45]} {wallypipelinedsoc/core/PCM[46]} {wallypipelinedsoc/core/PCM[47]} {wallypipelinedsoc/core/PCM[48]} {wallypipelinedsoc/core/PCM[49]} {wallypipelinedsoc/core/PCM[50]} {wallypipelinedsoc/core/PCM[51]} {wallypipelinedsoc/core/PCM[52]} {wallypipelinedsoc/core/PCM[53]} {wallypipelinedsoc/core/PCM[54]} {wallypipelinedsoc/core/PCM[55]} {wallypipelinedsoc/core/PCM[56]} {wallypipelinedsoc/core/PCM[57]} {wallypipelinedsoc/core/PCM[58]} {wallypipelinedsoc/core/PCM[59]} {wallypipelinedsoc/core/PCM[60]} {wallypipelinedsoc/core/PCM[61]} {wallypipelinedsoc/core/PCM[62]} {wallypipelinedsoc/core/PCM[63]} ]] -#create_debug_port u_ila_0 probe -#set_property port_width 1 [get_debug_ports u_ila_0/probe7] -#set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7] -#connect_debug_port u_ila_0/probe7 [get_nets [list {IlaTrigger} ]] - create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe7] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7] @@ -81,16 +76,6 @@ set_property port_width 3 [get_debug_ports u_ila_0/probe11] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe11] connect_debug_port u_ila_0/probe11 [get_nets [list {triggergen/CurrState[0]} {triggergen/CurrState[1]} {triggergen/CurrState[2]}]] -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe12] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe12] -connect_debug_port u_ila_0/probe12 [get_nets [list {RvviAxiRlast}]] - -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe13] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe13] -connect_debug_port u_ila_0/probe13 [get_nets [list {RvviAxiRvalid}]] - # the debug hub has issues with the clocks from the mmcm so lets give up an connect to the 100Mhz input clock. #connect_debug_port dbg_hub/clk [get_nets default_100mhz_clk] diff --git a/fpga/generator/Makefile b/fpga/generator/Makefile index df4ed0e2a..c23e22ee0 100644 --- a/fpga/generator/Makefile +++ b/fpga/generator/Makefile @@ -51,6 +51,8 @@ PreProcessFiles: $(MAKE) -C ../../sim deriv rm -rf ../src/CopiedFiles_do_not_add_to_repo/ cp -r ../../src/ ../src/CopiedFiles_do_not_add_to_repo/ + cp -r ../../addins/verilog-ethernet/*/*.sv ../src/CopiedFiles_do_not_add_to_repo/rvvi + cp -r ../../addins/verilog-ethernet/*/*/*/*.sv ../src/CopiedFiles_do_not_add_to_repo/rvvi mkdir ../src/CopiedFiles_do_not_add_to_repo/config/ cp ../../config/deriv/fpga/config.vh ../src/CopiedFiles_do_not_add_to_repo/config/ ./insert_debug_comment.sh diff --git a/src/rvvi/axis_adapter.sv b/src/rvvi/axis_adapter.sv deleted file mode 100644 index 8807a03b7..000000000 --- a/src/rvvi/axis_adapter.sv +++ /dev/null @@ -1,324 +0,0 @@ -/* - -Copyright (c) 2014-2023 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * AXI4-Stream bus width adapter - */ -module axis_adapter # -( - // Width of input AXI stream interface in bits - parameter S_DATA_WIDTH = 8, - // Propagate tkeep signal on input interface - // If disabled, tkeep assumed to be 1'b1 - parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8), - // tkeep signal width (words per cycle) on input interface - parameter S_KEEP_WIDTH = ((S_DATA_WIDTH+7)/8), - // Width of output AXI stream interface in bits - parameter M_DATA_WIDTH = 8, - // Propagate tkeep signal on output interface - // If disabled, tkeep assumed to be 1'b1 - parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8), - // tkeep signal width (words per cycle) on output interface - parameter M_KEEP_WIDTH = ((M_DATA_WIDTH+7)/8), - // Propagate tid signal - parameter ID_ENABLE = 0, - // tid signal width - parameter ID_WIDTH = 8, - // Propagate tdest signal - parameter DEST_ENABLE = 0, - // tdest signal width - parameter DEST_WIDTH = 8, - // Propagate tuser signal - parameter USER_ENABLE = 1, - // tuser signal width - parameter USER_WIDTH = 1 -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [S_DATA_WIDTH-1:0] s_axis_tdata, - input wire [S_KEEP_WIDTH-1:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire [ID_WIDTH-1:0] s_axis_tid, - input wire [DEST_WIDTH-1:0] s_axis_tdest, - input wire [USER_WIDTH-1:0] s_axis_tuser, - - /* - * AXI output - */ - output wire [M_DATA_WIDTH-1:0] m_axis_tdata, - output wire [M_KEEP_WIDTH-1:0] m_axis_tkeep, - output wire m_axis_tvalid, - input wire m_axis_tready, - output wire m_axis_tlast, - output wire [ID_WIDTH-1:0] m_axis_tid, - output wire [DEST_WIDTH-1:0] m_axis_tdest, - output wire [USER_WIDTH-1:0] m_axis_tuser -); - -// force keep width to 1 when disabled -localparam S_BYTE_LANES = S_KEEP_ENABLE ? S_KEEP_WIDTH : 1; -localparam M_BYTE_LANES = M_KEEP_ENABLE ? M_KEEP_WIDTH : 1; - -// bus byte sizes (must be identical) -localparam S_BYTE_SIZE = S_DATA_WIDTH / S_BYTE_LANES; -localparam M_BYTE_SIZE = M_DATA_WIDTH / M_BYTE_LANES; - -// bus width assertions -initial begin - if (S_BYTE_SIZE * S_BYTE_LANES != S_DATA_WIDTH) begin - $error("Error: input data width not evenly divisible (instance %m)"); - $finish; - end - - if (M_BYTE_SIZE * M_BYTE_LANES != M_DATA_WIDTH) begin - $error("Error: output data width not evenly divisible (instance %m)"); - $finish; - end - - if (S_BYTE_SIZE != M_BYTE_SIZE) begin - $error("Error: byte size mismatch (instance %m)"); - $finish; - end -end - -generate - -if (M_BYTE_LANES == S_BYTE_LANES) begin : bypass - // same width; bypass - - assign s_axis_tready = m_axis_tready; - - assign m_axis_tdata = s_axis_tdata; - assign m_axis_tkeep = M_KEEP_ENABLE ? s_axis_tkeep : {M_KEEP_WIDTH{1'b1}}; - assign m_axis_tvalid = s_axis_tvalid; - assign m_axis_tlast = s_axis_tlast; - assign m_axis_tid = ID_ENABLE ? s_axis_tid : {ID_WIDTH{1'b0}}; - assign m_axis_tdest = DEST_ENABLE ? s_axis_tdest : {DEST_WIDTH{1'b0}}; - assign m_axis_tuser = USER_ENABLE ? s_axis_tuser : {USER_WIDTH{1'b0}}; - -end else if (M_BYTE_LANES > S_BYTE_LANES) begin : upsize - // output is wider; upsize - - // required number of segments in wider bus - localparam SEG_COUNT = M_BYTE_LANES / S_BYTE_LANES; - // data width and keep width per segment - localparam SEG_DATA_WIDTH = M_DATA_WIDTH / SEG_COUNT; - localparam SEG_KEEP_WIDTH = M_BYTE_LANES / SEG_COUNT; - - reg [$clog2(SEG_COUNT)-1:0] seg_reg = 0; - - reg [S_DATA_WIDTH-1:0] s_axis_tdata_reg = {S_DATA_WIDTH{1'b0}}; - reg [S_KEEP_WIDTH-1:0] s_axis_tkeep_reg = {S_KEEP_WIDTH{1'b0}}; - reg s_axis_tvalid_reg = 1'b0; - reg s_axis_tlast_reg = 1'b0; - reg [ID_WIDTH-1:0] s_axis_tid_reg = {ID_WIDTH{1'b0}}; - reg [DEST_WIDTH-1:0] s_axis_tdest_reg = {DEST_WIDTH{1'b0}}; - reg [USER_WIDTH-1:0] s_axis_tuser_reg = {USER_WIDTH{1'b0}}; - - reg [M_DATA_WIDTH-1:0] m_axis_tdata_reg = {M_DATA_WIDTH{1'b0}}; - reg [M_KEEP_WIDTH-1:0] m_axis_tkeep_reg = {M_KEEP_WIDTH{1'b0}}; - reg m_axis_tvalid_reg = 1'b0; - reg m_axis_tlast_reg = 1'b0; - reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; - reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; - reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; - - assign s_axis_tready = !s_axis_tvalid_reg; - - assign m_axis_tdata = m_axis_tdata_reg; - assign m_axis_tkeep = M_KEEP_ENABLE ? m_axis_tkeep_reg : {M_KEEP_WIDTH{1'b1}}; - assign m_axis_tvalid = m_axis_tvalid_reg; - assign m_axis_tlast = m_axis_tlast_reg; - assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; - assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; - assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; - - always @(posedge clk) begin - m_axis_tvalid_reg <= m_axis_tvalid_reg && !m_axis_tready; - - if (!m_axis_tvalid_reg || m_axis_tready) begin - // output register empty - - if (seg_reg == 0) begin - m_axis_tdata_reg[seg_reg*SEG_DATA_WIDTH +: SEG_DATA_WIDTH] <= s_axis_tvalid_reg ? s_axis_tdata_reg : s_axis_tdata; - m_axis_tkeep_reg <= s_axis_tvalid_reg ? s_axis_tkeep_reg : s_axis_tkeep; - end else begin - m_axis_tdata_reg[seg_reg*SEG_DATA_WIDTH +: SEG_DATA_WIDTH] <= s_axis_tdata; - m_axis_tkeep_reg[seg_reg*SEG_KEEP_WIDTH +: SEG_KEEP_WIDTH] <= s_axis_tkeep; - end - m_axis_tlast_reg <= s_axis_tvalid_reg ? s_axis_tlast_reg : s_axis_tlast; - m_axis_tid_reg <= s_axis_tvalid_reg ? s_axis_tid_reg : s_axis_tid; - m_axis_tdest_reg <= s_axis_tvalid_reg ? s_axis_tdest_reg : s_axis_tdest; - m_axis_tuser_reg <= s_axis_tvalid_reg ? s_axis_tuser_reg : s_axis_tuser; - - if (s_axis_tvalid_reg) begin - // consume data from buffer - s_axis_tvalid_reg <= 1'b0; - - if (s_axis_tlast_reg || seg_reg == SEG_COUNT-1) begin - seg_reg <= 0; - m_axis_tvalid_reg <= 1'b1; - end else begin - seg_reg <= seg_reg + 1; - end - end else if (s_axis_tvalid) begin - // data direct from input - if (s_axis_tlast || seg_reg == SEG_COUNT-1) begin - seg_reg <= 0; - m_axis_tvalid_reg <= 1'b1; - end else begin - seg_reg <= seg_reg + 1; - end - end - end else if (s_axis_tvalid && s_axis_tready) begin - // store input data in skid buffer - s_axis_tdata_reg <= s_axis_tdata; - s_axis_tkeep_reg <= s_axis_tkeep; - s_axis_tvalid_reg <= 1'b1; - s_axis_tlast_reg <= s_axis_tlast; - s_axis_tid_reg <= s_axis_tid; - s_axis_tdest_reg <= s_axis_tdest; - s_axis_tuser_reg <= s_axis_tuser; - end - - if (rst) begin - seg_reg <= 0; - s_axis_tvalid_reg <= 1'b0; - m_axis_tvalid_reg <= 1'b0; - end - end - -end else begin : downsize - // output is narrower; downsize - - // required number of segments in wider bus - localparam SEG_COUNT = S_BYTE_LANES / M_BYTE_LANES; - // data width and keep width per segment - localparam SEG_DATA_WIDTH = S_DATA_WIDTH / SEG_COUNT; - localparam SEG_KEEP_WIDTH = S_BYTE_LANES / SEG_COUNT; - - reg [S_DATA_WIDTH-1:0] s_axis_tdata_reg = {S_DATA_WIDTH{1'b0}}; - reg [S_KEEP_WIDTH-1:0] s_axis_tkeep_reg = {S_KEEP_WIDTH{1'b0}}; - reg s_axis_tvalid_reg = 1'b0; - reg s_axis_tlast_reg = 1'b0; - reg [ID_WIDTH-1:0] s_axis_tid_reg = {ID_WIDTH{1'b0}}; - reg [DEST_WIDTH-1:0] s_axis_tdest_reg = {DEST_WIDTH{1'b0}}; - reg [USER_WIDTH-1:0] s_axis_tuser_reg = {USER_WIDTH{1'b0}}; - - reg [M_DATA_WIDTH-1:0] m_axis_tdata_reg = {M_DATA_WIDTH{1'b0}}; - reg [M_KEEP_WIDTH-1:0] m_axis_tkeep_reg = {M_KEEP_WIDTH{1'b0}}; - reg m_axis_tvalid_reg = 1'b0; - reg m_axis_tlast_reg = 1'b0; - reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; - reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; - reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; - - assign s_axis_tready = !s_axis_tvalid_reg; - - assign m_axis_tdata = m_axis_tdata_reg; - assign m_axis_tkeep = M_KEEP_ENABLE ? m_axis_tkeep_reg : {M_KEEP_WIDTH{1'b1}}; - assign m_axis_tvalid = m_axis_tvalid_reg; - assign m_axis_tlast = m_axis_tlast_reg; - assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; - assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; - assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; - - always @(posedge clk) begin - m_axis_tvalid_reg <= m_axis_tvalid_reg && !m_axis_tready; - - if (!m_axis_tvalid_reg || m_axis_tready) begin - // output register empty - - m_axis_tdata_reg <= s_axis_tvalid_reg ? s_axis_tdata_reg : s_axis_tdata; - m_axis_tkeep_reg <= s_axis_tvalid_reg ? s_axis_tkeep_reg : s_axis_tkeep; - m_axis_tlast_reg <= 1'b0; - m_axis_tid_reg <= s_axis_tvalid_reg ? s_axis_tid_reg : s_axis_tid; - m_axis_tdest_reg <= s_axis_tvalid_reg ? s_axis_tdest_reg : s_axis_tdest; - m_axis_tuser_reg <= s_axis_tvalid_reg ? s_axis_tuser_reg : s_axis_tuser; - - if (s_axis_tvalid_reg) begin - // buffer has data; shift out from buffer - s_axis_tdata_reg <= s_axis_tdata_reg >> SEG_DATA_WIDTH; - s_axis_tkeep_reg <= s_axis_tkeep_reg >> SEG_KEEP_WIDTH; - - m_axis_tvalid_reg <= 1'b1; - - if ((s_axis_tkeep_reg >> SEG_KEEP_WIDTH) == 0) begin - s_axis_tvalid_reg <= 1'b0; - m_axis_tlast_reg <= s_axis_tlast_reg; - end - end else if (s_axis_tvalid && s_axis_tready) begin - // buffer is empty; store from input - s_axis_tdata_reg <= s_axis_tdata >> SEG_DATA_WIDTH; - s_axis_tkeep_reg <= s_axis_tkeep >> SEG_KEEP_WIDTH; - s_axis_tlast_reg <= s_axis_tlast; - s_axis_tid_reg <= s_axis_tid; - s_axis_tdest_reg <= s_axis_tdest; - s_axis_tuser_reg <= s_axis_tuser; - - m_axis_tvalid_reg <= 1'b1; - - if ((s_axis_tkeep >> SEG_KEEP_WIDTH) == 0) begin - s_axis_tvalid_reg <= 1'b0; - m_axis_tlast_reg <= s_axis_tlast; - end else begin - s_axis_tvalid_reg <= 1'b1; - end - end - end else if (s_axis_tvalid && s_axis_tready) begin - // store input data - s_axis_tdata_reg <= s_axis_tdata; - s_axis_tkeep_reg <= s_axis_tkeep; - s_axis_tvalid_reg <= 1'b1; - s_axis_tlast_reg <= s_axis_tlast; - s_axis_tid_reg <= s_axis_tid; - s_axis_tdest_reg <= s_axis_tdest; - s_axis_tuser_reg <= s_axis_tuser; - end - - if (rst) begin - s_axis_tvalid_reg <= 1'b0; - m_axis_tvalid_reg <= 1'b0; - end - end - -end - -endgenerate - -endmodule - -`resetall diff --git a/src/rvvi/axis_async_fifo.sv b/src/rvvi/axis_async_fifo.sv deleted file mode 100644 index 1d8b6244f..000000000 --- a/src/rvvi/axis_async_fifo.sv +++ /dev/null @@ -1,909 +0,0 @@ -/* - -Copyright (c) 2014-2023 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * AXI4-Stream asynchronous FIFO - */ -module axis_async_fifo # -( - // FIFO depth in words - // KEEP_WIDTH words per cycle if KEEP_ENABLE set - // Rounded up to nearest power of 2 cycles - parameter DEPTH = 4096, - // Width of AXI stream interfaces in bits - parameter DATA_WIDTH = 8, - // Propagate tkeep signal - // If disabled, tkeep assumed to be 1'b1 - parameter KEEP_ENABLE = (DATA_WIDTH>8), - // tkeep signal width (words per cycle) - parameter KEEP_WIDTH = ((DATA_WIDTH+7)/8), - // Propagate tlast signal - parameter LAST_ENABLE = 1, - // Propagate tid signal - parameter ID_ENABLE = 0, - // tid signal width - parameter ID_WIDTH = 8, - // Propagate tdest signal - parameter DEST_ENABLE = 0, - // tdest signal width - parameter DEST_WIDTH = 8, - // Propagate tuser signal - parameter USER_ENABLE = 1, - // tuser signal width - parameter USER_WIDTH = 1, - // number of RAM pipeline registers - parameter RAM_PIPELINE = 1, - // use output FIFO - // When set, the RAM read enable and pipeline clock enables are removed - parameter OUTPUT_FIFO_ENABLE = 0, - // Frame FIFO mode - operate on frames instead of cycles - // When set, m_axis_tvalid will not be deasserted within a frame - // Requires LAST_ENABLE set - parameter FRAME_FIFO = 0, - // tuser value for bad frame marker - parameter USER_BAD_FRAME_VALUE = 1'b1, - // tuser mask for bad frame marker - parameter USER_BAD_FRAME_MASK = 1'b1, - // Drop frames larger than FIFO - // Requires FRAME_FIFO set - parameter DROP_OVERSIZE_FRAME = FRAME_FIFO, - // Drop frames marked bad - // Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set - parameter DROP_BAD_FRAME = 0, - // Drop incoming frames when full - // When set, s_axis_tready is always asserted - // Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set - parameter DROP_WHEN_FULL = 0, - // Mark incoming frames as bad frames when full - // When set, s_axis_tready is always asserted - // Requires FRAME_FIFO to be clear - parameter MARK_WHEN_FULL = 0, - // Enable pause request input - parameter PAUSE_ENABLE = 0, - // Pause between frames - parameter FRAME_PAUSE = FRAME_FIFO -) -( - /* - * AXI input - */ - input wire s_clk, - input wire s_rst, - input wire [DATA_WIDTH-1:0] s_axis_tdata, - input wire [KEEP_WIDTH-1:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire [ID_WIDTH-1:0] s_axis_tid, - input wire [DEST_WIDTH-1:0] s_axis_tdest, - input wire [USER_WIDTH-1:0] s_axis_tuser, - - /* - * AXI output - */ - input wire m_clk, - input wire m_rst, - output wire [DATA_WIDTH-1:0] m_axis_tdata, - output wire [KEEP_WIDTH-1:0] m_axis_tkeep, - output wire m_axis_tvalid, - input wire m_axis_tready, - output wire m_axis_tlast, - output wire [ID_WIDTH-1:0] m_axis_tid, - output wire [DEST_WIDTH-1:0] m_axis_tdest, - output wire [USER_WIDTH-1:0] m_axis_tuser, - - /* - * Pause - */ - input wire s_pause_req, - output wire s_pause_ack, - input wire m_pause_req, - output wire m_pause_ack, - - /* - * Status - */ - output wire [$clog2(DEPTH):0] s_status_depth, - output wire [$clog2(DEPTH):0] s_status_depth_commit, - output wire s_status_overflow, - output wire s_status_bad_frame, - output wire s_status_good_frame, - output wire [$clog2(DEPTH):0] m_status_depth, - output wire [$clog2(DEPTH):0] m_status_depth_commit, - output wire m_status_overflow, - output wire m_status_bad_frame, - output wire m_status_good_frame -); - -parameter ADDR_WIDTH = (KEEP_ENABLE && KEEP_WIDTH > 1) ? $clog2(DEPTH/KEEP_WIDTH) : $clog2(DEPTH); - -parameter OUTPUT_FIFO_ADDR_WIDTH = RAM_PIPELINE < 2 ? 3 : $clog2(RAM_PIPELINE*2+7); - -// check configuration -initial begin - if (FRAME_FIFO && !LAST_ENABLE) begin - $error("Error: FRAME_FIFO set requires LAST_ENABLE set (instance %m)"); - $finish; - end - - if (DROP_OVERSIZE_FRAME && !FRAME_FIFO) begin - $error("Error: DROP_OVERSIZE_FRAME set requires FRAME_FIFO set (instance %m)"); - $finish; - end - - if (DROP_BAD_FRAME && !(FRAME_FIFO && DROP_OVERSIZE_FRAME)) begin - $error("Error: DROP_BAD_FRAME set requires FRAME_FIFO and DROP_OVERSIZE_FRAME set (instance %m)"); - $finish; - end - - if (DROP_WHEN_FULL && !(FRAME_FIFO && DROP_OVERSIZE_FRAME)) begin - $error("Error: DROP_WHEN_FULL set requires FRAME_FIFO and DROP_OVERSIZE_FRAME set (instance %m)"); - $finish; - end - - if ((DROP_BAD_FRAME || MARK_WHEN_FULL) && (USER_BAD_FRAME_MASK & {USER_WIDTH{1'b1}}) == 0) begin - $error("Error: Invalid USER_BAD_FRAME_MASK value (instance %m)"); - $finish; - end - - if (MARK_WHEN_FULL && FRAME_FIFO) begin - $error("Error: MARK_WHEN_FULL is not compatible with FRAME_FIFO (instance %m)"); - $finish; - end - - if (MARK_WHEN_FULL && !LAST_ENABLE) begin - $error("Error: MARK_WHEN_FULL set requires LAST_ENABLE set (instance %m)"); - $finish; - end -end - -localparam KEEP_OFFSET = DATA_WIDTH; -localparam LAST_OFFSET = KEEP_OFFSET + (KEEP_ENABLE ? KEEP_WIDTH : 0); -localparam ID_OFFSET = LAST_OFFSET + (LAST_ENABLE ? 1 : 0); -localparam DEST_OFFSET = ID_OFFSET + (ID_ENABLE ? ID_WIDTH : 0); -localparam USER_OFFSET = DEST_OFFSET + (DEST_ENABLE ? DEST_WIDTH : 0); -localparam WIDTH = USER_OFFSET + (USER_ENABLE ? USER_WIDTH : 0); - -function [ADDR_WIDTH:0] bin2gray(input [ADDR_WIDTH:0] b); - bin2gray = b ^ (b >> 1); -endfunction - -function [ADDR_WIDTH:0] gray2bin(input [ADDR_WIDTH:0] g); - integer i; - for (i = 0; i <= ADDR_WIDTH; i = i + 1) begin - gray2bin[i] = ^(g >> i); - end -endfunction - -reg [ADDR_WIDTH:0] wr_ptr_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_commit_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_sync_commit_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_gray_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] wr_ptr_conv_reg = {ADDR_WIDTH+1{1'b0}}; -reg [ADDR_WIDTH:0] rd_ptr_conv_reg = {ADDR_WIDTH+1{1'b0}}; - -reg [ADDR_WIDTH:0] wr_ptr_temp; -reg [ADDR_WIDTH:0] rd_ptr_temp; - -(* SHREG_EXTRACT = "NO" *) -reg [ADDR_WIDTH:0] wr_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; -(* SHREG_EXTRACT = "NO" *) -reg [ADDR_WIDTH:0] wr_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; -(* SHREG_EXTRACT = "NO" *) -reg [ADDR_WIDTH:0] wr_ptr_commit_sync_reg = {ADDR_WIDTH+1{1'b0}}; -(* SHREG_EXTRACT = "NO" *) -reg [ADDR_WIDTH:0] rd_ptr_gray_sync1_reg = {ADDR_WIDTH+1{1'b0}}; -(* SHREG_EXTRACT = "NO" *) -reg [ADDR_WIDTH:0] rd_ptr_gray_sync2_reg = {ADDR_WIDTH+1{1'b0}}; - -reg wr_ptr_update_valid_reg = 1'b0; -reg wr_ptr_update_reg = 1'b0; -(* SHREG_EXTRACT = "NO" *) -reg wr_ptr_update_sync1_reg = 1'b0; -(* SHREG_EXTRACT = "NO" *) -reg wr_ptr_update_sync2_reg = 1'b0; -(* SHREG_EXTRACT = "NO" *) -reg wr_ptr_update_sync3_reg = 1'b0; -(* SHREG_EXTRACT = "NO" *) -reg wr_ptr_update_ack_sync1_reg = 1'b0; -(* SHREG_EXTRACT = "NO" *) -reg wr_ptr_update_ack_sync2_reg = 1'b0; - -(* SHREG_EXTRACT = "NO" *) -reg s_rst_sync1_reg = 1'b1; -(* SHREG_EXTRACT = "NO" *) -reg s_rst_sync2_reg = 1'b1; -(* SHREG_EXTRACT = "NO" *) -reg s_rst_sync3_reg = 1'b1; -(* SHREG_EXTRACT = "NO" *) -reg m_rst_sync1_reg = 1'b1; -(* SHREG_EXTRACT = "NO" *) -reg m_rst_sync2_reg = 1'b1; -(* SHREG_EXTRACT = "NO" *) -reg m_rst_sync3_reg = 1'b1; - -(* ramstyle = "no_rw_check" *) -reg [WIDTH-1:0] mem[(2**ADDR_WIDTH)-1:0]; -reg mem_read_data_valid_reg = 1'b0; - -(* shreg_extract = "no" *) -reg [WIDTH-1:0] m_axis_pipe_reg[RAM_PIPELINE+1-1:0]; -reg [RAM_PIPELINE+1-1:0] m_axis_tvalid_pipe_reg = 0; - -// full when first TWO MSBs do NOT match, but rest matches -// (gray code equivalent of first MSB different but rest same) -wire full = wr_ptr_gray_reg == (rd_ptr_gray_sync2_reg ^ {2'b11, {ADDR_WIDTH-1{1'b0}}}); -// empty when pointers match exactly -wire empty = FRAME_FIFO ? (rd_ptr_reg == wr_ptr_commit_sync_reg) : (rd_ptr_gray_reg == wr_ptr_gray_sync2_reg); -// overflow within packet -wire full_wr = wr_ptr_reg == (wr_ptr_commit_reg ^ {1'b1, {ADDR_WIDTH{1'b0}}}); - -// control signals -reg write; -reg read; -reg store_output; - -reg s_frame_reg = 1'b0; -reg m_frame_reg = 1'b0; - -reg drop_frame_reg = 1'b0; -reg mark_frame_reg = 1'b0; -reg send_frame_reg = 1'b0; -reg overflow_reg = 1'b0; -reg bad_frame_reg = 1'b0; -reg good_frame_reg = 1'b0; - -reg m_drop_frame_reg = 1'b0; -reg m_terminate_frame_reg = 1'b0; - -reg [ADDR_WIDTH:0] s_depth_reg = 0; -reg [ADDR_WIDTH:0] s_depth_commit_reg = 0; -reg [ADDR_WIDTH:0] m_depth_reg = 0; -reg [ADDR_WIDTH:0] m_depth_commit_reg = 0; - -reg overflow_sync1_reg = 1'b0; -reg overflow_sync2_reg = 1'b0; -reg overflow_sync3_reg = 1'b0; -reg overflow_sync4_reg = 1'b0; -reg bad_frame_sync1_reg = 1'b0; -reg bad_frame_sync2_reg = 1'b0; -reg bad_frame_sync3_reg = 1'b0; -reg bad_frame_sync4_reg = 1'b0; -reg good_frame_sync1_reg = 1'b0; -reg good_frame_sync2_reg = 1'b0; -reg good_frame_sync3_reg = 1'b0; -reg good_frame_sync4_reg = 1'b0; - -assign s_axis_tready = (FRAME_FIFO ? (!full || (full_wr && DROP_OVERSIZE_FRAME) || DROP_WHEN_FULL) : (!full || MARK_WHEN_FULL)) && !s_rst_sync3_reg; - -wire [WIDTH-1:0] s_axis; - -generate - assign s_axis[DATA_WIDTH-1:0] = s_axis_tdata; - if (KEEP_ENABLE) assign s_axis[KEEP_OFFSET +: KEEP_WIDTH] = s_axis_tkeep; - if (LAST_ENABLE) assign s_axis[LAST_OFFSET] = s_axis_tlast | mark_frame_reg; - if (ID_ENABLE) assign s_axis[ID_OFFSET +: ID_WIDTH] = s_axis_tid; - if (DEST_ENABLE) assign s_axis[DEST_OFFSET +: DEST_WIDTH] = s_axis_tdest; - if (USER_ENABLE) assign s_axis[USER_OFFSET +: USER_WIDTH] = mark_frame_reg ? USER_BAD_FRAME_VALUE : s_axis_tuser; -endgenerate - -wire [WIDTH-1:0] m_axis = m_axis_pipe_reg[RAM_PIPELINE+1-1]; - -wire m_axis_tready_pipe; -wire m_axis_tvalid_pipe = m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1]; - -wire [DATA_WIDTH-1:0] m_axis_tdata_pipe = m_axis[DATA_WIDTH-1:0]; -wire [KEEP_WIDTH-1:0] m_axis_tkeep_pipe = KEEP_ENABLE ? m_axis[KEEP_OFFSET +: KEEP_WIDTH] : {KEEP_WIDTH{1'b1}}; -wire m_axis_tlast_pipe = LAST_ENABLE ? m_axis[LAST_OFFSET] | m_terminate_frame_reg : 1'b1; -wire [ID_WIDTH-1:0] m_axis_tid_pipe = ID_ENABLE ? m_axis[ID_OFFSET +: ID_WIDTH] : {ID_WIDTH{1'b0}}; -wire [DEST_WIDTH-1:0] m_axis_tdest_pipe = DEST_ENABLE ? m_axis[DEST_OFFSET +: DEST_WIDTH] : {DEST_WIDTH{1'b0}}; -wire [USER_WIDTH-1:0] m_axis_tuser_pipe = USER_ENABLE ? (m_terminate_frame_reg ? USER_BAD_FRAME_VALUE : m_axis[USER_OFFSET +: USER_WIDTH]) : {USER_WIDTH{1'b0}}; - -wire m_axis_tready_out; -wire m_axis_tvalid_out; - -wire [DATA_WIDTH-1:0] m_axis_tdata_out; -wire [KEEP_WIDTH-1:0] m_axis_tkeep_out; -wire m_axis_tlast_out; -wire [ID_WIDTH-1:0] m_axis_tid_out; -wire [DEST_WIDTH-1:0] m_axis_tdest_out; -wire [USER_WIDTH-1:0] m_axis_tuser_out; - -wire pipe_ready; - -assign s_status_depth = (KEEP_ENABLE && KEEP_WIDTH > 1) ? {s_depth_reg, {$clog2(KEEP_WIDTH){1'b0}}} : s_depth_reg; -assign s_status_depth_commit = (KEEP_ENABLE && KEEP_WIDTH > 1) ? {s_depth_commit_reg, {$clog2(KEEP_WIDTH){1'b0}}} : s_depth_commit_reg; -assign s_status_overflow = overflow_reg; -assign s_status_bad_frame = bad_frame_reg; -assign s_status_good_frame = good_frame_reg; - -assign m_status_depth = (KEEP_ENABLE && KEEP_WIDTH > 1) ? {m_depth_reg, {$clog2(KEEP_WIDTH){1'b0}}} : m_depth_reg; -assign m_status_depth_commit = (KEEP_ENABLE && KEEP_WIDTH > 1) ? {m_depth_commit_reg, {$clog2(KEEP_WIDTH){1'b0}}} : m_depth_commit_reg; -assign m_status_overflow = overflow_sync3_reg ^ overflow_sync4_reg; -assign m_status_bad_frame = bad_frame_sync3_reg ^ bad_frame_sync4_reg; -assign m_status_good_frame = good_frame_sync3_reg ^ good_frame_sync4_reg; - -// reset synchronization -always @(posedge m_clk or posedge m_rst) begin - if (m_rst) begin - s_rst_sync1_reg <= 1'b1; - end else begin - s_rst_sync1_reg <= 1'b0; - end -end - -always @(posedge s_clk) begin - s_rst_sync2_reg <= s_rst_sync1_reg; - s_rst_sync3_reg <= s_rst_sync2_reg; -end - -always @(posedge s_clk or posedge s_rst) begin - if (s_rst) begin - m_rst_sync1_reg <= 1'b1; - end else begin - m_rst_sync1_reg <= 1'b0; - end -end - -always @(posedge m_clk) begin - m_rst_sync2_reg <= m_rst_sync1_reg; - m_rst_sync3_reg <= m_rst_sync2_reg; -end - -// Write logic -always @(posedge s_clk) begin - overflow_reg <= 1'b0; - bad_frame_reg <= 1'b0; - good_frame_reg <= 1'b0; - - if (FRAME_FIFO && wr_ptr_update_valid_reg) begin - // have updated pointer to sync - if (wr_ptr_update_reg == wr_ptr_update_ack_sync2_reg) begin - // no sync in progress; sync update - wr_ptr_update_valid_reg <= 1'b0; - wr_ptr_sync_commit_reg <= wr_ptr_commit_reg; - wr_ptr_update_reg <= !wr_ptr_update_ack_sync2_reg; - end - end - - if (s_axis_tready && s_axis_tvalid && LAST_ENABLE) begin - // track input frame status - s_frame_reg <= !s_axis_tlast; - end - - if (s_rst_sync3_reg && LAST_ENABLE) begin - // if sink side is reset during transfer, drop partial frame - if (s_frame_reg && !(s_axis_tready && s_axis_tvalid && s_axis_tlast)) begin - drop_frame_reg <= 1'b1; - end - if (s_axis_tready && s_axis_tvalid && !s_axis_tlast) begin - drop_frame_reg <= 1'b1; - end - end - - if (FRAME_FIFO) begin - // frame FIFO mode - if (s_axis_tready && s_axis_tvalid) begin - // transfer in - if ((full && DROP_WHEN_FULL) || (full_wr && DROP_OVERSIZE_FRAME) || drop_frame_reg) begin - // full, packet overflow, or currently dropping frame - // drop frame - drop_frame_reg <= 1'b1; - if (s_axis_tlast) begin - // end of frame, reset write pointer - wr_ptr_temp = wr_ptr_commit_reg; - wr_ptr_reg <= wr_ptr_temp; - wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); - drop_frame_reg <= 1'b0; - overflow_reg <= 1'b1; - end - end else begin - mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis; - wr_ptr_temp = wr_ptr_reg + 1; - wr_ptr_reg <= wr_ptr_temp; - wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); - if (s_axis_tlast || (!DROP_OVERSIZE_FRAME && (full_wr || send_frame_reg))) begin - // end of frame or send frame - send_frame_reg <= !s_axis_tlast; - if (s_axis_tlast && DROP_BAD_FRAME && USER_BAD_FRAME_MASK & ~(s_axis_tuser ^ USER_BAD_FRAME_VALUE)) begin - // bad packet, reset write pointer - wr_ptr_temp = wr_ptr_commit_reg; - wr_ptr_reg <= wr_ptr_temp; - wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); - bad_frame_reg <= 1'b1; - end else begin - // good packet or packet overflow, update write pointer - wr_ptr_temp = wr_ptr_reg + 1; - wr_ptr_reg <= wr_ptr_temp; - wr_ptr_commit_reg <= wr_ptr_temp; - wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); - - if (wr_ptr_update_reg == wr_ptr_update_ack_sync2_reg) begin - // no sync in progress; sync update - wr_ptr_update_valid_reg <= 1'b0; - wr_ptr_sync_commit_reg <= wr_ptr_temp; - wr_ptr_update_reg <= !wr_ptr_update_ack_sync2_reg; - end else begin - // sync in progress; flag it for later - wr_ptr_update_valid_reg <= 1'b1; - end - - good_frame_reg <= s_axis_tlast; - end - end - end - end else if (s_axis_tvalid && full_wr && FRAME_FIFO && !DROP_OVERSIZE_FRAME) begin - // data valid with packet overflow - // update write pointer - send_frame_reg <= 1'b1; - wr_ptr_temp = wr_ptr_reg; - wr_ptr_reg <= wr_ptr_temp; - wr_ptr_commit_reg <= wr_ptr_temp; - wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); - - if (wr_ptr_update_reg == wr_ptr_update_ack_sync2_reg) begin - // no sync in progress; sync update - wr_ptr_update_valid_reg <= 1'b0; - wr_ptr_sync_commit_reg <= wr_ptr_temp; - wr_ptr_update_reg <= !wr_ptr_update_ack_sync2_reg; - end else begin - // sync in progress; flag it for later - wr_ptr_update_valid_reg <= 1'b1; - end - end - end else begin - // normal FIFO mode - if (s_axis_tready && s_axis_tvalid) begin - if (drop_frame_reg && LAST_ENABLE) begin - // currently dropping frame - if (s_axis_tlast) begin - // end of frame - if (!full && mark_frame_reg && MARK_WHEN_FULL) begin - // terminate marked frame - mark_frame_reg <= 1'b0; - mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis; - wr_ptr_temp = wr_ptr_reg + 1; - wr_ptr_reg <= wr_ptr_temp; - wr_ptr_commit_reg <= wr_ptr_temp; - wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); - end - // end of frame, clear drop flag - drop_frame_reg <= 1'b0; - overflow_reg <= 1'b1; - end - end else if ((full || mark_frame_reg) && MARK_WHEN_FULL) begin - // full or marking frame - // drop frame; mark if this isn't the first cycle - drop_frame_reg <= 1'b1; - mark_frame_reg <= mark_frame_reg || s_frame_reg; - if (s_axis_tlast) begin - drop_frame_reg <= 1'b0; - overflow_reg <= 1'b1; - end - end else begin - // transfer in - mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis; - wr_ptr_temp = wr_ptr_reg + 1; - wr_ptr_reg <= wr_ptr_temp; - wr_ptr_commit_reg <= wr_ptr_temp; - wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); - end - end else if ((!full && !drop_frame_reg && mark_frame_reg) && MARK_WHEN_FULL) begin - // terminate marked frame - mark_frame_reg <= 1'b0; - mem[wr_ptr_reg[ADDR_WIDTH-1:0]] <= s_axis; - wr_ptr_temp = wr_ptr_reg + 1; - wr_ptr_reg <= wr_ptr_temp; - wr_ptr_commit_reg <= wr_ptr_temp; - wr_ptr_gray_reg <= bin2gray(wr_ptr_temp); - end - end - - if (s_rst_sync3_reg) begin - wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_commit_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_sync_commit_reg <= {ADDR_WIDTH+1{1'b0}}; - - wr_ptr_update_valid_reg <= 1'b0; - wr_ptr_update_reg <= 1'b0; - end - - if (s_rst) begin - wr_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_commit_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_sync_commit_reg <= {ADDR_WIDTH+1{1'b0}}; - - wr_ptr_update_valid_reg <= 1'b0; - wr_ptr_update_reg <= 1'b0; - - s_frame_reg <= 1'b0; - - drop_frame_reg <= 1'b0; - mark_frame_reg <= 1'b0; - send_frame_reg <= 1'b0; - overflow_reg <= 1'b0; - bad_frame_reg <= 1'b0; - good_frame_reg <= 1'b0; - end -end - -// Write-side status -always @(posedge s_clk) begin - rd_ptr_conv_reg <= gray2bin(rd_ptr_gray_sync2_reg); - s_depth_reg <= wr_ptr_reg - rd_ptr_conv_reg; - s_depth_commit_reg <= wr_ptr_commit_reg - rd_ptr_conv_reg; -end - -// pointer synchronization -always @(posedge s_clk) begin - rd_ptr_gray_sync1_reg <= rd_ptr_gray_reg; - rd_ptr_gray_sync2_reg <= rd_ptr_gray_sync1_reg; - wr_ptr_update_ack_sync1_reg <= wr_ptr_update_sync3_reg; - wr_ptr_update_ack_sync2_reg <= wr_ptr_update_ack_sync1_reg; - - if (s_rst) begin - rd_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; - rd_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_update_ack_sync1_reg <= 1'b0; - wr_ptr_update_ack_sync2_reg <= 1'b0; - end -end - -always @(posedge m_clk) begin - wr_ptr_gray_sync1_reg <= wr_ptr_gray_reg; - wr_ptr_gray_sync2_reg <= wr_ptr_gray_sync1_reg; - if (FRAME_FIFO && wr_ptr_update_sync2_reg ^ wr_ptr_update_sync3_reg) begin - wr_ptr_commit_sync_reg <= wr_ptr_sync_commit_reg; - end - wr_ptr_update_sync1_reg <= wr_ptr_update_reg; - wr_ptr_update_sync2_reg <= wr_ptr_update_sync1_reg; - wr_ptr_update_sync3_reg <= wr_ptr_update_sync2_reg; - - if (FRAME_FIFO && m_rst_sync3_reg) begin - wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; - end - - if (m_rst) begin - wr_ptr_gray_sync1_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_gray_sync2_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_commit_sync_reg <= {ADDR_WIDTH+1{1'b0}}; - wr_ptr_update_sync1_reg <= 1'b0; - wr_ptr_update_sync2_reg <= 1'b0; - wr_ptr_update_sync3_reg <= 1'b0; - end -end - -// status synchronization -always @(posedge s_clk) begin - overflow_sync1_reg <= overflow_sync1_reg ^ overflow_reg; - bad_frame_sync1_reg <= bad_frame_sync1_reg ^ bad_frame_reg; - good_frame_sync1_reg <= good_frame_sync1_reg ^ good_frame_reg; - - if (s_rst) begin - overflow_sync1_reg <= 1'b0; - bad_frame_sync1_reg <= 1'b0; - good_frame_sync1_reg <= 1'b0; - end -end - -always @(posedge m_clk) begin - overflow_sync2_reg <= overflow_sync1_reg; - overflow_sync3_reg <= overflow_sync2_reg; - overflow_sync4_reg <= overflow_sync3_reg; - bad_frame_sync2_reg <= bad_frame_sync1_reg; - bad_frame_sync3_reg <= bad_frame_sync2_reg; - bad_frame_sync4_reg <= bad_frame_sync3_reg; - good_frame_sync2_reg <= good_frame_sync1_reg; - good_frame_sync3_reg <= good_frame_sync2_reg; - good_frame_sync4_reg <= good_frame_sync3_reg; - - if (m_rst) begin - overflow_sync2_reg <= 1'b0; - overflow_sync3_reg <= 1'b0; - overflow_sync4_reg <= 1'b0; - bad_frame_sync2_reg <= 1'b0; - bad_frame_sync3_reg <= 1'b0; - bad_frame_sync4_reg <= 1'b0; - good_frame_sync2_reg <= 1'b0; - good_frame_sync3_reg <= 1'b0; - good_frame_sync4_reg <= 1'b0; - end -end - -// Read logic -integer j; - -always @(posedge m_clk) begin - if (m_axis_tready_pipe) begin - // output ready; invalidate stage - m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1] <= 1'b0; - m_terminate_frame_reg <= 1'b0; - end - - for (j = RAM_PIPELINE+1-1; j > 0; j = j - 1) begin - if (m_axis_tready_pipe || ((~m_axis_tvalid_pipe_reg) >> j)) begin - // output ready or bubble in pipeline; transfer down pipeline - m_axis_tvalid_pipe_reg[j] <= m_axis_tvalid_pipe_reg[j-1]; - m_axis_pipe_reg[j] <= m_axis_pipe_reg[j-1]; - m_axis_tvalid_pipe_reg[j-1] <= 1'b0; - end - end - - if (m_axis_tready_pipe || ~m_axis_tvalid_pipe_reg) begin - // output ready or bubble in pipeline; read new data from FIFO - m_axis_tvalid_pipe_reg[0] <= 1'b0; - m_axis_pipe_reg[0] <= mem[rd_ptr_reg[ADDR_WIDTH-1:0]]; - if (!empty && !m_rst_sync3_reg && !m_drop_frame_reg && pipe_ready) begin - // not empty, increment pointer - m_axis_tvalid_pipe_reg[0] <= 1'b1; - rd_ptr_temp = rd_ptr_reg + 1; - rd_ptr_reg <= rd_ptr_temp; - rd_ptr_gray_reg <= rd_ptr_temp ^ (rd_ptr_temp >> 1); - end - end - - if (m_axis_tvalid_pipe && LAST_ENABLE) begin - // track output frame status - if (m_axis_tlast_pipe && m_axis_tready_pipe) begin - m_frame_reg <= 1'b0; - end else begin - m_frame_reg <= 1'b1; - end - end - - if (m_drop_frame_reg && (OUTPUT_FIFO_ENABLE ? pipe_ready : m_axis_tready_pipe || !m_axis_tvalid_pipe) && LAST_ENABLE) begin - // terminate frame - // (only for frame transfers interrupted by source reset) - m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-1] <= 1'b1; - m_terminate_frame_reg <= 1'b1; - m_drop_frame_reg <= 1'b0; - end - - if (m_rst_sync3_reg && LAST_ENABLE) begin - // if source side is reset during transfer, drop partial frame - - // empty output pipeline, except for last stage - if (RAM_PIPELINE > 0) begin - m_axis_tvalid_pipe_reg[RAM_PIPELINE+1-2:0] <= 0; - end - - if (m_frame_reg && (!m_axis_tvalid_pipe || (m_axis_tvalid_pipe && !m_axis_tlast_pipe)) && - !(m_drop_frame_reg || m_terminate_frame_reg)) begin - // terminate frame - m_drop_frame_reg <= 1'b1; - end - end - - if (m_rst_sync3_reg) begin - rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - end - - if (m_rst) begin - rd_ptr_reg <= {ADDR_WIDTH+1{1'b0}}; - rd_ptr_gray_reg <= {ADDR_WIDTH+1{1'b0}}; - m_axis_tvalid_pipe_reg <= 0; - m_frame_reg <= 1'b0; - m_drop_frame_reg <= 1'b0; - m_terminate_frame_reg <= 1'b0; - end -end - -// Read-side status -always @(posedge m_clk) begin - wr_ptr_conv_reg <= gray2bin(wr_ptr_gray_sync2_reg); - m_depth_reg <= wr_ptr_conv_reg - rd_ptr_reg; - m_depth_commit_reg <= FRAME_FIFO ? wr_ptr_commit_sync_reg - rd_ptr_reg : wr_ptr_conv_reg - rd_ptr_reg; -end - -generate - -if (!OUTPUT_FIFO_ENABLE) begin - - assign pipe_ready = 1'b1; - - assign m_axis_tready_pipe = m_axis_tready_out; - assign m_axis_tvalid_out = m_axis_tvalid_pipe; - - assign m_axis_tdata_out = m_axis_tdata_pipe; - assign m_axis_tkeep_out = m_axis_tkeep_pipe; - assign m_axis_tlast_out = m_axis_tlast_pipe; - assign m_axis_tid_out = m_axis_tid_pipe; - assign m_axis_tdest_out = m_axis_tdest_pipe; - assign m_axis_tuser_out = m_axis_tuser_pipe; - -end else begin : output_fifo - - // output datapath logic - reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; - reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; - reg m_axis_tvalid_reg = 1'b0; - reg m_axis_tlast_reg = 1'b0; - reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; - reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; - reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; - - reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_fifo_wr_ptr_reg = 0; - reg [OUTPUT_FIFO_ADDR_WIDTH+1-1:0] out_fifo_rd_ptr_reg = 0; - reg out_fifo_half_full_reg = 1'b0; - - wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1, {OUTPUT_FIFO_ADDR_WIDTH{1'b0}}}); - wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg; - - (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) - reg [DATA_WIDTH-1:0] out_fifo_tdata[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) - reg [KEEP_WIDTH-1:0] out_fifo_tkeep[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) - reg out_fifo_tlast[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) - reg [ID_WIDTH-1:0] out_fifo_tid[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) - reg [DEST_WIDTH-1:0] out_fifo_tdest[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - (* ram_style = "distributed", ramstyle = "no_rw_check, mlab" *) - reg [USER_WIDTH-1:0] out_fifo_tuser[2**OUTPUT_FIFO_ADDR_WIDTH-1:0]; - - assign pipe_ready = !out_fifo_half_full_reg; - - assign m_axis_tready_pipe = 1'b1; - - assign m_axis_tdata_out = m_axis_tdata_reg; - assign m_axis_tkeep_out = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; - assign m_axis_tvalid_out = m_axis_tvalid_reg; - assign m_axis_tlast_out = LAST_ENABLE ? m_axis_tlast_reg : 1'b1; - assign m_axis_tid_out = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; - assign m_axis_tdest_out = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; - assign m_axis_tuser_out = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; - - always @(posedge m_clk) begin - m_axis_tvalid_reg <= m_axis_tvalid_reg && !m_axis_tready_out; - - out_fifo_half_full_reg <= $unsigned(out_fifo_wr_ptr_reg - out_fifo_rd_ptr_reg) >= 2**(OUTPUT_FIFO_ADDR_WIDTH-1); - - if (!out_fifo_full && m_axis_tvalid_pipe) begin - out_fifo_tdata[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tdata_pipe; - out_fifo_tkeep[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tkeep_pipe; - out_fifo_tlast[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tlast_pipe; - out_fifo_tid[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tid_pipe; - out_fifo_tdest[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tdest_pipe; - out_fifo_tuser[out_fifo_wr_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]] <= m_axis_tuser_pipe; - out_fifo_wr_ptr_reg <= out_fifo_wr_ptr_reg + 1; - end - - if (!out_fifo_empty && (!m_axis_tvalid_reg || m_axis_tready_out)) begin - m_axis_tdata_reg <= out_fifo_tdata[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; - m_axis_tkeep_reg <= out_fifo_tkeep[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; - m_axis_tvalid_reg <= 1'b1; - m_axis_tlast_reg <= out_fifo_tlast[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; - m_axis_tid_reg <= out_fifo_tid[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; - m_axis_tdest_reg <= out_fifo_tdest[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; - m_axis_tuser_reg <= out_fifo_tuser[out_fifo_rd_ptr_reg[OUTPUT_FIFO_ADDR_WIDTH-1:0]]; - out_fifo_rd_ptr_reg <= out_fifo_rd_ptr_reg + 1; - end - - if (m_rst) begin - out_fifo_wr_ptr_reg <= 0; - out_fifo_rd_ptr_reg <= 0; - m_axis_tvalid_reg <= 1'b0; - end - end - -end - -if (PAUSE_ENABLE) begin : pause - - // Pause logic - reg pause_reg = 1'b0; - reg pause_frame_reg = 1'b0; - - reg s_pause_req_sync1_reg; - reg s_pause_req_sync2_reg; - reg s_pause_req_sync3_reg; - reg s_pause_ack_sync1_reg; - reg s_pause_ack_sync2_reg; - reg s_pause_ack_sync3_reg; - - always @(posedge s_clk) begin - s_pause_req_sync1_reg <= s_pause_req; - s_pause_ack_sync2_reg <= s_pause_ack_sync1_reg; - s_pause_ack_sync3_reg <= s_pause_ack_sync2_reg; - end - - always @(posedge m_clk) begin - s_pause_req_sync2_reg <= s_pause_req_sync1_reg; - s_pause_req_sync3_reg <= s_pause_req_sync2_reg; - s_pause_ack_sync1_reg <= pause_reg; - end - - assign m_axis_tready_out = m_axis_tready && !pause_reg; - assign m_axis_tvalid = m_axis_tvalid_out && !pause_reg; - - assign m_axis_tdata = m_axis_tdata_out; - assign m_axis_tkeep = m_axis_tkeep_out; - assign m_axis_tlast = m_axis_tlast_out; - assign m_axis_tid = m_axis_tid_out; - assign m_axis_tdest = m_axis_tdest_out; - assign m_axis_tuser = m_axis_tuser_out; - - assign s_pause_ack = s_pause_ack_sync3_reg; - assign m_pause_ack = pause_reg; - - always @(posedge m_clk) begin - if (FRAME_PAUSE) begin - if (pause_reg) begin - // paused; update pause status - pause_reg <= m_pause_req || s_pause_req_sync3_reg; - end else if (m_axis_tvalid_out) begin - // frame transfer; set frame bit - pause_frame_reg <= 1'b1; - if (m_axis_tready && m_axis_tlast) begin - // end of frame; clear frame bit and update pause status - pause_frame_reg <= 1'b0; - pause_reg <= m_pause_req || s_pause_req_sync3_reg; - end - end else if (!pause_frame_reg) begin - // idle; update pause status - pause_reg <= m_pause_req || s_pause_req_sync3_reg; - end - end else begin - pause_reg <= m_pause_req || s_pause_req_sync3_reg; - end - - if (m_rst) begin - pause_frame_reg <= 1'b0; - pause_reg <= 1'b0; - end - end - -end else begin - - assign m_axis_tready_out = m_axis_tready; - assign m_axis_tvalid = m_axis_tvalid_out; - - assign m_axis_tdata = m_axis_tdata_out; - assign m_axis_tkeep = m_axis_tkeep_out; - assign m_axis_tlast = m_axis_tlast_out; - assign m_axis_tid = m_axis_tid_out; - assign m_axis_tdest = m_axis_tdest_out; - assign m_axis_tuser = m_axis_tuser_out; - - assign s_pause_ack = 1'b0; - assign m_pause_ack = 1'b0; - -end - -endgenerate - -endmodule - -`resetall diff --git a/src/rvvi/axis_async_fifo_adapter.sv b/src/rvvi/axis_async_fifo_adapter.sv deleted file mode 100644 index d1e71b9fc..000000000 --- a/src/rvvi/axis_async_fifo_adapter.sv +++ /dev/null @@ -1,377 +0,0 @@ -/* - -Copyright (c) 2019 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * AXI4-Stream asynchronous FIFO with width converter - */ -module axis_async_fifo_adapter # -( - // FIFO depth in words - // KEEP_WIDTH words per cycle if KEEP_ENABLE set - // Rounded up to nearest power of 2 cycles - parameter DEPTH = 4096, - // Width of input AXI stream interface in bits - parameter S_DATA_WIDTH = 8, - // Propagate tkeep signal on input interface - // If disabled, tkeep assumed to be 1'b1 - parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8), - // tkeep signal width (words per cycle) on input interface - parameter S_KEEP_WIDTH = ((S_DATA_WIDTH+7)/8), - // Width of output AXI stream interface in bits - parameter M_DATA_WIDTH = 8, - // Propagate tkeep signal on output interface - // If disabled, tkeep assumed to be 1'b1 - parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8), - // tkeep signal width (words per cycle) on output interface - parameter M_KEEP_WIDTH = ((M_DATA_WIDTH+7)/8), - // Propagate tid signal - parameter ID_ENABLE = 0, - // tid signal width - parameter ID_WIDTH = 8, - // Propagate tdest signal - parameter DEST_ENABLE = 0, - // tdest signal width - parameter DEST_WIDTH = 8, - // Propagate tuser signal - parameter USER_ENABLE = 1, - // tuser signal width - parameter USER_WIDTH = 1, - // number of RAM pipeline registers in FIFO - parameter RAM_PIPELINE = 1, - // use output FIFO - // When set, the RAM read enable and pipeline clock enables are removed - parameter OUTPUT_FIFO_ENABLE = 0, - // Frame FIFO mode - operate on frames instead of cycles - // When set, m_axis_tvalid will not be deasserted within a frame - // Requires LAST_ENABLE set - parameter FRAME_FIFO = 0, - // tuser value for bad frame marker - parameter USER_BAD_FRAME_VALUE = 1'b1, - // tuser mask for bad frame marker - parameter USER_BAD_FRAME_MASK = 1'b1, - // Drop frames larger than FIFO - // Requires FRAME_FIFO set - parameter DROP_OVERSIZE_FRAME = FRAME_FIFO, - // Drop frames marked bad - // Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set - parameter DROP_BAD_FRAME = 0, - // Drop incoming frames when full - // When set, s_axis_tready is always asserted - // Requires FRAME_FIFO and DROP_OVERSIZE_FRAME set - parameter DROP_WHEN_FULL = 0, - // Mark incoming frames as bad frames when full - // When set, s_axis_tready is always asserted - // Requires FRAME_FIFO to be clear - parameter MARK_WHEN_FULL = 0, - // Enable pause request input - parameter PAUSE_ENABLE = 0, - // Pause between frames - parameter FRAME_PAUSE = FRAME_FIFO -) -( - /* - * AXI input - */ - input wire s_clk, - input wire s_rst, - input wire [S_DATA_WIDTH-1:0] s_axis_tdata, - input wire [S_KEEP_WIDTH-1:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire [ID_WIDTH-1:0] s_axis_tid, - input wire [DEST_WIDTH-1:0] s_axis_tdest, - input wire [USER_WIDTH-1:0] s_axis_tuser, - - /* - * AXI output - */ - input wire m_clk, - input wire m_rst, - output wire [M_DATA_WIDTH-1:0] m_axis_tdata, - output wire [M_KEEP_WIDTH-1:0] m_axis_tkeep, - output wire m_axis_tvalid, - input wire m_axis_tready, - output wire m_axis_tlast, - output wire [ID_WIDTH-1:0] m_axis_tid, - output wire [DEST_WIDTH-1:0] m_axis_tdest, - output wire [USER_WIDTH-1:0] m_axis_tuser, - - /* - * Pause - */ - input wire s_pause_req, - output wire s_pause_ack, - input wire m_pause_req, - output wire m_pause_ack, - - /* - * Status - */ - output wire [$clog2(DEPTH):0] s_status_depth, - output wire [$clog2(DEPTH):0] s_status_depth_commit, - output wire s_status_overflow, - output wire s_status_bad_frame, - output wire s_status_good_frame, - output wire [$clog2(DEPTH):0] m_status_depth, - output wire [$clog2(DEPTH):0] m_status_depth_commit, - output wire m_status_overflow, - output wire m_status_bad_frame, - output wire m_status_good_frame -); - -// force keep width to 1 when disabled -localparam S_BYTE_LANES = S_KEEP_ENABLE ? S_KEEP_WIDTH : 1; -localparam M_BYTE_LANES = M_KEEP_ENABLE ? M_KEEP_WIDTH : 1; - -// bus byte sizes (must be identical) -localparam S_BYTE_SIZE = S_DATA_WIDTH / S_BYTE_LANES; -localparam M_BYTE_SIZE = M_DATA_WIDTH / M_BYTE_LANES; -// output bus is wider -localparam EXPAND_BUS = M_BYTE_LANES > S_BYTE_LANES; -// total data and keep widths -localparam DATA_WIDTH = EXPAND_BUS ? M_DATA_WIDTH : S_DATA_WIDTH; -localparam KEEP_WIDTH = EXPAND_BUS ? M_BYTE_LANES : S_BYTE_LANES; - -// bus width assertions -initial begin - if (S_BYTE_SIZE * S_BYTE_LANES != S_DATA_WIDTH) begin - $error("Error: input data width not evenly divisible (instance %m)"); - $finish; - end - - if (M_BYTE_SIZE * M_BYTE_LANES != M_DATA_WIDTH) begin - $error("Error: output data width not evenly divisible (instance %m)"); - $finish; - end - - if (S_BYTE_SIZE != M_BYTE_SIZE) begin - $error("Error: byte size mismatch (instance %m)"); - $finish; - end -end - -wire [DATA_WIDTH-1:0] pre_fifo_axis_tdata; -wire [KEEP_WIDTH-1:0] pre_fifo_axis_tkeep; -wire pre_fifo_axis_tvalid; -wire pre_fifo_axis_tready; -wire pre_fifo_axis_tlast; -wire [ID_WIDTH-1:0] pre_fifo_axis_tid; -wire [DEST_WIDTH-1:0] pre_fifo_axis_tdest; -wire [USER_WIDTH-1:0] pre_fifo_axis_tuser; - -wire [DATA_WIDTH-1:0] post_fifo_axis_tdata; -wire [KEEP_WIDTH-1:0] post_fifo_axis_tkeep; -wire post_fifo_axis_tvalid; -wire post_fifo_axis_tready; -wire post_fifo_axis_tlast; -wire [ID_WIDTH-1:0] post_fifo_axis_tid; -wire [DEST_WIDTH-1:0] post_fifo_axis_tdest; -wire [USER_WIDTH-1:0] post_fifo_axis_tuser; - -generate - -if (M_BYTE_LANES > S_BYTE_LANES) begin : upsize_pre - - // output wider, adapt width before FIFO - - axis_adapter #( - .S_DATA_WIDTH(S_DATA_WIDTH), - .S_KEEP_ENABLE(S_KEEP_ENABLE), - .S_KEEP_WIDTH(S_KEEP_WIDTH), - .M_DATA_WIDTH(M_DATA_WIDTH), - .M_KEEP_ENABLE(M_KEEP_ENABLE), - .M_KEEP_WIDTH(M_KEEP_WIDTH), - .ID_ENABLE(ID_ENABLE), - .ID_WIDTH(ID_WIDTH), - .DEST_ENABLE(DEST_ENABLE), - .DEST_WIDTH(DEST_WIDTH), - .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) - ) - adapter_inst ( - .clk(s_clk), - .rst(s_rst), - // AXI input - .s_axis_tdata(s_axis_tdata), - .s_axis_tkeep(s_axis_tkeep), - .s_axis_tvalid(s_axis_tvalid), - .s_axis_tready(s_axis_tready), - .s_axis_tlast(s_axis_tlast), - .s_axis_tid(s_axis_tid), - .s_axis_tdest(s_axis_tdest), - .s_axis_tuser(s_axis_tuser), - // AXI output - .m_axis_tdata(pre_fifo_axis_tdata), - .m_axis_tkeep(pre_fifo_axis_tkeep), - .m_axis_tvalid(pre_fifo_axis_tvalid), - .m_axis_tready(pre_fifo_axis_tready), - .m_axis_tlast(pre_fifo_axis_tlast), - .m_axis_tid(pre_fifo_axis_tid), - .m_axis_tdest(pre_fifo_axis_tdest), - .m_axis_tuser(pre_fifo_axis_tuser) - ); - -end else begin : bypass_pre - - assign pre_fifo_axis_tdata = s_axis_tdata; - assign pre_fifo_axis_tkeep = s_axis_tkeep; - assign pre_fifo_axis_tvalid = s_axis_tvalid; - assign s_axis_tready = pre_fifo_axis_tready; - assign pre_fifo_axis_tlast = s_axis_tlast; - assign pre_fifo_axis_tid = s_axis_tid; - assign pre_fifo_axis_tdest = s_axis_tdest; - assign pre_fifo_axis_tuser = s_axis_tuser; - -end - -axis_async_fifo #( - .DEPTH(DEPTH), - .DATA_WIDTH(DATA_WIDTH), - .KEEP_ENABLE(EXPAND_BUS ? M_KEEP_ENABLE : S_KEEP_ENABLE), - .KEEP_WIDTH(KEEP_WIDTH), - .LAST_ENABLE(1), - .ID_ENABLE(ID_ENABLE), - .ID_WIDTH(ID_WIDTH), - .DEST_ENABLE(DEST_ENABLE), - .DEST_WIDTH(DEST_WIDTH), - .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH), - .RAM_PIPELINE(RAM_PIPELINE), - .OUTPUT_FIFO_ENABLE(OUTPUT_FIFO_ENABLE), - .FRAME_FIFO(FRAME_FIFO), - .USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE), - .USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK), - .DROP_OVERSIZE_FRAME(DROP_OVERSIZE_FRAME), - .DROP_BAD_FRAME(DROP_BAD_FRAME), - .DROP_WHEN_FULL(DROP_WHEN_FULL), - .MARK_WHEN_FULL(MARK_WHEN_FULL), - .PAUSE_ENABLE(PAUSE_ENABLE), - .FRAME_PAUSE(FRAME_PAUSE) -) -fifo_inst ( - // AXI input - .s_clk(s_clk), - .s_rst(s_rst), - .s_axis_tdata(pre_fifo_axis_tdata), - .s_axis_tkeep(pre_fifo_axis_tkeep), - .s_axis_tvalid(pre_fifo_axis_tvalid), - .s_axis_tready(pre_fifo_axis_tready), - .s_axis_tlast(pre_fifo_axis_tlast), - .s_axis_tid(pre_fifo_axis_tid), - .s_axis_tdest(pre_fifo_axis_tdest), - .s_axis_tuser(pre_fifo_axis_tuser), - // AXI output - .m_clk(m_clk), - .m_rst(m_rst), - .m_axis_tdata(post_fifo_axis_tdata), - .m_axis_tkeep(post_fifo_axis_tkeep), - .m_axis_tvalid(post_fifo_axis_tvalid), - .m_axis_tready(post_fifo_axis_tready), - .m_axis_tlast(post_fifo_axis_tlast), - .m_axis_tid(post_fifo_axis_tid), - .m_axis_tdest(post_fifo_axis_tdest), - .m_axis_tuser(post_fifo_axis_tuser), - // Pause - .s_pause_req(s_pause_req), - .s_pause_ack(s_pause_ack), - .m_pause_req(m_pause_req), - .m_pause_ack(m_pause_ack), - // Status - .s_status_depth(s_status_depth), - .s_status_depth_commit(s_status_depth_commit), - .s_status_overflow(s_status_overflow), - .s_status_bad_frame(s_status_bad_frame), - .s_status_good_frame(s_status_good_frame), - .m_status_depth(m_status_depth), - .m_status_depth_commit(m_status_depth_commit), - .m_status_overflow(m_status_overflow), - .m_status_bad_frame(m_status_bad_frame), - .m_status_good_frame(m_status_good_frame) -); - -if (M_BYTE_LANES < S_BYTE_LANES) begin : downsize_post - - // input wider, adapt width after FIFO - - axis_adapter #( - .S_DATA_WIDTH(S_DATA_WIDTH), - .S_KEEP_ENABLE(S_KEEP_ENABLE), - .S_KEEP_WIDTH(S_KEEP_WIDTH), - .M_DATA_WIDTH(M_DATA_WIDTH), - .M_KEEP_ENABLE(M_KEEP_ENABLE), - .M_KEEP_WIDTH(M_KEEP_WIDTH), - .ID_ENABLE(ID_ENABLE), - .ID_WIDTH(ID_WIDTH), - .DEST_ENABLE(DEST_ENABLE), - .DEST_WIDTH(DEST_WIDTH), - .USER_ENABLE(USER_ENABLE), - .USER_WIDTH(USER_WIDTH) - ) - adapter_inst ( - .clk(m_clk), - .rst(m_rst), - // AXI input - .s_axis_tdata(post_fifo_axis_tdata), - .s_axis_tkeep(post_fifo_axis_tkeep), - .s_axis_tvalid(post_fifo_axis_tvalid), - .s_axis_tready(post_fifo_axis_tready), - .s_axis_tlast(post_fifo_axis_tlast), - .s_axis_tid(post_fifo_axis_tid), - .s_axis_tdest(post_fifo_axis_tdest), - .s_axis_tuser(post_fifo_axis_tuser), - // AXI output - .m_axis_tdata(m_axis_tdata), - .m_axis_tkeep(m_axis_tkeep), - .m_axis_tvalid(m_axis_tvalid), - .m_axis_tready(m_axis_tready), - .m_axis_tlast(m_axis_tlast), - .m_axis_tid(m_axis_tid), - .m_axis_tdest(m_axis_tdest), - .m_axis_tuser(m_axis_tuser) - ); - -end else begin : bypass_post - - assign m_axis_tdata = post_fifo_axis_tdata; - assign m_axis_tkeep = post_fifo_axis_tkeep; - assign m_axis_tvalid = post_fifo_axis_tvalid; - assign post_fifo_axis_tready = m_axis_tready; - assign m_axis_tlast = post_fifo_axis_tlast; - assign m_axis_tid = post_fifo_axis_tid; - assign m_axis_tdest = post_fifo_axis_tdest; - assign m_axis_tuser = post_fifo_axis_tuser; - -end - -endgenerate - -endmodule - -`resetall diff --git a/src/rvvi/axis_gmii_rx.sv b/src/rvvi/axis_gmii_rx.sv deleted file mode 100644 index 037fce77a..000000000 --- a/src/rvvi/axis_gmii_rx.sv +++ /dev/null @@ -1,357 +0,0 @@ -/* - -Copyright (c) 2015-2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * AXI4-Stream GMII frame receiver (GMII in, AXI out) - */ -module axis_gmii_rx # -( - parameter DATA_WIDTH = 8, - parameter PTP_TS_ENABLE = 0, - parameter PTP_TS_WIDTH = 96, - parameter USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1 -) -( - input wire clk, - input wire rst, - - /* - * GMII input - */ - input wire [DATA_WIDTH-1:0] gmii_rxd, - input wire gmii_rx_dv, - input wire gmii_rx_er, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] m_axis_tdata, - output wire m_axis_tvalid, - output wire m_axis_tlast, - output wire [USER_WIDTH-1:0] m_axis_tuser, - - /* - * PTP - */ - input wire [PTP_TS_WIDTH-1:0] ptp_ts, - - /* - * Control - */ - input wire clk_enable, - input wire mii_select, - - /* - * Configuration - */ - input wire cfg_rx_enable, - - /* - * Status - */ - output wire start_packet, - output wire error_bad_frame, - output wire error_bad_fcs -); - -// bus width assertions -initial begin - if (DATA_WIDTH != 8) begin - $error("Error: Interface width must be 8"); - $finish; - end -end - -localparam [7:0] - ETH_PRE = 8'h55, - ETH_SFD = 8'hD5; - -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_PAYLOAD = 3'd1, - STATE_WAIT_LAST = 3'd2; - -reg [2:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg reset_crc; -reg update_crc; - -reg mii_odd = 1'b0; -reg in_frame = 1'b0; - -reg [DATA_WIDTH-1:0] gmii_rxd_d0 = {DATA_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] gmii_rxd_d1 = {DATA_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] gmii_rxd_d2 = {DATA_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] gmii_rxd_d3 = {DATA_WIDTH{1'b0}}; -reg [DATA_WIDTH-1:0] gmii_rxd_d4 = {DATA_WIDTH{1'b0}}; - -reg gmii_rx_dv_d0 = 1'b0; -reg gmii_rx_dv_d1 = 1'b0; -reg gmii_rx_dv_d2 = 1'b0; -reg gmii_rx_dv_d3 = 1'b0; -reg gmii_rx_dv_d4 = 1'b0; - -reg gmii_rx_er_d0 = 1'b0; -reg gmii_rx_er_d1 = 1'b0; -reg gmii_rx_er_d2 = 1'b0; -reg gmii_rx_er_d3 = 1'b0; -reg gmii_rx_er_d4 = 1'b0; - -reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}, m_axis_tdata_next; -reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; -reg m_axis_tlast_reg = 1'b0, m_axis_tlast_next; -reg m_axis_tuser_reg = 1'b0, m_axis_tuser_next; - -reg start_packet_int_reg = 1'b0; -reg start_packet_reg = 1'b0; -reg error_bad_frame_reg = 1'b0, error_bad_frame_next; -reg error_bad_fcs_reg = 1'b0, error_bad_fcs_next; - -reg [PTP_TS_WIDTH-1:0] ptp_ts_reg = 0; - -reg [31:0] crc_state = 32'hFFFFFFFF; -wire [31:0] crc_next; - -assign m_axis_tdata = m_axis_tdata_reg; -assign m_axis_tvalid = m_axis_tvalid_reg; -assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tuser = PTP_TS_ENABLE ? {ptp_ts_reg, m_axis_tuser_reg} : m_axis_tuser_reg; - -assign start_packet = start_packet_reg; -assign error_bad_frame = error_bad_frame_reg; -assign error_bad_fcs = error_bad_fcs_reg; - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(8), - .STYLE("AUTO") -) -eth_crc_8 ( - .data_in(gmii_rxd_d4), - .state_in(crc_state), - .data_out(), - .state_out(crc_next) -); - -always @* begin - state_next = STATE_IDLE; - - reset_crc = 1'b0; - update_crc = 1'b0; - - m_axis_tdata_next = {DATA_WIDTH{1'b0}}; - m_axis_tvalid_next = 1'b0; - m_axis_tlast_next = 1'b0; - m_axis_tuser_next = 1'b0; - - error_bad_frame_next = 1'b0; - error_bad_fcs_next = 1'b0; - - if (!clk_enable) begin - // clock disabled - hold state - state_next = state_reg; - end else if (mii_select && !mii_odd) begin - // MII even cycle - hold state - state_next = state_reg; - end else begin - case (state_reg) - STATE_IDLE: begin - // idle state - wait for packet - reset_crc = 1'b1; - - if (gmii_rx_dv_d4 && !gmii_rx_er_d4 && gmii_rxd_d4 == ETH_SFD && cfg_rx_enable) begin - state_next = STATE_PAYLOAD; - end else begin - state_next = STATE_IDLE; - end - end - STATE_PAYLOAD: begin - // read payload - update_crc = 1'b1; - - m_axis_tdata_next = gmii_rxd_d4; - m_axis_tvalid_next = 1'b1; - - if (gmii_rx_dv_d4 && gmii_rx_er_d4) begin - // error - m_axis_tlast_next = 1'b1; - m_axis_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - state_next = STATE_WAIT_LAST; - end else if (!gmii_rx_dv) begin - // end of packet - m_axis_tlast_next = 1'b1; - if (gmii_rx_er_d0 || gmii_rx_er_d1 || gmii_rx_er_d2 || gmii_rx_er_d3) begin - // error received in FCS bytes - m_axis_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - end else if ({gmii_rxd_d0, gmii_rxd_d1, gmii_rxd_d2, gmii_rxd_d3} == ~crc_next) begin - // FCS good - m_axis_tuser_next = 1'b0; - end else begin - // FCS bad - m_axis_tuser_next = 1'b1; - error_bad_frame_next = 1'b1; - error_bad_fcs_next = 1'b1; - end - state_next = STATE_IDLE; - end else begin - state_next = STATE_PAYLOAD; - end - end - STATE_WAIT_LAST: begin - // wait for end of packet - - if (~gmii_rx_dv) begin - state_next = STATE_IDLE; - end else begin - state_next = STATE_WAIT_LAST; - end - end - endcase - end -end - -always @(posedge clk) begin - state_reg <= state_next; - - m_axis_tdata_reg <= m_axis_tdata_next; - m_axis_tvalid_reg <= m_axis_tvalid_next; - m_axis_tlast_reg <= m_axis_tlast_next; - m_axis_tuser_reg <= m_axis_tuser_next; - - start_packet_int_reg <= 1'b0; - start_packet_reg <= 1'b0; - - if (start_packet_int_reg) begin - ptp_ts_reg <= ptp_ts; - start_packet_reg <= 1'b1; - end - - if (clk_enable) begin - if (mii_select) begin - mii_odd <= !mii_odd; - - if (in_frame) begin - in_frame <= gmii_rx_dv; - end else if (gmii_rx_dv && {gmii_rxd[3:0], gmii_rxd_d0[7:4]} == ETH_SFD) begin - in_frame <= 1'b1; - start_packet_int_reg <= 1'b1; - mii_odd <= 1'b1; - end - - gmii_rxd_d0 <= {gmii_rxd[3:0], gmii_rxd_d0[7:4]}; - - if (mii_odd) begin - gmii_rxd_d1 <= gmii_rxd_d0; - gmii_rxd_d2 <= gmii_rxd_d1; - gmii_rxd_d3 <= gmii_rxd_d2; - gmii_rxd_d4 <= gmii_rxd_d3; - - gmii_rx_dv_d0 <= gmii_rx_dv & gmii_rx_dv_d0; - gmii_rx_dv_d1 <= gmii_rx_dv_d0 & gmii_rx_dv; - gmii_rx_dv_d2 <= gmii_rx_dv_d1 & gmii_rx_dv; - gmii_rx_dv_d3 <= gmii_rx_dv_d2 & gmii_rx_dv; - gmii_rx_dv_d4 <= gmii_rx_dv_d3 & gmii_rx_dv; - - gmii_rx_er_d0 <= gmii_rx_er | gmii_rx_er_d0; - gmii_rx_er_d1 <= gmii_rx_er_d0; - gmii_rx_er_d2 <= gmii_rx_er_d1; - gmii_rx_er_d3 <= gmii_rx_er_d2; - gmii_rx_er_d4 <= gmii_rx_er_d3; - end else begin - gmii_rx_dv_d0 <= gmii_rx_dv; - gmii_rx_er_d0 <= gmii_rx_er; - end - end else begin - if (in_frame) begin - in_frame <= gmii_rx_dv; - end else if (gmii_rx_dv && gmii_rxd == ETH_SFD) begin - in_frame <= 1'b1; - start_packet_int_reg <= 1'b1; - end - - gmii_rxd_d0 <= gmii_rxd; - gmii_rxd_d1 <= gmii_rxd_d0; - gmii_rxd_d2 <= gmii_rxd_d1; - gmii_rxd_d3 <= gmii_rxd_d2; - gmii_rxd_d4 <= gmii_rxd_d3; - - gmii_rx_dv_d0 <= gmii_rx_dv; - gmii_rx_dv_d1 <= gmii_rx_dv_d0 & gmii_rx_dv; - gmii_rx_dv_d2 <= gmii_rx_dv_d1 & gmii_rx_dv; - gmii_rx_dv_d3 <= gmii_rx_dv_d2 & gmii_rx_dv; - gmii_rx_dv_d4 <= gmii_rx_dv_d3 & gmii_rx_dv; - - gmii_rx_er_d0 <= gmii_rx_er; - gmii_rx_er_d1 <= gmii_rx_er_d0; - gmii_rx_er_d2 <= gmii_rx_er_d1; - gmii_rx_er_d3 <= gmii_rx_er_d2; - gmii_rx_er_d4 <= gmii_rx_er_d3; - end - end - - if (reset_crc) begin - crc_state <= 32'hFFFFFFFF; - end else if (update_crc) begin - crc_state <= crc_next; - end - - error_bad_frame_reg <= error_bad_frame_next; - error_bad_fcs_reg <= error_bad_fcs_next; - - if (rst) begin - state_reg <= STATE_IDLE; - - m_axis_tvalid_reg <= 1'b0; - - start_packet_int_reg <= 1'b0; - start_packet_reg <= 1'b0; - error_bad_frame_reg <= 1'b0; - error_bad_fcs_reg <= 1'b0; - - in_frame <= 1'b0; - mii_odd <= 1'b0; - - gmii_rx_dv_d0 <= 1'b0; - gmii_rx_dv_d1 <= 1'b0; - gmii_rx_dv_d2 <= 1'b0; - gmii_rx_dv_d3 <= 1'b0; - gmii_rx_dv_d4 <= 1'b0; - end -end - -endmodule - -`resetall diff --git a/src/rvvi/axis_gmii_tx.sv b/src/rvvi/axis_gmii_tx.sv deleted file mode 100644 index f2936039f..000000000 --- a/src/rvvi/axis_gmii_tx.sv +++ /dev/null @@ -1,457 +0,0 @@ -/* - -Copyright (c) 2015-2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * AXI4-Stream GMII frame transmitter (AXI in, GMII out) - */ -module axis_gmii_tx # -( - parameter DATA_WIDTH = 8, - parameter ENABLE_PADDING = 1, - parameter MIN_FRAME_LENGTH = 64, - parameter PTP_TS_ENABLE = 0, - parameter PTP_TS_WIDTH = 96, - parameter PTP_TS_CTRL_IN_TUSER = 0, - parameter PTP_TAG_ENABLE = PTP_TS_ENABLE, - parameter PTP_TAG_WIDTH = 16, - parameter USER_WIDTH = (PTP_TS_ENABLE ? (PTP_TAG_ENABLE ? PTP_TAG_WIDTH : 0) + (PTP_TS_CTRL_IN_TUSER ? 1 : 0) : 0) + 1 -) -( - input wire clk, - input wire rst, - - /* - * AXI input - */ - input wire [DATA_WIDTH-1:0] s_axis_tdata, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire [USER_WIDTH-1:0] s_axis_tuser, - - /* - * GMII output - */ - output wire [DATA_WIDTH-1:0] gmii_txd, - output wire gmii_tx_en, - output wire gmii_tx_er, - - /* - * PTP - */ - input wire [PTP_TS_WIDTH-1:0] ptp_ts, - output wire [PTP_TS_WIDTH-1:0] m_axis_ptp_ts, - output wire [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag, - output wire m_axis_ptp_ts_valid, - - /* - * Control - */ - input wire clk_enable, - input wire mii_select, - - /* - * Configuration - */ - input wire [7:0] cfg_ifg, - input wire cfg_tx_enable, - - /* - * Status - */ - output wire start_packet, - output wire error_underflow -); - -parameter MIN_LEN_WIDTH = $clog2(MIN_FRAME_LENGTH-4-1+1); - -// bus width assertions -initial begin - if (DATA_WIDTH != 8) begin - $error("Error: Interface width must be 8"); - $finish; - end -end - -localparam [7:0] - ETH_PRE = 8'h55, - ETH_SFD = 8'hD5; - -localparam [2:0] - STATE_IDLE = 3'd0, - STATE_PREAMBLE = 3'd1, - STATE_PAYLOAD = 3'd2, - STATE_LAST = 3'd3, - STATE_PAD = 3'd4, - STATE_FCS = 3'd5, - STATE_IFG = 3'd6; - -reg [2:0] state_reg = STATE_IDLE, state_next; - -// datapath control signals -reg reset_crc; -reg update_crc; - -reg [7:0] s_tdata_reg = 8'd0, s_tdata_next; - -reg mii_odd_reg = 1'b0, mii_odd_next; -reg [3:0] mii_msn_reg = 4'b0, mii_msn_next; - -reg frame_reg = 1'b0, frame_next; -reg frame_error_reg = 1'b0, frame_error_next; -reg [7:0] frame_ptr_reg = 0, frame_ptr_next; -reg [MIN_LEN_WIDTH-1:0] frame_min_count_reg = 0, frame_min_count_next; - -reg [7:0] gmii_txd_reg = 8'd0, gmii_txd_next; -reg gmii_tx_en_reg = 1'b0, gmii_tx_en_next; -reg gmii_tx_er_reg = 1'b0, gmii_tx_er_next; - -reg s_axis_tready_reg = 1'b0, s_axis_tready_next; - -reg [PTP_TS_WIDTH-1:0] m_axis_ptp_ts_reg = 0, m_axis_ptp_ts_next; -reg [PTP_TAG_WIDTH-1:0] m_axis_ptp_ts_tag_reg = 0, m_axis_ptp_ts_tag_next; -reg m_axis_ptp_ts_valid_reg = 1'b0, m_axis_ptp_ts_valid_next; - -reg start_packet_int_reg = 1'b0, start_packet_int_next; -reg start_packet_reg = 1'b0, start_packet_next; -reg error_underflow_reg = 1'b0, error_underflow_next; - -reg [31:0] crc_state = 32'hFFFFFFFF; -wire [31:0] crc_next; - -assign s_axis_tready = s_axis_tready_reg; - -assign gmii_txd = gmii_txd_reg; -assign gmii_tx_en = gmii_tx_en_reg; -assign gmii_tx_er = gmii_tx_er_reg; - -assign m_axis_ptp_ts = PTP_TS_ENABLE ? m_axis_ptp_ts_reg : 0; -assign m_axis_ptp_ts_tag = PTP_TAG_ENABLE ? m_axis_ptp_ts_tag_reg : 0; -assign m_axis_ptp_ts_valid = PTP_TS_ENABLE || PTP_TAG_ENABLE ? m_axis_ptp_ts_valid_reg : 1'b0; - -assign start_packet = start_packet_reg; -assign error_underflow = error_underflow_reg; - -lfsr #( - .LFSR_WIDTH(32), - .LFSR_POLY(32'h4c11db7), - .LFSR_CONFIG("GALOIS"), - .LFSR_FEED_FORWARD(0), - .REVERSE(1), - .DATA_WIDTH(8), - .STYLE("AUTO") -) -eth_crc_8 ( - .data_in(s_tdata_reg), - .state_in(crc_state), - .data_out(), - .state_out(crc_next) -); - -always @* begin - state_next = STATE_IDLE; - - reset_crc = 1'b0; - update_crc = 1'b0; - - mii_odd_next = mii_odd_reg; - mii_msn_next = mii_msn_reg; - - frame_next = frame_reg; - frame_error_next = frame_error_reg; - frame_ptr_next = frame_ptr_reg; - frame_min_count_next = frame_min_count_reg; - - s_axis_tready_next = 1'b0; - - s_tdata_next = s_tdata_reg; - - m_axis_ptp_ts_next = m_axis_ptp_ts_reg; - m_axis_ptp_ts_tag_next = m_axis_ptp_ts_tag_reg; - m_axis_ptp_ts_valid_next = 1'b0; - - if (start_packet_reg && PTP_TS_ENABLE) begin - m_axis_ptp_ts_next = ptp_ts; - if (PTP_TS_CTRL_IN_TUSER) begin - m_axis_ptp_ts_tag_next = s_axis_tuser >> 2; - m_axis_ptp_ts_valid_next = s_axis_tuser[1]; - end else begin - m_axis_ptp_ts_tag_next = s_axis_tuser >> 1; - m_axis_ptp_ts_valid_next = 1'b1; - end - end - - gmii_txd_next = {DATA_WIDTH{1'b0}}; - gmii_tx_en_next = 1'b0; - gmii_tx_er_next = 1'b0; - - start_packet_int_next = start_packet_int_reg; - start_packet_next = 1'b0; - error_underflow_next = 1'b0; - - if (s_axis_tvalid && s_axis_tready) begin - frame_next = !s_axis_tlast; - end - - if (!clk_enable) begin - // clock disabled - hold state and outputs - gmii_txd_next = gmii_txd_reg; - gmii_tx_en_next = gmii_tx_en_reg; - gmii_tx_er_next = gmii_tx_er_reg; - state_next = state_reg; - end else if (mii_select && mii_odd_reg) begin - // MII odd cycle - hold state, output MSN - mii_odd_next = 1'b0; - gmii_txd_next = {4'd0, mii_msn_reg}; - gmii_tx_en_next = gmii_tx_en_reg; - gmii_tx_er_next = gmii_tx_er_reg; - state_next = state_reg; - if (start_packet_int_reg) begin - start_packet_int_next = 1'b0; - start_packet_next = 1'b1; - end - end else begin - case (state_reg) - STATE_IDLE: begin - // idle state - wait for packet - reset_crc = 1'b1; - - mii_odd_next = 1'b0; - frame_ptr_next = 1; - - frame_error_next = 1'b0; - frame_min_count_next = MIN_FRAME_LENGTH-4-1; - - if (s_axis_tvalid && cfg_tx_enable) begin - mii_odd_next = 1'b1; - gmii_txd_next = ETH_PRE; - gmii_tx_en_next = 1'b1; - state_next = STATE_PREAMBLE; - end else begin - state_next = STATE_IDLE; - end - end - STATE_PREAMBLE: begin - // send preamble - reset_crc = 1'b1; - - mii_odd_next = 1'b1; - frame_ptr_next = frame_ptr_reg + 1; - - gmii_txd_next = ETH_PRE; - gmii_tx_en_next = 1'b1; - - if (frame_ptr_reg == 6) begin - s_axis_tready_next = 1'b1; - s_tdata_next = s_axis_tdata; - state_next = STATE_PREAMBLE; - end else if (frame_ptr_reg == 7) begin - // end of preamble; start payload - frame_ptr_next = 0; - if (s_axis_tready_reg) begin - s_axis_tready_next = 1'b1; - s_tdata_next = s_axis_tdata; - end - gmii_txd_next = ETH_SFD; - if (mii_select) begin - start_packet_int_next = 1'b1; - end else begin - start_packet_next = 1'b1; - end - state_next = STATE_PAYLOAD; - end else begin - state_next = STATE_PREAMBLE; - end - end - STATE_PAYLOAD: begin - // send payload - - update_crc = 1'b1; - s_axis_tready_next = 1'b1; - - mii_odd_next = 1'b1; - - if (frame_min_count_reg) begin - frame_min_count_next = frame_min_count_reg - 1; - end - - gmii_txd_next = s_tdata_reg; - gmii_tx_en_next = 1'b1; - - s_tdata_next = s_axis_tdata; - - if (!s_axis_tvalid || s_axis_tlast) begin - s_axis_tready_next = frame_next; // drop frame - frame_error_next = !s_axis_tvalid || s_axis_tuser[0]; - error_underflow_next = !s_axis_tvalid; - - state_next = STATE_LAST; - end else begin - state_next = STATE_PAYLOAD; - end - end - STATE_LAST: begin - // last payload word - - update_crc = 1'b1; - s_axis_tready_next = 1'b0; - - mii_odd_next = 1'b1; - - gmii_txd_next = s_tdata_reg; - gmii_tx_en_next = 1'b1; - - if (ENABLE_PADDING && frame_min_count_reg) begin - frame_min_count_next = frame_min_count_reg - 1; - s_tdata_next = 8'd0; - state_next = STATE_PAD; - end else begin - frame_ptr_next = 0; - state_next = STATE_FCS; - end - end - STATE_PAD: begin - // send padding - s_axis_tready_next = frame_next; // drop frame - - update_crc = 1'b1; - mii_odd_next = 1'b1; - - gmii_txd_next = 8'd0; - gmii_tx_en_next = 1'b1; - - s_tdata_next = 8'd0; - - if (frame_min_count_reg) begin - frame_min_count_next = frame_min_count_reg - 1; - state_next = STATE_PAD; - end else begin - frame_ptr_next = 0; - state_next = STATE_FCS; - end - end - STATE_FCS: begin - // send FCS - s_axis_tready_next = frame_next; // drop frame - - mii_odd_next = 1'b1; - frame_ptr_next = frame_ptr_reg + 1; - - case (frame_ptr_reg) - 2'd0: gmii_txd_next = ~crc_state[7:0]; - 2'd1: gmii_txd_next = ~crc_state[15:8]; - 2'd2: gmii_txd_next = ~crc_state[23:16]; - 2'd3: gmii_txd_next = ~crc_state[31:24]; - endcase - gmii_tx_en_next = 1'b1; - gmii_tx_er_next = frame_error_reg; - - if (frame_ptr_reg < 3) begin - state_next = STATE_FCS; - end else begin - frame_ptr_next = 0; - state_next = STATE_IFG; - end - end - STATE_IFG: begin - // send IFG - s_axis_tready_next = frame_next; // drop frame - - mii_odd_next = 1'b1; - frame_ptr_next = frame_ptr_reg + 1; - - if (frame_ptr_reg < cfg_ifg-1 || frame_reg) begin - state_next = STATE_IFG; - end else begin - state_next = STATE_IDLE; - end - end - endcase - - if (mii_select) begin - mii_msn_next = gmii_txd_next[7:4]; - gmii_txd_next[7:4] = 4'd0; - end - end -end - -always @(posedge clk) begin - state_reg <= state_next; - - frame_reg <= frame_next; - frame_error_reg <= frame_error_next; - frame_ptr_reg <= frame_ptr_next; - frame_min_count_reg <= frame_min_count_next; - - m_axis_ptp_ts_reg <= m_axis_ptp_ts_next; - m_axis_ptp_ts_tag_reg <= m_axis_ptp_ts_tag_next; - m_axis_ptp_ts_valid_reg <= m_axis_ptp_ts_valid_next; - - mii_odd_reg <= mii_odd_next; - mii_msn_reg <= mii_msn_next; - - s_tdata_reg <= s_tdata_next; - - s_axis_tready_reg <= s_axis_tready_next; - - gmii_txd_reg <= gmii_txd_next; - gmii_tx_en_reg <= gmii_tx_en_next; - gmii_tx_er_reg <= gmii_tx_er_next; - - if (reset_crc) begin - crc_state <= 32'hFFFFFFFF; - end else if (update_crc) begin - crc_state <= crc_next; - end - - start_packet_int_reg <= start_packet_int_next; - start_packet_reg <= start_packet_next; - error_underflow_reg <= error_underflow_next; - - if (rst) begin - state_reg <= STATE_IDLE; - - frame_reg <= 1'b0; - - s_axis_tready_reg <= 1'b0; - - m_axis_ptp_ts_valid_reg <= 1'b0; - - gmii_tx_en_reg <= 1'b0; - gmii_tx_er_reg <= 1'b0; - - start_packet_int_reg <= 1'b0; - start_packet_reg <= 1'b0; - error_underflow_reg <= 1'b0; - end -end - -endmodule - -`resetall diff --git a/src/rvvi/eth_axis_tx.sv b/src/rvvi/eth_axis_tx.sv deleted file mode 100644 index b4287b281..000000000 --- a/src/rvvi/eth_axis_tx.sv +++ /dev/null @@ -1,408 +0,0 @@ -/* - -Copyright (c) 2014-2020 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * AXI4-Stream ethernet frame transmitter (Ethernet frame in, AXI out) - */ -module eth_axis_tx # -( - // Width of AXI stream interfaces in bits - parameter DATA_WIDTH = 8, - // Propagate tkeep signal - // If disabled, tkeep assumed to be 1'b1 - parameter KEEP_ENABLE = (DATA_WIDTH>8), - // tkeep signal width (words per cycle) - parameter KEEP_WIDTH = (DATA_WIDTH/8) -) -( - input wire clk, - input wire rst, - - /* - * Ethernet frame input - */ - input wire s_eth_hdr_valid, - output wire s_eth_hdr_ready, - input wire [47:0] s_eth_dest_mac, - input wire [47:0] s_eth_src_mac, - input wire [15:0] s_eth_type, - input wire [DATA_WIDTH-1:0] s_eth_payload_axis_tdata, - input wire [KEEP_WIDTH-1:0] s_eth_payload_axis_tkeep, - input wire s_eth_payload_axis_tvalid, - output wire s_eth_payload_axis_tready, - input wire s_eth_payload_axis_tlast, - input wire s_eth_payload_axis_tuser, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] m_axis_tdata, - output wire [KEEP_WIDTH-1:0] m_axis_tkeep, - output wire m_axis_tvalid, - input wire m_axis_tready, - output wire m_axis_tlast, - output wire m_axis_tuser, - - /* - * Status signals - */ - output wire busy -); - -parameter BYTE_LANES = KEEP_ENABLE ? KEEP_WIDTH : 1; - -parameter HDR_SIZE = 14; - -parameter CYCLE_COUNT = (HDR_SIZE+BYTE_LANES-1)/BYTE_LANES; - -parameter PTR_WIDTH = $clog2(CYCLE_COUNT); - -parameter OFFSET = HDR_SIZE % BYTE_LANES; - -// bus width assertions -initial begin - if (BYTE_LANES * 8 != DATA_WIDTH) begin - $error("Error: AXI stream interface requires byte (8-bit) granularity (instance %m)"); - $finish; - end -end - -/* - -Ethernet frame - - Field Length - Destination MAC address 6 octets - Source MAC address 6 octets - Ethertype 2 octets - -This module receives an Ethernet frame with header fields in parallel along -with the payload in an AXI stream, combines the header with the payload, and -transmits the complete Ethernet frame on the output AXI stream interface. - -*/ - -// datapath control signals -reg store_eth_hdr; - -reg send_eth_header_reg = 1'b0, send_eth_header_next; -reg send_eth_payload_reg = 1'b0, send_eth_payload_next; -reg [PTR_WIDTH-1:0] ptr_reg = 0, ptr_next; - -reg flush_save; -reg transfer_in_save; - -reg [47:0] eth_dest_mac_reg = 48'd0; -reg [47:0] eth_src_mac_reg = 48'd0; -reg [15:0] eth_type_reg = 16'd0; - -reg s_eth_hdr_ready_reg = 1'b0, s_eth_hdr_ready_next; -reg s_eth_payload_axis_tready_reg = 1'b0, s_eth_payload_axis_tready_next; - -reg busy_reg = 1'b0; - -reg [DATA_WIDTH-1:0] save_eth_payload_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] save_eth_payload_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg save_eth_payload_axis_tlast_reg = 1'b0; -reg save_eth_payload_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] shift_eth_payload_axis_tdata; -reg [KEEP_WIDTH-1:0] shift_eth_payload_axis_tkeep; -reg shift_eth_payload_axis_tvalid; -reg shift_eth_payload_axis_tlast; -reg shift_eth_payload_axis_tuser; -reg shift_eth_payload_axis_input_tready; -reg shift_eth_payload_axis_extra_cycle_reg = 1'b0; - -// internal datapath -reg [DATA_WIDTH-1:0] m_axis_tdata_int; -reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; -reg m_axis_tvalid_int; -reg m_axis_tready_int_reg = 1'b0; -reg m_axis_tlast_int; -reg m_axis_tuser_int; -wire m_axis_tready_int_early; - -assign s_eth_hdr_ready = s_eth_hdr_ready_reg; -assign s_eth_payload_axis_tready = s_eth_payload_axis_tready_reg; - -assign busy = busy_reg; - -always @* begin - if (OFFSET == 0) begin - // passthrough if no overlap - shift_eth_payload_axis_tdata = s_eth_payload_axis_tdata; - shift_eth_payload_axis_tkeep = s_eth_payload_axis_tkeep; - shift_eth_payload_axis_tvalid = s_eth_payload_axis_tvalid; - shift_eth_payload_axis_tlast = s_eth_payload_axis_tlast; - shift_eth_payload_axis_tuser = s_eth_payload_axis_tuser; - shift_eth_payload_axis_input_tready = 1'b1; - end else if (shift_eth_payload_axis_extra_cycle_reg) begin - shift_eth_payload_axis_tdata = {s_eth_payload_axis_tdata, save_eth_payload_axis_tdata_reg} >> ((KEEP_WIDTH-OFFSET)*8); - shift_eth_payload_axis_tkeep = {{KEEP_WIDTH{1'b0}}, save_eth_payload_axis_tkeep_reg} >> (KEEP_WIDTH-OFFSET); - shift_eth_payload_axis_tvalid = 1'b1; - shift_eth_payload_axis_tlast = save_eth_payload_axis_tlast_reg; - shift_eth_payload_axis_tuser = save_eth_payload_axis_tuser_reg; - shift_eth_payload_axis_input_tready = flush_save; - end else begin - shift_eth_payload_axis_tdata = {s_eth_payload_axis_tdata, save_eth_payload_axis_tdata_reg} >> ((KEEP_WIDTH-OFFSET)*8); - shift_eth_payload_axis_tkeep = {s_eth_payload_axis_tkeep, save_eth_payload_axis_tkeep_reg} >> (KEEP_WIDTH-OFFSET); - shift_eth_payload_axis_tvalid = s_eth_payload_axis_tvalid; - shift_eth_payload_axis_tlast = (s_eth_payload_axis_tlast && ((s_eth_payload_axis_tkeep & ({KEEP_WIDTH{1'b1}} << (KEEP_WIDTH-OFFSET))) == 0)); - shift_eth_payload_axis_tuser = (s_eth_payload_axis_tuser && ((s_eth_payload_axis_tkeep & ({KEEP_WIDTH{1'b1}} << (KEEP_WIDTH-OFFSET))) == 0)); - shift_eth_payload_axis_input_tready = !(s_eth_payload_axis_tlast && s_eth_payload_axis_tready && s_eth_payload_axis_tvalid); - end -end - -always @* begin - send_eth_header_next = send_eth_header_reg; - send_eth_payload_next = send_eth_payload_reg; - ptr_next = ptr_reg; - - s_eth_hdr_ready_next = 1'b0; - s_eth_payload_axis_tready_next = 1'b0; - - store_eth_hdr = 1'b0; - - flush_save = 1'b0; - transfer_in_save = 1'b0; - - m_axis_tdata_int = {DATA_WIDTH{1'b0}}; - m_axis_tkeep_int = {KEEP_WIDTH{1'b0}}; - m_axis_tvalid_int = 1'b0; - m_axis_tlast_int = 1'b0; - m_axis_tuser_int = 1'b0; - - if (s_eth_hdr_ready && s_eth_hdr_valid) begin - store_eth_hdr = 1'b1; - ptr_next = 0; - send_eth_header_next = 1'b1; - send_eth_payload_next = (OFFSET != 0) && (CYCLE_COUNT == 1); - s_eth_payload_axis_tready_next = send_eth_payload_next && m_axis_tready_int_early; - end - - if (send_eth_payload_reg) begin - s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_axis_input_tready; - - m_axis_tdata_int = shift_eth_payload_axis_tdata; - m_axis_tkeep_int = shift_eth_payload_axis_tkeep; - m_axis_tlast_int = shift_eth_payload_axis_tlast; - m_axis_tuser_int = shift_eth_payload_axis_tuser; - - if ((s_eth_payload_axis_tready && s_eth_payload_axis_tvalid) || (m_axis_tready_int_reg && shift_eth_payload_axis_extra_cycle_reg)) begin - transfer_in_save = 1'b1; - - m_axis_tvalid_int = 1'b1; - - if (shift_eth_payload_axis_tlast) begin - flush_save = 1'b1; - s_eth_payload_axis_tready_next = 1'b0; - ptr_next = 0; - send_eth_payload_next = 1'b0; - end - end - end - - if (m_axis_tready_int_reg && (!OFFSET || !send_eth_payload_reg || m_axis_tvalid_int)) begin - if (send_eth_header_reg) begin - ptr_next = ptr_reg + 1; - - if ((OFFSET != 0) && (CYCLE_COUNT == 1 || ptr_next == CYCLE_COUNT-1) && !send_eth_payload_reg) begin - send_eth_payload_next = 1'b1; - s_eth_payload_axis_tready_next = m_axis_tready_int_early && shift_eth_payload_axis_input_tready; - end - - m_axis_tvalid_int = 1'b1; - - `define _HEADER_FIELD_(offset, field) \ - if (ptr_reg == offset/BYTE_LANES) begin \ - m_axis_tdata_int[(offset%BYTE_LANES)*8 +: 8] = field; \ - m_axis_tkeep_int[offset%BYTE_LANES] = 1'b1; \ - end - - `_HEADER_FIELD_(0, eth_dest_mac_reg[5*8 +: 8]) - `_HEADER_FIELD_(1, eth_dest_mac_reg[4*8 +: 8]) - `_HEADER_FIELD_(2, eth_dest_mac_reg[3*8 +: 8]) - `_HEADER_FIELD_(3, eth_dest_mac_reg[2*8 +: 8]) - `_HEADER_FIELD_(4, eth_dest_mac_reg[1*8 +: 8]) - `_HEADER_FIELD_(5, eth_dest_mac_reg[0*8 +: 8]) - `_HEADER_FIELD_(6, eth_src_mac_reg[5*8 +: 8]) - `_HEADER_FIELD_(7, eth_src_mac_reg[4*8 +: 8]) - `_HEADER_FIELD_(8, eth_src_mac_reg[3*8 +: 8]) - `_HEADER_FIELD_(9, eth_src_mac_reg[2*8 +: 8]) - `_HEADER_FIELD_(10, eth_src_mac_reg[1*8 +: 8]) - `_HEADER_FIELD_(11, eth_src_mac_reg[0*8 +: 8]) - `_HEADER_FIELD_(12, eth_type_reg[1*8 +: 8]) - `_HEADER_FIELD_(13, eth_type_reg[0*8 +: 8]) - - if (ptr_reg == 13/BYTE_LANES) begin - if (!send_eth_payload_reg) begin - s_eth_payload_axis_tready_next = m_axis_tready_int_early; - send_eth_payload_next = 1'b1; - end - send_eth_header_next = 1'b0; - end - - `undef _HEADER_FIELD_ - end - end - - s_eth_hdr_ready_next = !(send_eth_header_next || send_eth_payload_next); -end - -always @(posedge clk) begin - send_eth_header_reg <= send_eth_header_next; - send_eth_payload_reg <= send_eth_payload_next; - ptr_reg <= ptr_next; - - s_eth_hdr_ready_reg <= s_eth_hdr_ready_next; - s_eth_payload_axis_tready_reg <= s_eth_payload_axis_tready_next; - - busy_reg <= send_eth_header_next || send_eth_payload_next; - - if (store_eth_hdr) begin - eth_dest_mac_reg <= s_eth_dest_mac; - eth_src_mac_reg <= s_eth_src_mac; - eth_type_reg <= s_eth_type; - end - - if (transfer_in_save) begin - save_eth_payload_axis_tdata_reg <= s_eth_payload_axis_tdata; - save_eth_payload_axis_tkeep_reg <= s_eth_payload_axis_tkeep; - save_eth_payload_axis_tuser_reg <= s_eth_payload_axis_tuser; - end - - if (flush_save) begin - save_eth_payload_axis_tlast_reg <= 1'b0; - shift_eth_payload_axis_extra_cycle_reg <= 1'b0; - end else if (transfer_in_save) begin - save_eth_payload_axis_tlast_reg <= s_eth_payload_axis_tlast; - shift_eth_payload_axis_extra_cycle_reg <= OFFSET ? s_eth_payload_axis_tlast && ((s_eth_payload_axis_tkeep & ({KEEP_WIDTH{1'b1}} << (KEEP_WIDTH-OFFSET))) != 0) : 1'b0; - end - - if (rst) begin - send_eth_header_reg <= 1'b0; - send_eth_payload_reg <= 1'b0; - ptr_reg <= 0; - s_eth_hdr_ready_reg <= 1'b0; - s_eth_payload_axis_tready_reg <= 1'b0; - busy_reg <= 1'b0; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; -reg m_axis_tlast_reg = 1'b0; -reg m_axis_tuser_reg = 1'b0; - -reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; -reg temp_m_axis_tlast_reg = 1'b0; -reg temp_m_axis_tuser_reg = 1'b0; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign m_axis_tdata = m_axis_tdata_reg; -assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign m_axis_tvalid = m_axis_tvalid_reg; -assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tuser = m_axis_tuser_reg; - -// enable ready input next cycle if output is ready or if both output registers are empty -assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && !m_axis_tvalid_reg); - -always @* begin - // transfer sink ready state to source - m_axis_tvalid_next = m_axis_tvalid_reg; - temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (m_axis_tready_int_reg) begin - // input is ready - if (m_axis_tready || !m_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - m_axis_tvalid_next = m_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_m_axis_tvalid_next = m_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (m_axis_tready) begin - // input is not ready, but output is ready - m_axis_tvalid_next = temp_m_axis_tvalid_reg; - temp_m_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - m_axis_tvalid_reg <= m_axis_tvalid_next; - m_axis_tready_int_reg <= m_axis_tready_int_early; - temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; - - // datapath - if (store_axis_int_to_output) begin - m_axis_tdata_reg <= m_axis_tdata_int; - m_axis_tkeep_reg <= m_axis_tkeep_int; - m_axis_tlast_reg <= m_axis_tlast_int; - m_axis_tuser_reg <= m_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - m_axis_tdata_reg <= temp_m_axis_tdata_reg; - m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; - m_axis_tlast_reg <= temp_m_axis_tlast_reg; - m_axis_tuser_reg <= temp_m_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_m_axis_tdata_reg <= m_axis_tdata_int; - temp_m_axis_tkeep_reg <= m_axis_tkeep_int; - temp_m_axis_tlast_reg <= m_axis_tlast_int; - temp_m_axis_tuser_reg <= m_axis_tuser_int; - end - - if (rst) begin - m_axis_tvalid_reg <= 1'b0; - m_axis_tready_int_reg <= 1'b0; - temp_m_axis_tvalid_reg <= 1'b0; - end -end - -endmodule - -`resetall diff --git a/src/rvvi/eth_mac_1g.sv b/src/rvvi/eth_mac_1g.sv deleted file mode 100644 index 6e0592fac..000000000 --- a/src/rvvi/eth_mac_1g.sv +++ /dev/null @@ -1,643 +0,0 @@ -/* - -Copyright (c) 2015-2023 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * 1G Ethernet MAC - */ -module eth_mac_1g # -( - parameter DATA_WIDTH = 8, - parameter ENABLE_PADDING = 1, - parameter MIN_FRAME_LENGTH = 64, - parameter PTP_TS_ENABLE = 0, - parameter PTP_TS_FMT_TOD = 1, - parameter PTP_TS_WIDTH = PTP_TS_FMT_TOD ? 96 : 64, - parameter TX_PTP_TS_CTRL_IN_TUSER = 0, - parameter TX_PTP_TAG_ENABLE = PTP_TS_ENABLE, - parameter TX_PTP_TAG_WIDTH = 16, - parameter TX_USER_WIDTH = (PTP_TS_ENABLE ? (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + (TX_PTP_TS_CTRL_IN_TUSER ? 1 : 0) : 0) + 1, - parameter RX_USER_WIDTH = (PTP_TS_ENABLE ? PTP_TS_WIDTH : 0) + 1, - parameter PFC_ENABLE = 0, - parameter PAUSE_ENABLE = PFC_ENABLE -) -( - input wire rx_clk, - input wire rx_rst, - input wire tx_clk, - input wire tx_rst, - - /* - * AXI input - */ - input wire [DATA_WIDTH-1:0] tx_axis_tdata, - input wire tx_axis_tvalid, - output wire tx_axis_tready, - input wire tx_axis_tlast, - input wire [TX_USER_WIDTH-1:0] tx_axis_tuser, - - /* - * AXI output - */ - output wire [DATA_WIDTH-1:0] rx_axis_tdata, - output wire rx_axis_tvalid, - output wire rx_axis_tlast, - output wire [RX_USER_WIDTH-1:0] rx_axis_tuser, - - /* - * GMII interface - */ - input wire [DATA_WIDTH-1:0] gmii_rxd, - input wire gmii_rx_dv, - input wire gmii_rx_er, - output wire [DATA_WIDTH-1:0] gmii_txd, - output wire gmii_tx_en, - output wire gmii_tx_er, - - /* - * PTP - */ - input wire [PTP_TS_WIDTH-1:0] tx_ptp_ts, - input wire [PTP_TS_WIDTH-1:0] rx_ptp_ts, - output wire [PTP_TS_WIDTH-1:0] tx_axis_ptp_ts, - output wire [TX_PTP_TAG_WIDTH-1:0] tx_axis_ptp_ts_tag, - output wire tx_axis_ptp_ts_valid, - - /* - * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) - */ - input wire tx_lfc_req, - input wire tx_lfc_resend, - input wire rx_lfc_en, - output wire rx_lfc_req, - input wire rx_lfc_ack, - - /* - * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) - */ - input wire [7:0] tx_pfc_req, - input wire tx_pfc_resend, - input wire [7:0] rx_pfc_en, - output wire [7:0] rx_pfc_req, - input wire [7:0] rx_pfc_ack, - - /* - * Pause interface - */ - input wire tx_lfc_pause_en, - input wire tx_pause_req, - output wire tx_pause_ack, - - /* - * Control - */ - input wire rx_clk_enable, - input wire tx_clk_enable, - input wire rx_mii_select, - input wire tx_mii_select, - - /* - * Status - */ - output wire tx_start_packet, - output wire tx_error_underflow, - output wire rx_start_packet, - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, - output wire stat_tx_mcf, - output wire stat_rx_mcf, - output wire stat_tx_lfc_pkt, - output wire stat_tx_lfc_xon, - output wire stat_tx_lfc_xoff, - output wire stat_tx_lfc_paused, - output wire stat_tx_pfc_pkt, - output wire [7:0] stat_tx_pfc_xon, - output wire [7:0] stat_tx_pfc_xoff, - output wire [7:0] stat_tx_pfc_paused, - output wire stat_rx_lfc_pkt, - output wire stat_rx_lfc_xon, - output wire stat_rx_lfc_xoff, - output wire stat_rx_lfc_paused, - output wire stat_rx_pfc_pkt, - output wire [7:0] stat_rx_pfc_xon, - output wire [7:0] stat_rx_pfc_xoff, - output wire [7:0] stat_rx_pfc_paused, - - /* - * Configuration - */ - input wire [7:0] cfg_ifg, - input wire cfg_tx_enable, - input wire cfg_rx_enable, - input wire [47:0] cfg_mcf_rx_eth_dst_mcast, - input wire cfg_mcf_rx_check_eth_dst_mcast, - input wire [47:0] cfg_mcf_rx_eth_dst_ucast, - input wire cfg_mcf_rx_check_eth_dst_ucast, - input wire [47:0] cfg_mcf_rx_eth_src, - input wire cfg_mcf_rx_check_eth_src, - input wire [15:0] cfg_mcf_rx_eth_type, - input wire [15:0] cfg_mcf_rx_opcode_lfc, - input wire cfg_mcf_rx_check_opcode_lfc, - input wire [15:0] cfg_mcf_rx_opcode_pfc, - input wire cfg_mcf_rx_check_opcode_pfc, - input wire cfg_mcf_rx_forward, - input wire cfg_mcf_rx_enable, - input wire [47:0] cfg_tx_lfc_eth_dst, - input wire [47:0] cfg_tx_lfc_eth_src, - input wire [15:0] cfg_tx_lfc_eth_type, - input wire [15:0] cfg_tx_lfc_opcode, - input wire cfg_tx_lfc_en, - input wire [15:0] cfg_tx_lfc_quanta, - input wire [15:0] cfg_tx_lfc_refresh, - input wire [47:0] cfg_tx_pfc_eth_dst, - input wire [47:0] cfg_tx_pfc_eth_src, - input wire [15:0] cfg_tx_pfc_eth_type, - input wire [15:0] cfg_tx_pfc_opcode, - input wire cfg_tx_pfc_en, - input wire [8*16-1:0] cfg_tx_pfc_quanta, - input wire [8*16-1:0] cfg_tx_pfc_refresh, - input wire [15:0] cfg_rx_lfc_opcode, - input wire cfg_rx_lfc_en, - input wire [15:0] cfg_rx_pfc_opcode, - input wire cfg_rx_pfc_en -); - -parameter MAC_CTRL_ENABLE = PAUSE_ENABLE || PFC_ENABLE; -parameter TX_USER_WIDTH_INT = MAC_CTRL_ENABLE ? (PTP_TS_ENABLE ? (TX_PTP_TAG_ENABLE ? TX_PTP_TAG_WIDTH : 0) + 1 : 0) + 1 : TX_USER_WIDTH; - -wire [DATA_WIDTH-1:0] tx_axis_tdata_int; -wire tx_axis_tvalid_int; -wire tx_axis_tready_int; -wire tx_axis_tlast_int; -wire [TX_USER_WIDTH_INT-1:0] tx_axis_tuser_int; - -wire [DATA_WIDTH-1:0] rx_axis_tdata_int; -wire rx_axis_tvalid_int; -wire rx_axis_tlast_int; -wire [RX_USER_WIDTH-1:0] rx_axis_tuser_int; - -axis_gmii_rx #( - .DATA_WIDTH(DATA_WIDTH), - .PTP_TS_ENABLE(PTP_TS_ENABLE), - .PTP_TS_WIDTH(PTP_TS_WIDTH), - .USER_WIDTH(RX_USER_WIDTH) -) -axis_gmii_rx_inst ( - .clk(rx_clk), - .rst(rx_rst), - .gmii_rxd(gmii_rxd), - .gmii_rx_dv(gmii_rx_dv), - .gmii_rx_er(gmii_rx_er), - .m_axis_tdata(rx_axis_tdata_int), - .m_axis_tvalid(rx_axis_tvalid_int), - .m_axis_tlast(rx_axis_tlast_int), - .m_axis_tuser(rx_axis_tuser_int), - .ptp_ts(rx_ptp_ts), - .clk_enable(rx_clk_enable), - .mii_select(rx_mii_select), - .cfg_rx_enable(cfg_rx_enable), - .start_packet(rx_start_packet), - .error_bad_frame(rx_error_bad_frame), - .error_bad_fcs(rx_error_bad_fcs) -); - -axis_gmii_tx #( - .DATA_WIDTH(DATA_WIDTH), - .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH), - .PTP_TS_ENABLE(PTP_TS_ENABLE), - .PTP_TS_WIDTH(PTP_TS_WIDTH), - .PTP_TS_CTRL_IN_TUSER(MAC_CTRL_ENABLE ? PTP_TS_ENABLE : TX_PTP_TS_CTRL_IN_TUSER), - .PTP_TAG_ENABLE(TX_PTP_TAG_ENABLE), - .PTP_TAG_WIDTH(TX_PTP_TAG_WIDTH), - .USER_WIDTH(TX_USER_WIDTH_INT) -) -axis_gmii_tx_inst ( - .clk(tx_clk), - .rst(tx_rst), - .s_axis_tdata(tx_axis_tdata_int), - .s_axis_tvalid(tx_axis_tvalid_int), - .s_axis_tready(tx_axis_tready_int), - .s_axis_tlast(tx_axis_tlast_int), - .s_axis_tuser(tx_axis_tuser_int), - .gmii_txd(gmii_txd), - .gmii_tx_en(gmii_tx_en), - .gmii_tx_er(gmii_tx_er), - .ptp_ts(tx_ptp_ts), - .m_axis_ptp_ts(tx_axis_ptp_ts), - .m_axis_ptp_ts_tag(tx_axis_ptp_ts_tag), - .m_axis_ptp_ts_valid(tx_axis_ptp_ts_valid), - .clk_enable(tx_clk_enable), - .mii_select(tx_mii_select), - .cfg_ifg(cfg_ifg), - .cfg_tx_enable(cfg_tx_enable), - .start_packet(tx_start_packet), - .error_underflow(tx_error_underflow) -); - -generate - -if (MAC_CTRL_ENABLE) begin : mac_ctrl - - localparam MCF_PARAMS_SIZE = PFC_ENABLE ? 18 : 2; - - wire tx_mcf_valid; - wire tx_mcf_ready; - wire [47:0] tx_mcf_eth_dst; - wire [47:0] tx_mcf_eth_src; - wire [15:0] tx_mcf_eth_type; - wire [15:0] tx_mcf_opcode; - wire [MCF_PARAMS_SIZE*8-1:0] tx_mcf_params; - - wire rx_mcf_valid; - wire [47:0] rx_mcf_eth_dst; - wire [47:0] rx_mcf_eth_src; - wire [15:0] rx_mcf_eth_type; - wire [15:0] rx_mcf_opcode; - wire [MCF_PARAMS_SIZE*8-1:0] rx_mcf_params; - - // terminate LFC pause requests from RX internally on TX side - wire tx_pause_req_int; - wire rx_lfc_ack_int; - - reg tx_lfc_req_sync_reg_1 = 1'b0; - reg tx_lfc_req_sync_reg_2 = 1'b0; - reg tx_lfc_req_sync_reg_3 = 1'b0; - - always @(posedge rx_clk or posedge rx_rst) begin - if (rx_rst) begin - tx_lfc_req_sync_reg_1 <= 1'b0; - end else begin - tx_lfc_req_sync_reg_1 <= rx_lfc_req; - end - end - - always @(posedge tx_clk or posedge tx_rst) begin - if (tx_rst) begin - tx_lfc_req_sync_reg_2 <= 1'b0; - tx_lfc_req_sync_reg_3 <= 1'b0; - end else begin - tx_lfc_req_sync_reg_2 <= tx_lfc_req_sync_reg_1; - tx_lfc_req_sync_reg_3 <= tx_lfc_req_sync_reg_2; - end - end - - reg rx_lfc_ack_sync_reg_1 = 1'b0; - reg rx_lfc_ack_sync_reg_2 = 1'b0; - reg rx_lfc_ack_sync_reg_3 = 1'b0; - - always @(posedge tx_clk or posedge tx_rst) begin - if (tx_rst) begin - rx_lfc_ack_sync_reg_1 <= 1'b0; - end else begin - rx_lfc_ack_sync_reg_1 <= tx_lfc_pause_en ? tx_pause_ack : 0; - end - end - - always @(posedge rx_clk or posedge rx_rst) begin - if (rx_rst) begin - rx_lfc_ack_sync_reg_2 <= 1'b0; - rx_lfc_ack_sync_reg_3 <= 1'b0; - end else begin - rx_lfc_ack_sync_reg_2 <= rx_lfc_ack_sync_reg_1; - rx_lfc_ack_sync_reg_3 <= rx_lfc_ack_sync_reg_2; - end - end - - assign tx_pause_req_int = tx_pause_req || (tx_lfc_pause_en ? tx_lfc_req_sync_reg_3 : 0); - - assign rx_lfc_ack_int = rx_lfc_ack || rx_lfc_ack_sync_reg_3; - - // handle PTP TS enable bit in tuser - wire [TX_USER_WIDTH_INT-1:0] tx_axis_tuser_in; - - if (PTP_TS_ENABLE && !TX_PTP_TS_CTRL_IN_TUSER) begin - assign tx_axis_tuser_in = {tx_axis_tuser[TX_USER_WIDTH-1:1], 1'b1, tx_axis_tuser[0]}; - end else begin - assign tx_axis_tuser_in = tx_axis_tuser; - end - - mac_ctrl_tx #( - .DATA_WIDTH(DATA_WIDTH), - .KEEP_ENABLE(0), - .ID_ENABLE(0), - .DEST_ENABLE(0), - .USER_ENABLE(1), - .USER_WIDTH(TX_USER_WIDTH_INT), - .MCF_PARAMS_SIZE(MCF_PARAMS_SIZE) - ) - mac_ctrl_tx_inst ( - .clk(tx_clk), - .rst(tx_rst), - - /* - * AXI stream input - */ - .s_axis_tdata(tx_axis_tdata), - .s_axis_tkeep(1'b1), - .s_axis_tvalid(tx_axis_tvalid), - .s_axis_tready(tx_axis_tready), - .s_axis_tlast(tx_axis_tlast), - .s_axis_tid(0), - .s_axis_tdest(0), - .s_axis_tuser(tx_axis_tuser_in), - - /* - * AXI stream output - */ - .m_axis_tdata(tx_axis_tdata_int), - .m_axis_tkeep(), - .m_axis_tvalid(tx_axis_tvalid_int), - .m_axis_tready(tx_axis_tready_int), - .m_axis_tlast(tx_axis_tlast_int), - .m_axis_tid(), - .m_axis_tdest(), - .m_axis_tuser(tx_axis_tuser_int), - - /* - * MAC control frame interface - */ - .mcf_valid(tx_mcf_valid), - .mcf_ready(tx_mcf_ready), - .mcf_eth_dst(tx_mcf_eth_dst), - .mcf_eth_src(tx_mcf_eth_src), - .mcf_eth_type(tx_mcf_eth_type), - .mcf_opcode(tx_mcf_opcode), - .mcf_params(tx_mcf_params), - .mcf_id(0), - .mcf_dest(0), - .mcf_user(0), - - /* - * Pause interface - */ - .tx_pause_req(tx_pause_req_int), - .tx_pause_ack(tx_pause_ack), - - /* - * Status - */ - .stat_tx_mcf(stat_tx_mcf) - ); - - mac_ctrl_rx #( - .DATA_WIDTH(DATA_WIDTH), - .KEEP_ENABLE(0), - .ID_ENABLE(0), - .DEST_ENABLE(0), - .USER_ENABLE(1), - .USER_WIDTH(RX_USER_WIDTH), - .USE_READY(0), - .MCF_PARAMS_SIZE(MCF_PARAMS_SIZE) - ) - mac_ctrl_rx_inst ( - .clk(rx_clk), - .rst(rx_rst), - - /* - * AXI stream input - */ - .s_axis_tdata(rx_axis_tdata_int), - .s_axis_tkeep(1'b1), - .s_axis_tvalid(rx_axis_tvalid_int), - .s_axis_tready(), - .s_axis_tlast(rx_axis_tlast_int), - .s_axis_tid(0), - .s_axis_tdest(0), - .s_axis_tuser(rx_axis_tuser_int), - - /* - * AXI stream output - */ - .m_axis_tdata(rx_axis_tdata), - .m_axis_tkeep(), - .m_axis_tvalid(rx_axis_tvalid), - .m_axis_tready(1'b1), - .m_axis_tlast(rx_axis_tlast), - .m_axis_tid(), - .m_axis_tdest(), - .m_axis_tuser(rx_axis_tuser), - - /* - * MAC control frame interface - */ - .mcf_valid(rx_mcf_valid), - .mcf_eth_dst(rx_mcf_eth_dst), - .mcf_eth_src(rx_mcf_eth_src), - .mcf_eth_type(rx_mcf_eth_type), - .mcf_opcode(rx_mcf_opcode), - .mcf_params(rx_mcf_params), - .mcf_id(), - .mcf_dest(), - .mcf_user(), - - /* - * Configuration - */ - .cfg_mcf_rx_eth_dst_mcast(cfg_mcf_rx_eth_dst_mcast), - .cfg_mcf_rx_check_eth_dst_mcast(cfg_mcf_rx_check_eth_dst_mcast), - .cfg_mcf_rx_eth_dst_ucast(cfg_mcf_rx_eth_dst_ucast), - .cfg_mcf_rx_check_eth_dst_ucast(cfg_mcf_rx_check_eth_dst_ucast), - .cfg_mcf_rx_eth_src(cfg_mcf_rx_eth_src), - .cfg_mcf_rx_check_eth_src(cfg_mcf_rx_check_eth_src), - .cfg_mcf_rx_eth_type(cfg_mcf_rx_eth_type), - .cfg_mcf_rx_opcode_lfc(cfg_mcf_rx_opcode_lfc), - .cfg_mcf_rx_check_opcode_lfc(cfg_mcf_rx_check_opcode_lfc), - .cfg_mcf_rx_opcode_pfc(cfg_mcf_rx_opcode_pfc), - .cfg_mcf_rx_check_opcode_pfc(cfg_mcf_rx_check_opcode_pfc), - .cfg_mcf_rx_forward(cfg_mcf_rx_forward), - .cfg_mcf_rx_enable(cfg_mcf_rx_enable), - - /* - * Status - */ - .stat_rx_mcf(stat_rx_mcf) - ); - - mac_pause_ctrl_tx #( - .MCF_PARAMS_SIZE(MCF_PARAMS_SIZE), - .PFC_ENABLE(PFC_ENABLE) - ) - mac_pause_ctrl_tx_inst ( - .clk(tx_clk), - .rst(tx_rst), - - /* - * MAC control frame interface - */ - .mcf_valid(tx_mcf_valid), - .mcf_ready(tx_mcf_ready), - .mcf_eth_dst(tx_mcf_eth_dst), - .mcf_eth_src(tx_mcf_eth_src), - .mcf_eth_type(tx_mcf_eth_type), - .mcf_opcode(tx_mcf_opcode), - .mcf_params(tx_mcf_params), - - /* - * Pause (IEEE 802.3 annex 31B) - */ - .tx_lfc_req(tx_lfc_req), - .tx_lfc_resend(tx_lfc_resend), - - /* - * Priority Flow Control (PFC) (IEEE 802.3 annex 31D) - */ - .tx_pfc_req(tx_pfc_req), - .tx_pfc_resend(tx_pfc_resend), - - /* - * Configuration - */ - .cfg_tx_lfc_eth_dst(cfg_tx_lfc_eth_dst), - .cfg_tx_lfc_eth_src(cfg_tx_lfc_eth_src), - .cfg_tx_lfc_eth_type(cfg_tx_lfc_eth_type), - .cfg_tx_lfc_opcode(cfg_tx_lfc_opcode), - .cfg_tx_lfc_en(cfg_tx_lfc_en), - .cfg_tx_lfc_quanta(cfg_tx_lfc_quanta), - .cfg_tx_lfc_refresh(cfg_tx_lfc_refresh), - .cfg_tx_pfc_eth_dst(cfg_tx_pfc_eth_dst), - .cfg_tx_pfc_eth_src(cfg_tx_pfc_eth_src), - .cfg_tx_pfc_eth_type(cfg_tx_pfc_eth_type), - .cfg_tx_pfc_opcode(cfg_tx_pfc_opcode), - .cfg_tx_pfc_en(cfg_tx_pfc_en), - .cfg_tx_pfc_quanta(cfg_tx_pfc_quanta), - .cfg_tx_pfc_refresh(cfg_tx_pfc_refresh), - .cfg_quanta_step(tx_mii_select ? (4*256)/512 : (8*256)/512), - .cfg_quanta_clk_en(tx_clk_enable), - - /* - * Status - */ - .stat_tx_lfc_pkt(stat_tx_lfc_pkt), - .stat_tx_lfc_xon(stat_tx_lfc_xon), - .stat_tx_lfc_xoff(stat_tx_lfc_xoff), - .stat_tx_lfc_paused(stat_tx_lfc_paused), - .stat_tx_pfc_pkt(stat_tx_pfc_pkt), - .stat_tx_pfc_xon(stat_tx_pfc_xon), - .stat_tx_pfc_xoff(stat_tx_pfc_xoff), - .stat_tx_pfc_paused(stat_tx_pfc_paused) - ); - - mac_pause_ctrl_rx #( - .MCF_PARAMS_SIZE(18), - .PFC_ENABLE(PFC_ENABLE) - ) - mac_pause_ctrl_rx_inst ( - .clk(rx_clk), - .rst(rx_rst), - - /* - * MAC control frame interface - */ - .mcf_valid(rx_mcf_valid), - .mcf_eth_dst(rx_mcf_eth_dst), - .mcf_eth_src(rx_mcf_eth_src), - .mcf_eth_type(rx_mcf_eth_type), - .mcf_opcode(rx_mcf_opcode), - .mcf_params(rx_mcf_params), - - /* - * Pause (IEEE 802.3 annex 31B) - */ - .rx_lfc_en(rx_lfc_en), - .rx_lfc_req(rx_lfc_req), - .rx_lfc_ack(rx_lfc_ack_int), - - /* - * Priority Flow Control (PFC) (IEEE 802.3 annex 31D) - */ - .rx_pfc_en(rx_pfc_en), - .rx_pfc_req(rx_pfc_req), - .rx_pfc_ack(rx_pfc_ack), - - /* - * Configuration - */ - .cfg_rx_lfc_opcode(cfg_rx_lfc_opcode), - .cfg_rx_lfc_en(cfg_rx_lfc_en), - .cfg_rx_pfc_opcode(cfg_rx_pfc_opcode), - .cfg_rx_pfc_en(cfg_rx_pfc_en), - .cfg_quanta_step(rx_mii_select ? (4*256)/512 : (8*256)/512), - .cfg_quanta_clk_en(rx_clk_enable), - - /* - * Status - */ - .stat_rx_lfc_pkt(stat_rx_lfc_pkt), - .stat_rx_lfc_xon(stat_rx_lfc_xon), - .stat_rx_lfc_xoff(stat_rx_lfc_xoff), - .stat_rx_lfc_paused(stat_rx_lfc_paused), - .stat_rx_pfc_pkt(stat_rx_pfc_pkt), - .stat_rx_pfc_xon(stat_rx_pfc_xon), - .stat_rx_pfc_xoff(stat_rx_pfc_xoff), - .stat_rx_pfc_paused(stat_rx_pfc_paused) - ); - -end else begin - - assign tx_axis_tdata_int = tx_axis_tdata; - assign tx_axis_tvalid_int = tx_axis_tvalid; - assign tx_axis_tready = tx_axis_tready_int; - assign tx_axis_tlast_int = tx_axis_tlast; - assign tx_axis_tuser_int = tx_axis_tuser; - - assign rx_axis_tdata = rx_axis_tdata_int; - assign rx_axis_tvalid = rx_axis_tvalid_int; - assign rx_axis_tlast = rx_axis_tlast_int; - assign rx_axis_tuser = rx_axis_tuser_int; - - assign rx_lfc_req = 0; - assign rx_pfc_req = 0; - assign tx_pause_ack = 0; - - assign stat_tx_mcf = 0; - assign stat_rx_mcf = 0; - assign stat_tx_lfc_pkt = 0; - assign stat_tx_lfc_xon = 0; - assign stat_tx_lfc_xoff = 0; - assign stat_tx_lfc_paused = 0; - assign stat_tx_pfc_pkt = 0; - assign stat_tx_pfc_xon = 0; - assign stat_tx_pfc_xoff = 0; - assign stat_tx_pfc_paused = 0; - assign stat_rx_lfc_pkt = 0; - assign stat_rx_lfc_xon = 0; - assign stat_rx_lfc_xoff = 0; - assign stat_rx_lfc_paused = 0; - assign stat_rx_pfc_pkt = 0; - assign stat_rx_pfc_xon = 0; - assign stat_rx_pfc_xoff = 0; - assign stat_rx_pfc_paused = 0; - -end - -endgenerate - -endmodule - -`resetall diff --git a/src/rvvi/eth_mac_mii.sv b/src/rvvi/eth_mac_mii.sv deleted file mode 100644 index 212f4b84a..000000000 --- a/src/rvvi/eth_mac_mii.sv +++ /dev/null @@ -1,175 +0,0 @@ -/* - -Copyright (c) 2019 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * 10M/100M Ethernet MAC with MII interface - */ -module eth_mac_mii # -( - // target ("SIM", "GENERIC", "XILINX", "ALTERA") - parameter TARGET = "GENERIC", - // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") - // Use BUFR for Virtex-5, Virtex-6, 7-series - // Use BUFG for Ultrascale - // Use BUFIO2 for Spartan-6 - parameter CLOCK_INPUT_STYLE = "BUFIO2", - parameter ENABLE_PADDING = 1, - parameter MIN_FRAME_LENGTH = 64 -) -( - input wire rst, - output wire rx_clk, - output wire rx_rst, - output wire tx_clk, - output wire tx_rst, - - /* - * AXI input - */ - input wire [7:0] tx_axis_tdata, - input wire tx_axis_tvalid, - output wire tx_axis_tready, - input wire tx_axis_tlast, - input wire tx_axis_tuser, - - /* - * AXI output - */ - output wire [7:0] rx_axis_tdata, - output wire rx_axis_tvalid, - output wire rx_axis_tlast, - output wire rx_axis_tuser, - - /* - * MII interface - */ - input wire mii_rx_clk, - input wire [3:0] mii_rxd, - input wire mii_rx_dv, - input wire mii_rx_er, - input wire mii_tx_clk, - output wire [3:0] mii_txd, - output wire mii_tx_en, - output wire mii_tx_er, - - /* - * Status - */ - output wire tx_start_packet, - output wire tx_error_underflow, - output wire rx_start_packet, - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, - - /* - * Configuration - */ - input wire [7:0] cfg_ifg, - input wire cfg_tx_enable, - input wire cfg_rx_enable -); - -wire [3:0] mac_mii_rxd; -wire mac_mii_rx_dv; -wire mac_mii_rx_er; -wire [3:0] mac_mii_txd; -wire mac_mii_tx_en; -wire mac_mii_tx_er; - -mii_phy_if #( - .TARGET(TARGET), - .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE) -) -mii_phy_if_inst ( - .rst(rst), - - .mac_mii_rx_clk(rx_clk), - .mac_mii_rx_rst(rx_rst), - .mac_mii_rxd(mac_mii_rxd), - .mac_mii_rx_dv(mac_mii_rx_dv), - .mac_mii_rx_er(mac_mii_rx_er), - .mac_mii_tx_clk(tx_clk), - .mac_mii_tx_rst(tx_rst), - .mac_mii_txd(mac_mii_txd), - .mac_mii_tx_en(mac_mii_tx_en), - .mac_mii_tx_er(mac_mii_tx_er), - - .phy_mii_rx_clk(mii_rx_clk), - .phy_mii_rxd(mii_rxd), - .phy_mii_rx_dv(mii_rx_dv), - .phy_mii_rx_er(mii_rx_er), - .phy_mii_tx_clk(mii_tx_clk), - .phy_mii_txd(mii_txd), - .phy_mii_tx_en(mii_tx_en), - .phy_mii_tx_er(mii_tx_er) -); - // *** there a bunch of missing pins -/* verilator lint_off PINMISSING */ -eth_mac_1g #( - .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) -) -eth_mac_1g_inst ( - .tx_clk(tx_clk), - .tx_rst(tx_rst), - .rx_clk(rx_clk), - .rx_rst(rx_rst), - .tx_axis_tdata(tx_axis_tdata), - .tx_axis_tvalid(tx_axis_tvalid), - .tx_axis_tready(tx_axis_tready), - .tx_axis_tlast(tx_axis_tlast), - .tx_axis_tuser(tx_axis_tuser), - .rx_axis_tdata(rx_axis_tdata), - .rx_axis_tvalid(rx_axis_tvalid), - .rx_axis_tlast(rx_axis_tlast), - .rx_axis_tuser(rx_axis_tuser), - .gmii_rxd(mac_mii_rxd), - .gmii_rx_dv(mac_mii_rx_dv), - .gmii_rx_er(mac_mii_rx_er), - .gmii_txd(mac_mii_txd), - .gmii_tx_en(mac_mii_tx_en), - .gmii_tx_er(mac_mii_tx_er), - .rx_clk_enable(1'b1), - .tx_clk_enable(1'b1), - .rx_mii_select(1'b1), - .tx_mii_select(1'b1), - .tx_start_packet(tx_start_packet), - .tx_error_underflow(tx_error_underflow), - .rx_start_packet(rx_start_packet), - .rx_error_bad_frame(rx_error_bad_frame), - .rx_error_bad_fcs(rx_error_bad_fcs), - .cfg_ifg(cfg_ifg), - .cfg_tx_enable(cfg_tx_enable), - .cfg_rx_enable(cfg_rx_enable) -); -/* verilator lint_on PINMISSING */ - -endmodule - -`resetall diff --git a/src/rvvi/eth_mac_mii_fifo.sv b/src/rvvi/eth_mac_mii_fifo.sv deleted file mode 100644 index a285ceeed..000000000 --- a/src/rvvi/eth_mac_mii_fifo.sv +++ /dev/null @@ -1,339 +0,0 @@ -/* - -Copyright (c) 2019 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * 10M/100M Ethernet MAC with MII interface and TX and RX FIFOs - */ -module eth_mac_mii_fifo # -( - // target ("SIM", "GENERIC", "XILINX", "ALTERA") - parameter TARGET = "GENERIC", - // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") - // Use BUFR for Virtex-5, Virtex-6, 7-series - // Use BUFG for Ultrascale - // Use BUFIO2 for Spartan-6 - parameter CLOCK_INPUT_STYLE = "BUFIO2", - parameter AXIS_DATA_WIDTH = 8, - parameter AXIS_KEEP_ENABLE = (AXIS_DATA_WIDTH>8), - parameter AXIS_KEEP_WIDTH = (AXIS_DATA_WIDTH/8), - parameter ENABLE_PADDING = 1, - parameter MIN_FRAME_LENGTH = 64, - parameter TX_FIFO_DEPTH = 4096, - parameter TX_FIFO_RAM_PIPELINE = 1, - parameter TX_FRAME_FIFO = 1, - parameter TX_DROP_OVERSIZE_FRAME = TX_FRAME_FIFO, - parameter TX_DROP_BAD_FRAME = TX_DROP_OVERSIZE_FRAME, - parameter TX_DROP_WHEN_FULL = 0, - parameter RX_FIFO_DEPTH = 4096, - parameter RX_FIFO_RAM_PIPELINE = 1, - parameter RX_FRAME_FIFO = 1, - parameter RX_DROP_OVERSIZE_FRAME = RX_FRAME_FIFO, - parameter RX_DROP_BAD_FRAME = RX_DROP_OVERSIZE_FRAME, - parameter RX_DROP_WHEN_FULL = RX_DROP_OVERSIZE_FRAME -) -( - input wire rst, - input wire logic_clk, - input wire logic_rst, - - /* - * AXI input - */ - input wire [AXIS_DATA_WIDTH-1:0] tx_axis_tdata, - input wire [AXIS_KEEP_WIDTH-1:0] tx_axis_tkeep, - input wire tx_axis_tvalid, - output wire tx_axis_tready, - input wire tx_axis_tlast, - input wire tx_axis_tuser, - - /* - * AXI output - */ - output wire [AXIS_DATA_WIDTH-1:0] rx_axis_tdata, - output wire [AXIS_KEEP_WIDTH-1:0] rx_axis_tkeep, - output wire rx_axis_tvalid, - input wire rx_axis_tready, - output wire rx_axis_tlast, - output wire rx_axis_tuser, - - /* - * MII interface - */ - input wire mii_rx_clk, - input wire [3:0] mii_rxd, - input wire mii_rx_dv, - input wire mii_rx_er, - input wire mii_tx_clk, - output wire [3:0] mii_txd, - output wire mii_tx_en, - output wire mii_tx_er, - - /* - * Status - */ - output wire tx_error_underflow, - output wire tx_fifo_overflow, - output wire tx_fifo_bad_frame, - output wire tx_fifo_good_frame, - output wire rx_error_bad_frame, - output wire rx_error_bad_fcs, - output wire rx_fifo_overflow, - output wire rx_fifo_bad_frame, - output wire rx_fifo_good_frame, - - /* - * Configuration - */ - input wire [7:0] cfg_ifg, - input wire cfg_tx_enable, - input wire cfg_rx_enable -); - -wire tx_clk; -wire rx_clk; -wire tx_rst; -wire rx_rst; - -wire [7:0] tx_fifo_axis_tdata; -wire tx_fifo_axis_tvalid; -wire tx_fifo_axis_tready; -wire tx_fifo_axis_tlast; -wire tx_fifo_axis_tuser; - -wire [7:0] rx_fifo_axis_tdata; -wire rx_fifo_axis_tvalid; -wire rx_fifo_axis_tlast; -wire rx_fifo_axis_tuser; - -// synchronize MAC status signals into logic clock domain -wire tx_error_underflow_int; - -reg [0:0] tx_sync_reg_1 = 1'b0; -reg [0:0] tx_sync_reg_2 = 1'b0; -reg [0:0] tx_sync_reg_3 = 1'b0; -reg [0:0] tx_sync_reg_4 = 1'b0; - -assign tx_error_underflow = tx_sync_reg_3[0] ^ tx_sync_reg_4[0]; - -always @(posedge tx_clk or posedge tx_rst) begin - if (tx_rst) begin - tx_sync_reg_1 <= 1'b0; - end else begin - tx_sync_reg_1 <= tx_sync_reg_1 ^ {tx_error_underflow_int}; - end -end - -always @(posedge logic_clk or posedge logic_rst) begin - if (logic_rst) begin - tx_sync_reg_2 <= 1'b0; - tx_sync_reg_3 <= 1'b0; - tx_sync_reg_4 <= 1'b0; - end else begin - tx_sync_reg_2 <= tx_sync_reg_1; - tx_sync_reg_3 <= tx_sync_reg_2; - tx_sync_reg_4 <= tx_sync_reg_3; - end -end - -wire rx_error_bad_frame_int; -wire rx_error_bad_fcs_int; - -reg [1:0] rx_sync_reg_1 = 2'd0; -reg [1:0] rx_sync_reg_2 = 2'd0; -reg [1:0] rx_sync_reg_3 = 2'd0; -reg [1:0] rx_sync_reg_4 = 2'd0; - -assign rx_error_bad_frame = rx_sync_reg_3[0] ^ rx_sync_reg_4[0]; -assign rx_error_bad_fcs = rx_sync_reg_3[1] ^ rx_sync_reg_4[1]; - -always @(posedge rx_clk or posedge rx_rst) begin - if (rx_rst) begin - rx_sync_reg_1 <= 2'd0; - end else begin - rx_sync_reg_1 <= rx_sync_reg_1 ^ {rx_error_bad_fcs_int, rx_error_bad_frame_int}; - end -end - -always @(posedge logic_clk or posedge logic_rst) begin - if (logic_rst) begin - rx_sync_reg_2 <= 2'd0; - rx_sync_reg_3 <= 2'd0; - rx_sync_reg_4 <= 2'd0; - end else begin - rx_sync_reg_2 <= rx_sync_reg_1; - rx_sync_reg_3 <= rx_sync_reg_2; - rx_sync_reg_4 <= rx_sync_reg_3; - end -end - - // *** there are a bunch of missing pins - /* verilator lint_off PINMISSING */ -eth_mac_mii #( - .TARGET(TARGET), - .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), - .ENABLE_PADDING(ENABLE_PADDING), - .MIN_FRAME_LENGTH(MIN_FRAME_LENGTH) -) -eth_mac_1g_mii_inst ( - .rst(rst), - .tx_clk(tx_clk), - .tx_rst(tx_rst), - .rx_clk(rx_clk), - .rx_rst(rx_rst), - .tx_axis_tdata(tx_fifo_axis_tdata), - .tx_axis_tvalid(tx_fifo_axis_tvalid), - .tx_axis_tready(tx_fifo_axis_tready), - .tx_axis_tlast(tx_fifo_axis_tlast), - .tx_axis_tuser(tx_fifo_axis_tuser), - .rx_axis_tdata(rx_fifo_axis_tdata), - .rx_axis_tvalid(rx_fifo_axis_tvalid), - .rx_axis_tlast(rx_fifo_axis_tlast), - .rx_axis_tuser(rx_fifo_axis_tuser), - .mii_rx_clk(mii_rx_clk), - .mii_rxd(mii_rxd), - .mii_rx_dv(mii_rx_dv), - .mii_rx_er(mii_rx_er), - .mii_tx_clk(mii_tx_clk), - .mii_txd(mii_txd), - .mii_tx_en(mii_tx_en), - .mii_tx_er(mii_tx_er), - .tx_error_underflow(tx_error_underflow_int), - .rx_error_bad_frame(rx_error_bad_frame_int), - .rx_error_bad_fcs(rx_error_bad_fcs_int), - .cfg_ifg(cfg_ifg), - .cfg_tx_enable(cfg_tx_enable), - .cfg_rx_enable(cfg_rx_enable) -); - -axis_async_fifo_adapter #( - .DEPTH(TX_FIFO_DEPTH), - .S_DATA_WIDTH(AXIS_DATA_WIDTH), - .S_KEEP_ENABLE(AXIS_KEEP_ENABLE), - .S_KEEP_WIDTH(AXIS_KEEP_WIDTH), - .M_DATA_WIDTH(8), - .M_KEEP_ENABLE(0), - .ID_ENABLE(0), - .DEST_ENABLE(0), - .USER_ENABLE(1), - .USER_WIDTH(1), - .RAM_PIPELINE(TX_FIFO_RAM_PIPELINE), - .FRAME_FIFO(TX_FRAME_FIFO), - .USER_BAD_FRAME_VALUE(1'b1), - .USER_BAD_FRAME_MASK(1'b1), - .DROP_OVERSIZE_FRAME(TX_DROP_OVERSIZE_FRAME), - .DROP_BAD_FRAME(TX_DROP_BAD_FRAME), - .DROP_WHEN_FULL(TX_DROP_WHEN_FULL) -) -tx_fifo ( - // AXI input - .s_clk(logic_clk), - .s_rst(logic_rst), - .s_axis_tdata(tx_axis_tdata), - .s_axis_tkeep(tx_axis_tkeep), - .s_axis_tvalid(tx_axis_tvalid), - .s_axis_tready(tx_axis_tready), - .s_axis_tlast(tx_axis_tlast), - .s_axis_tid(0), - .s_axis_tdest(0), - .s_axis_tuser(tx_axis_tuser), - // AXI output - .m_clk(tx_clk), - .m_rst(tx_rst), - .m_axis_tdata(tx_fifo_axis_tdata), - .m_axis_tkeep(), - .m_axis_tvalid(tx_fifo_axis_tvalid), - .m_axis_tready(tx_fifo_axis_tready), - .m_axis_tlast(tx_fifo_axis_tlast), - .m_axis_tid(), - .m_axis_tdest(), - .m_axis_tuser(tx_fifo_axis_tuser), - // Status - .s_status_overflow(tx_fifo_overflow), - .s_status_bad_frame(tx_fifo_bad_frame), - .s_status_good_frame(tx_fifo_good_frame), - .m_status_overflow(), - .m_status_bad_frame(), - .m_status_good_frame() -); - -axis_async_fifo_adapter #( - .DEPTH(RX_FIFO_DEPTH), - .S_DATA_WIDTH(8), - .S_KEEP_ENABLE(0), - .M_DATA_WIDTH(AXIS_DATA_WIDTH), - .M_KEEP_ENABLE(AXIS_KEEP_ENABLE), - .M_KEEP_WIDTH(AXIS_KEEP_WIDTH), - .ID_ENABLE(0), - .DEST_ENABLE(0), - .USER_ENABLE(1), - .USER_WIDTH(1), - .RAM_PIPELINE(RX_FIFO_RAM_PIPELINE), - .FRAME_FIFO(RX_FRAME_FIFO), - .USER_BAD_FRAME_VALUE(1'b1), - .USER_BAD_FRAME_MASK(1'b1), - .DROP_OVERSIZE_FRAME(RX_DROP_OVERSIZE_FRAME), - .DROP_BAD_FRAME(RX_DROP_BAD_FRAME), - .DROP_WHEN_FULL(RX_DROP_WHEN_FULL) -) -rx_fifo ( - // AXI input - .s_clk(rx_clk), - .s_rst(rx_rst), - .s_axis_tdata(rx_fifo_axis_tdata), - .s_axis_tkeep(0), - .s_axis_tvalid(rx_fifo_axis_tvalid), - .s_axis_tready(), - .s_axis_tlast(rx_fifo_axis_tlast), - .s_axis_tid(0), - .s_axis_tdest(0), - .s_axis_tuser(rx_fifo_axis_tuser), - // AXI output - .m_clk(logic_clk), - .m_rst(logic_rst), - .m_axis_tdata(rx_axis_tdata), - .m_axis_tkeep(rx_axis_tkeep), - .m_axis_tvalid(rx_axis_tvalid), - .m_axis_tready(rx_axis_tready), - .m_axis_tlast(rx_axis_tlast), - .m_axis_tid(), - .m_axis_tdest(), - .m_axis_tuser(rx_axis_tuser), - // Status - .s_status_overflow(), - .s_status_bad_frame(), - .s_status_good_frame(), - .m_status_overflow(rx_fifo_overflow), - .m_status_bad_frame(rx_fifo_bad_frame), - .m_status_good_frame(rx_fifo_good_frame) -); -/* verilator lint_on PINMISSING */ - -endmodule - -`resetall diff --git a/src/rvvi/lfsr.sv b/src/rvvi/lfsr.sv deleted file mode 100644 index 4b404fe94..000000000 --- a/src/rvvi/lfsr.sv +++ /dev/null @@ -1,446 +0,0 @@ -/* - -Copyright (c) 2016-2023 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * Parametrizable combinatorial parallel LFSR/CRC - */ -module lfsr # -( - // width of LFSR - parameter LFSR_WIDTH = 31, - // LFSR polynomial - parameter LFSR_POLY = 31'h10000001, - // LFSR configuration: "GALOIS", "FIBONACCI" - parameter LFSR_CONFIG = "FIBONACCI", - // LFSR feed forward enable - parameter LFSR_FEED_FORWARD = 0, - // bit-reverse input and output - parameter REVERSE = 0, - // width of data input - parameter DATA_WIDTH = 8, - // implementation style: "AUTO", "LOOP", "REDUCTION" - parameter STYLE = "AUTO" -) -( - input wire [DATA_WIDTH-1:0] data_in, - input wire [LFSR_WIDTH-1:0] state_in, - output wire [DATA_WIDTH-1:0] data_out, - output wire [LFSR_WIDTH-1:0] state_out -); - -/* - -Fully parametrizable combinatorial parallel LFSR/CRC module. Implements an unrolled LFSR -next state computation, shifting DATA_WIDTH bits per pass through the module. Input data -is XORed with LFSR feedback path, tie data_in to zero if this is not required. - -Works in two parts: statically computes a set of bit masks, then uses these bit masks to -select bits for XORing to compute the next state. - -Ports: - -data_in - -Data bits to be shifted through the LFSR (DATA_WIDTH bits) - -state_in - -LFSR/CRC current state input (LFSR_WIDTH bits) - -data_out - -Data bits shifted out of LFSR (DATA_WIDTH bits) - -state_out - -LFSR/CRC next state output (LFSR_WIDTH bits) - -Parameters: - -LFSR_WIDTH - -Specify width of LFSR/CRC register - -LFSR_POLY - -Specify the LFSR/CRC polynomial in hex format. For example, the polynomial - -x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 - -would be represented as - -32'h04c11db7 - -Note that the largest term (x^32) is suppressed. This term is generated automatically based -on LFSR_WIDTH. - -LFSR_CONFIG - -Specify the LFSR configuration, either Fibonacci or Galois. Fibonacci is generally used -for linear-feedback shift registers (LFSR) for pseudorandom binary sequence (PRBS) generators, -scramblers, and descrambers, while Galois is generally used for cyclic redundancy check -generators and checkers. - -Fibonacci style (example for 64b66b scrambler, 0x8000000001) - - DIN (LSB first) - | - V - (+)<---------------------------(+)<-----------------------------. - | ^ | - | .----. .----. .----. | .----. .----. .----. | - +->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--' - | '----' '----' '----' '----' '----' '----' - V - DOUT - -Galois style (example for CRC16, 0x8005) - - ,-------------------+-------------------------+----------(+)<-- DIN (MSB first) - | | | ^ - | .----. .----. V .----. .----. V .----. | - `->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |--+---> DOUT - '----' '----' '----' '----' '----' - -LFSR_FEED_FORWARD - -Generate feed forward instead of feed back LFSR. Enable this for PRBS checking and self- -synchronous descrambling. - -Fibonacci feed-forward style (example for 64b66b descrambler, 0x8000000001) - - DIN (LSB first) - | - | .----. .----. .----. .----. .----. .----. - +->| 0 |->| 1 |->...->| 38 |-+->| 39 |->...->| 56 |->| 57 |--. - | '----' '----' '----' | '----' '----' '----' | - | V | - (+)<---------------------------(+)------------------------------' - | - V - DOUT - -Galois feed-forward style - - ,-------------------+-------------------------+------------+--- DIN (MSB first) - | | | | - | .----. .----. V .----. .----. V .----. V - `->| 0 |->| 1 |->(+)->| 2 |->...->| 14 |->(+)->| 15 |->(+)-> DOUT - '----' '----' '----' '----' '----' - -REVERSE - -Bit-reverse LFSR input and output. Shifts MSB first by default, set REVERSE for LSB first. - -DATA_WIDTH - -Specify width of input and output data bus. The module will perform one shift per input -data bit, so if the input data bus is not required tie data_in to zero and set DATA_WIDTH -to the required number of shifts per clock cycle. - -STYLE - -Specify implementation style. Can be "AUTO", "LOOP", or "REDUCTION". When "AUTO" -is selected, implemenation will be "LOOP" or "REDUCTION" based on synthesis translate -directives. "REDUCTION" and "LOOP" are functionally identical, however they simulate -and synthesize differently. "REDUCTION" is implemented with a loop over a Verilog -reduction operator. "LOOP" is implemented as a doubly-nested loop with no reduction -operator. "REDUCTION" is very fast for simulation in iverilog and synthesizes well in -Quartus but synthesizes poorly in ISE, likely due to large inferred XOR gates causing -problems with the optimizer. "LOOP" synthesizes will in both ISE and Quartus. "AUTO" -will default to "REDUCTION" when simulating and "LOOP" for synthesizers that obey -synthesis translate directives. - -Settings for common LFSR/CRC implementations: - -Name Configuration Length Polynomial Initial value Notes -CRC16-IBM Galois, bit-reverse 16 16'h8005 16'hffff -CRC16-CCITT Galois 16 16'h1021 16'h1d0f -CRC32 Galois, bit-reverse 32 32'h04c11db7 32'hffffffff Ethernet FCS; invert final output -CRC32C Galois, bit-reverse 32 32'h1edc6f41 32'hffffffff iSCSI, Intel CRC32 instruction; invert final output -PRBS6 Fibonacci 6 6'h21 any -PRBS7 Fibonacci 7 7'h41 any -PRBS9 Fibonacci 9 9'h021 any ITU V.52 -PRBS10 Fibonacci 10 10'h081 any ITU -PRBS11 Fibonacci 11 11'h201 any ITU O.152 -PRBS15 Fibonacci, inverted 15 15'h4001 any ITU O.152 -PRBS17 Fibonacci 17 17'h04001 any -PRBS20 Fibonacci 20 20'h00009 any ITU V.57 -PRBS23 Fibonacci, inverted 23 23'h040001 any ITU O.151 -PRBS29 Fibonacci, inverted 29 29'h08000001 any -PRBS31 Fibonacci, inverted 31 31'h10000001 any -64b66b Fibonacci, bit-reverse 58 58'h8000000001 any 10G Ethernet -128b130b Galois, bit-reverse 23 23'h210125 any PCIe gen 3 - -*/ - -function [LFSR_WIDTH+DATA_WIDTH-1:0] lfsr_mask(input [31:0] index); - reg [LFSR_WIDTH-1:0] lfsr_mask_state[LFSR_WIDTH-1:0]; - reg [DATA_WIDTH-1:0] lfsr_mask_data[LFSR_WIDTH-1:0]; - reg [LFSR_WIDTH-1:0] output_mask_state[DATA_WIDTH-1:0]; - reg [DATA_WIDTH-1:0] output_mask_data[DATA_WIDTH-1:0]; - - reg [LFSR_WIDTH-1:0] state_val; - reg [DATA_WIDTH-1:0] data_val; - - reg [DATA_WIDTH-1:0] data_mask; - - integer i, j; - - begin - // init bit masks - for (i = 0; i < LFSR_WIDTH; i = i + 1) begin - lfsr_mask_state[i] = 0; - lfsr_mask_state[i][i] = 1'b1; - lfsr_mask_data[i] = 0; - end - for (i = 0; i < DATA_WIDTH; i = i + 1) begin - output_mask_state[i] = 0; - if (i < LFSR_WIDTH) begin - output_mask_state[i][i] = 1'b1; - end - output_mask_data[i] = 0; - end - - // simulate shift register - if (LFSR_CONFIG == "FIBONACCI") begin - // Fibonacci configuration - for (data_mask = {1'b1, {DATA_WIDTH-1{1'b0}}}; data_mask != 0; data_mask = data_mask >> 1) begin - // determine shift in value - // current value in last FF, XOR with input data bit (MSB first) - state_val = lfsr_mask_state[LFSR_WIDTH-1]; - data_val = lfsr_mask_data[LFSR_WIDTH-1]; - data_val = data_val ^ data_mask; - - // add XOR inputs from correct indicies - for (j = 1; j < LFSR_WIDTH; j = j + 1) begin - if ((LFSR_POLY >> j) & 1) begin - state_val = lfsr_mask_state[j-1] ^ state_val; - data_val = lfsr_mask_data[j-1] ^ data_val; - end - end - - // shift - for (j = LFSR_WIDTH-1; j > 0; j = j - 1) begin - lfsr_mask_state[j] = lfsr_mask_state[j-1]; - lfsr_mask_data[j] = lfsr_mask_data[j-1]; - end - for (j = DATA_WIDTH-1; j > 0; j = j - 1) begin - output_mask_state[j] = output_mask_state[j-1]; - output_mask_data[j] = output_mask_data[j-1]; - end - output_mask_state[0] = state_val; - output_mask_data[0] = data_val; - if (LFSR_FEED_FORWARD) begin - // only shift in new input data - state_val = {LFSR_WIDTH{1'b0}}; - data_val = data_mask; - end - lfsr_mask_state[0] = state_val; - lfsr_mask_data[0] = data_val; - end - end else if (LFSR_CONFIG == "GALOIS") begin - // Galois configuration - for (data_mask = {1'b1, {DATA_WIDTH-1{1'b0}}}; data_mask != 0; data_mask = data_mask >> 1) begin - // determine shift in value - // current value in last FF, XOR with input data bit (MSB first) - state_val = lfsr_mask_state[LFSR_WIDTH-1]; - data_val = lfsr_mask_data[LFSR_WIDTH-1]; - data_val = data_val ^ data_mask; - - // shift - for (j = LFSR_WIDTH-1; j > 0; j = j - 1) begin - lfsr_mask_state[j] = lfsr_mask_state[j-1]; - lfsr_mask_data[j] = lfsr_mask_data[j-1]; - end - for (j = DATA_WIDTH-1; j > 0; j = j - 1) begin - output_mask_state[j] = output_mask_state[j-1]; - output_mask_data[j] = output_mask_data[j-1]; - end - output_mask_state[0] = state_val; - output_mask_data[0] = data_val; - if (LFSR_FEED_FORWARD) begin - // only shift in new input data - state_val = {LFSR_WIDTH{1'b0}}; - data_val = data_mask; - end - lfsr_mask_state[0] = state_val; - lfsr_mask_data[0] = data_val; - - // add XOR inputs at correct indicies - for (j = 1; j < LFSR_WIDTH; j = j + 1) begin - if ((LFSR_POLY >> j) & 1) begin - lfsr_mask_state[j] = lfsr_mask_state[j] ^ state_val; - lfsr_mask_data[j] = lfsr_mask_data[j] ^ data_val; - end - end - end - end else begin - $error("Error: unknown configuration setting!"); - $finish; - end - - // reverse bits if selected - if (REVERSE) begin - if (index < LFSR_WIDTH) begin - state_val = 0; - for (i = 0; i < LFSR_WIDTH; i = i + 1) begin - state_val[i] = lfsr_mask_state[LFSR_WIDTH-index-1][LFSR_WIDTH-i-1]; - end - - data_val = 0; - for (i = 0; i < DATA_WIDTH; i = i + 1) begin - data_val[i] = lfsr_mask_data[LFSR_WIDTH-index-1][DATA_WIDTH-i-1]; - end - end else begin - state_val = 0; - for (i = 0; i < LFSR_WIDTH; i = i + 1) begin - state_val[i] = output_mask_state[DATA_WIDTH-(index-LFSR_WIDTH)-1][LFSR_WIDTH-i-1]; - end - - data_val = 0; - for (i = 0; i < DATA_WIDTH; i = i + 1) begin - data_val[i] = output_mask_data[DATA_WIDTH-(index-LFSR_WIDTH)-1][DATA_WIDTH-i-1]; - end - end - end else begin - if (index < LFSR_WIDTH) begin - state_val = lfsr_mask_state[index]; - data_val = lfsr_mask_data[index]; - end else begin - state_val = output_mask_state[index-LFSR_WIDTH]; - data_val = output_mask_data[index-LFSR_WIDTH]; - end - end - lfsr_mask = {data_val, state_val}; - end -endfunction - -// synthesis translate_off -`define SIMULATION -// synthesis translate_on - -`ifdef SIMULATION -// "AUTO" style is "REDUCTION" for faster simulation -parameter STYLE_INT = (STYLE == "AUTO") ? "REDUCTION" : STYLE; -`else -// "AUTO" style is "LOOP" for better synthesis result -parameter STYLE_INT = (STYLE == "AUTO") ? "LOOP" : STYLE; -`endif - -genvar n; - -generate - -if (STYLE_INT == "REDUCTION") begin - - // use Verilog reduction operator - // fast in iverilog - // significantly larger than generated code with ISE (inferred wide XORs may be tripping up optimizer) - // slightly smaller than generated code with Quartus - // --> better for simulation - - for (n = 0; n < LFSR_WIDTH; n = n + 1) begin : lfsr_state - wire [LFSR_WIDTH+DATA_WIDTH-1:0] mask = lfsr_mask(n); - assign state_out[n] = ^({data_in, state_in} & mask); - end - for (n = 0; n < DATA_WIDTH; n = n + 1) begin : lfsr_data - wire [LFSR_WIDTH+DATA_WIDTH-1:0] mask = lfsr_mask(n+LFSR_WIDTH); - assign data_out[n] = ^({data_in, state_in} & mask); - end - -end else if (STYLE_INT == "LOOP") begin - - // use nested loops - // very slow in iverilog - // slightly smaller than generated code with ISE - // same size as generated code with Quartus - // --> better for synthesis - - for (n = 0; n < LFSR_WIDTH; n = n + 1) begin : lfsr_state - wire [LFSR_WIDTH+DATA_WIDTH-1:0] mask = lfsr_mask(n); - - reg state_reg; - - assign state_out[n] = state_reg; - - integer i; - - always @* begin - state_reg = 1'b0; - for (i = 0; i < LFSR_WIDTH; i = i + 1) begin - if (mask[i]) begin - state_reg = state_reg ^ state_in[i]; - end - end - for (i = 0; i < DATA_WIDTH; i = i + 1) begin - if (mask[i+LFSR_WIDTH]) begin - state_reg = state_reg ^ data_in[i]; - end - end - end - end - for (n = 0; n < DATA_WIDTH; n = n + 1) begin : lfsr_data - wire [LFSR_WIDTH+DATA_WIDTH-1:0] mask = lfsr_mask(n+LFSR_WIDTH); - - reg data_reg; - - assign data_out[n] = data_reg; - - integer i; - - always @* begin - data_reg = 1'b0; - for (i = 0; i < LFSR_WIDTH; i = i + 1) begin - if (mask[i]) begin - data_reg = data_reg ^ state_in[i]; - end - end - for (i = 0; i < DATA_WIDTH; i = i + 1) begin - if (mask[i+LFSR_WIDTH]) begin - data_reg = data_reg ^ data_in[i]; - end - end - end - end - -end else begin - - initial begin - $error("Error: unknown style setting!"); - $finish; - end - -end - -endgenerate - -endmodule - -`resetall diff --git a/src/rvvi/mac_ctrl_rx.sv b/src/rvvi/mac_ctrl_rx.sv deleted file mode 100644 index f7171887b..000000000 --- a/src/rvvi/mac_ctrl_rx.sv +++ /dev/null @@ -1,447 +0,0 @@ -/* - -Copyright (c) 2023 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * MAC control receive - */ -module mac_ctrl_rx # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = DATA_WIDTH>8, - parameter KEEP_WIDTH = DATA_WIDTH/8, - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1, - parameter USE_READY = 0, - parameter MCF_PARAMS_SIZE = 18 -) -( - input wire clk, - input wire rst, - - /* - * AXI stream input - */ - input wire [DATA_WIDTH-1:0] s_axis_tdata, - input wire [KEEP_WIDTH-1:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire [ID_WIDTH-1:0] s_axis_tid, - input wire [DEST_WIDTH-1:0] s_axis_tdest, - input wire [USER_WIDTH-1:0] s_axis_tuser, - - /* - * AXI stream output - */ - output wire [DATA_WIDTH-1:0] m_axis_tdata, - output wire [KEEP_WIDTH-1:0] m_axis_tkeep, - output wire m_axis_tvalid, - input wire m_axis_tready, - output wire m_axis_tlast, - output wire [ID_WIDTH-1:0] m_axis_tid, - output wire [DEST_WIDTH-1:0] m_axis_tdest, - output wire [USER_WIDTH-1:0] m_axis_tuser, - - /* - * MAC control frame interface - */ - output wire mcf_valid, - output wire [47:0] mcf_eth_dst, - output wire [47:0] mcf_eth_src, - output wire [15:0] mcf_eth_type, - output wire [15:0] mcf_opcode, - output wire [MCF_PARAMS_SIZE*8-1:0] mcf_params, - output wire [ID_WIDTH-1:0] mcf_id, - output wire [DEST_WIDTH-1:0] mcf_dest, - output wire [USER_WIDTH-1:0] mcf_user, - - /* - * Configuration - */ - input wire [47:0] cfg_mcf_rx_eth_dst_mcast, - input wire cfg_mcf_rx_check_eth_dst_mcast, - input wire [47:0] cfg_mcf_rx_eth_dst_ucast, - input wire cfg_mcf_rx_check_eth_dst_ucast, - input wire [47:0] cfg_mcf_rx_eth_src, - input wire cfg_mcf_rx_check_eth_src, - input wire [15:0] cfg_mcf_rx_eth_type, - input wire [15:0] cfg_mcf_rx_opcode_lfc, - input wire cfg_mcf_rx_check_opcode_lfc, - input wire [15:0] cfg_mcf_rx_opcode_pfc, - input wire cfg_mcf_rx_check_opcode_pfc, - input wire cfg_mcf_rx_forward, - input wire cfg_mcf_rx_enable, - - /* - * Status - */ - output wire stat_rx_mcf -); - -parameter BYTE_LANES = KEEP_ENABLE ? KEEP_WIDTH : 1; - -parameter HDR_SIZE = 60; - -parameter CYCLE_COUNT = (HDR_SIZE+BYTE_LANES-1)/BYTE_LANES; - -parameter PTR_WIDTH = $clog2(CYCLE_COUNT); - -parameter OFFSET = HDR_SIZE % BYTE_LANES; - -// check configuration -initial begin - if (BYTE_LANES * 8 != DATA_WIDTH) begin - $error("Error: AXI stream interface requires byte (8-bit) granularity (instance %m)"); - $finish; - end - - if (MCF_PARAMS_SIZE > 44) begin - $error("Error: Maximum MCF_PARAMS_SIZE is 44 bytes (instance %m)"); - $finish; - end -end - -/* - -MAC control frame - - Field Length - Destination MAC address 6 octets [01:80:C2:00:00:01] - Source MAC address 6 octets - Ethertype 2 octets [0x8808] - Opcode 2 octets - Parameters 0-44 octets - -This module manages the reception of MAC control frames. Incoming frames are -checked based on the ethertype and (optionally) MAC addresses. Matching control -frames are marked by setting tuser[0] on the data output and forwarded through -a separate interface for processing. - -*/ - -reg read_mcf_reg = 1'b1, read_mcf_next; -reg mcf_frame_reg = 1'b0, mcf_frame_next; -reg [PTR_WIDTH-1:0] ptr_reg = 0, ptr_next; - -reg s_axis_tready_reg = 1'b0, s_axis_tready_next; - -// internal datapath -reg [DATA_WIDTH-1:0] m_axis_tdata_int; -reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; -reg m_axis_tvalid_int; -reg m_axis_tready_int_reg = 1'b0; -reg m_axis_tlast_int; -reg [ID_WIDTH-1:0] m_axis_tid_int; -reg [DEST_WIDTH-1:0] m_axis_tdest_int; -reg [USER_WIDTH-1:0] m_axis_tuser_int; -wire m_axis_tready_int_early; - -reg mcf_valid_reg = 0, mcf_valid_next; -reg [47:0] mcf_eth_dst_reg = 0, mcf_eth_dst_next; -reg [47:0] mcf_eth_src_reg = 0, mcf_eth_src_next; -reg [15:0] mcf_eth_type_reg = 0, mcf_eth_type_next; -reg [15:0] mcf_opcode_reg = 0, mcf_opcode_next; -reg [MCF_PARAMS_SIZE*8-1:0] mcf_params_reg = 0, mcf_params_next; -reg [ID_WIDTH-1:0] mcf_id_reg = 0, mcf_id_next; -reg [DEST_WIDTH-1:0] mcf_dest_reg = 0, mcf_dest_next; -reg [USER_WIDTH-1:0] mcf_user_reg = 0, mcf_user_next; - -reg stat_rx_mcf_reg = 1'b0, stat_rx_mcf_next; - -assign s_axis_tready = s_axis_tready_reg; - -assign mcf_valid = mcf_valid_reg; -assign mcf_eth_dst = mcf_eth_dst_reg; -assign mcf_eth_src = mcf_eth_src_reg; -assign mcf_eth_type = mcf_eth_type_reg; -assign mcf_opcode = mcf_opcode_reg; -assign mcf_params = mcf_params_reg; -assign mcf_id = mcf_id_reg; -assign mcf_dest = mcf_dest_reg; -assign mcf_user = mcf_user_reg; - -assign stat_rx_mcf = stat_rx_mcf_reg; - -wire mcf_eth_dst_mcast_match = mcf_eth_dst_next == cfg_mcf_rx_eth_dst_mcast; -wire mcf_eth_dst_ucast_match = mcf_eth_dst_next == cfg_mcf_rx_eth_dst_ucast; -wire mcf_eth_src_match = mcf_eth_src_next == cfg_mcf_rx_eth_src; -wire mcf_eth_type_match = mcf_eth_type_next == cfg_mcf_rx_eth_type; -wire mcf_opcode_lfc_match = mcf_opcode_next == cfg_mcf_rx_opcode_lfc; -wire mcf_opcode_pfc_match = mcf_opcode_next == cfg_mcf_rx_opcode_pfc; - -wire mcf_eth_dst_match = ((mcf_eth_dst_mcast_match && cfg_mcf_rx_check_eth_dst_mcast) || - (mcf_eth_dst_ucast_match && cfg_mcf_rx_check_eth_dst_ucast) || - (!cfg_mcf_rx_check_eth_dst_mcast && !cfg_mcf_rx_check_eth_dst_ucast)); - -wire mcf_opcode_match = ((mcf_opcode_lfc_match && cfg_mcf_rx_check_opcode_lfc) || - (mcf_opcode_pfc_match && cfg_mcf_rx_check_opcode_pfc) || - (!cfg_mcf_rx_check_opcode_lfc && !cfg_mcf_rx_check_opcode_pfc)); - -wire mcf_match = (mcf_eth_dst_match && - (mcf_eth_src_match || !cfg_mcf_rx_check_eth_src) && - mcf_eth_type_match && mcf_opcode_match); - -integer k; - -always @* begin - read_mcf_next = read_mcf_reg; - mcf_frame_next = mcf_frame_reg; - ptr_next = ptr_reg; - - // pass through data - m_axis_tdata_int = s_axis_tdata; - m_axis_tkeep_int = s_axis_tkeep; - m_axis_tvalid_int = s_axis_tvalid; - m_axis_tlast_int = s_axis_tlast; - m_axis_tid_int = s_axis_tid; - m_axis_tdest_int = s_axis_tdest; - m_axis_tuser_int = s_axis_tuser; - - s_axis_tready_next = m_axis_tready_int_early || !USE_READY; - - mcf_valid_next = 1'b0; - mcf_eth_dst_next = mcf_eth_dst_reg; - mcf_eth_src_next = mcf_eth_src_reg; - mcf_eth_type_next = mcf_eth_type_reg; - mcf_opcode_next = mcf_opcode_reg; - mcf_params_next = mcf_params_reg; - mcf_id_next = mcf_id_reg; - mcf_dest_next = mcf_dest_reg; - mcf_user_next = mcf_user_reg; - - stat_rx_mcf_next = 1'b0; - - if ((s_axis_tready || !USE_READY) && s_axis_tvalid) begin - if (read_mcf_reg) begin - ptr_next = ptr_reg + 1; - - mcf_id_next = s_axis_tid; - mcf_dest_next = s_axis_tdest; - mcf_user_next = s_axis_tuser; - - `define _HEADER_FIELD_(offset, field) \ - if (ptr_reg == offset/BYTE_LANES) begin \ - field = s_axis_tdata[(offset%BYTE_LANES)*8 +: 8]; \ - end - - `_HEADER_FIELD_(0, mcf_eth_dst_next[5*8 +: 8]) - `_HEADER_FIELD_(1, mcf_eth_dst_next[4*8 +: 8]) - `_HEADER_FIELD_(2, mcf_eth_dst_next[3*8 +: 8]) - `_HEADER_FIELD_(3, mcf_eth_dst_next[2*8 +: 8]) - `_HEADER_FIELD_(4, mcf_eth_dst_next[1*8 +: 8]) - `_HEADER_FIELD_(5, mcf_eth_dst_next[0*8 +: 8]) - `_HEADER_FIELD_(6, mcf_eth_src_next[5*8 +: 8]) - `_HEADER_FIELD_(7, mcf_eth_src_next[4*8 +: 8]) - `_HEADER_FIELD_(8, mcf_eth_src_next[3*8 +: 8]) - `_HEADER_FIELD_(9, mcf_eth_src_next[2*8 +: 8]) - `_HEADER_FIELD_(10, mcf_eth_src_next[1*8 +: 8]) - `_HEADER_FIELD_(11, mcf_eth_src_next[0*8 +: 8]) - `_HEADER_FIELD_(12, mcf_eth_type_next[1*8 +: 8]) - `_HEADER_FIELD_(13, mcf_eth_type_next[0*8 +: 8]) - `_HEADER_FIELD_(14, mcf_opcode_next[1*8 +: 8]) - `_HEADER_FIELD_(15, mcf_opcode_next[0*8 +: 8]) - - if (ptr_reg == 0/BYTE_LANES) begin - // ensure params field gets cleared - mcf_params_next = 0; - end - - for (k = 0; k < MCF_PARAMS_SIZE; k = k + 1) begin - if (ptr_reg == (16+k)/BYTE_LANES) begin - mcf_params_next[k*8 +: 8] = s_axis_tdata[((16+k)%BYTE_LANES)*8 +: 8]; - end - end - - if (ptr_reg == 15/BYTE_LANES && (!KEEP_ENABLE || s_axis_tkeep[13%BYTE_LANES])) begin - // record match at end of opcode field - mcf_frame_next = mcf_match && cfg_mcf_rx_enable; - end - - if (ptr_reg == (HDR_SIZE-1)/BYTE_LANES) begin - read_mcf_next = 1'b0; - end - - `undef _HEADER_FIELD_ - end - - if (s_axis_tlast) begin - if (s_axis_tuser[0]) begin - // frame marked invalid - end else if (mcf_frame_next) begin - if (!cfg_mcf_rx_forward) begin - // mark frame invalid - m_axis_tuser_int[0] = 1'b1; - end - // transfer out MAC control frame - mcf_valid_next = 1'b1; - stat_rx_mcf_next = 1'b1; - end - - read_mcf_next = 1'b1; - mcf_frame_next = 1'b0; - ptr_next = 0; - end - end -end - -always @(posedge clk) begin - read_mcf_reg <= read_mcf_next; - mcf_frame_reg <= mcf_frame_next; - ptr_reg <= ptr_next; - - s_axis_tready_reg <= s_axis_tready_next; - - mcf_valid_reg <= mcf_valid_next; - mcf_eth_dst_reg <= mcf_eth_dst_next; - mcf_eth_src_reg <= mcf_eth_src_next; - mcf_eth_type_reg <= mcf_eth_type_next; - mcf_opcode_reg <= mcf_opcode_next; - mcf_params_reg <= mcf_params_next; - mcf_id_reg <= mcf_id_next; - mcf_dest_reg <= mcf_dest_next; - mcf_user_reg <= mcf_user_next; - - stat_rx_mcf_reg <= stat_rx_mcf_next; - - if (rst) begin - read_mcf_reg <= 1'b1; - mcf_frame_reg <= 1'b0; - ptr_reg <= 0; - s_axis_tready_reg <= 1'b0; - mcf_valid_reg <= 1'b0; - stat_rx_mcf_reg <= 1'b0; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; -reg m_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; -reg temp_m_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign m_axis_tdata = m_axis_tdata_reg; -assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign m_axis_tvalid = m_axis_tvalid_reg; -assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign m_axis_tready_int_early = m_axis_tready || !USE_READY || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - m_axis_tvalid_next = m_axis_tvalid_reg; - temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (m_axis_tready_int_reg) begin - // input is ready - if (m_axis_tready || !USE_READY || !m_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - m_axis_tvalid_next = m_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_m_axis_tvalid_next = m_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (m_axis_tready || !USE_READY) begin - // input is not ready, but output is ready - m_axis_tvalid_next = temp_m_axis_tvalid_reg; - temp_m_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - m_axis_tvalid_reg <= m_axis_tvalid_next; - m_axis_tready_int_reg <= m_axis_tready_int_early; - temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; - - // datapath - if (store_axis_int_to_output) begin - m_axis_tdata_reg <= m_axis_tdata_int; - m_axis_tkeep_reg <= m_axis_tkeep_int; - m_axis_tlast_reg <= m_axis_tlast_int; - m_axis_tid_reg <= m_axis_tid_int; - m_axis_tdest_reg <= m_axis_tdest_int; - m_axis_tuser_reg <= m_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - m_axis_tdata_reg <= temp_m_axis_tdata_reg; - m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; - m_axis_tlast_reg <= temp_m_axis_tlast_reg; - m_axis_tid_reg <= temp_m_axis_tid_reg; - m_axis_tdest_reg <= temp_m_axis_tdest_reg; - m_axis_tuser_reg <= temp_m_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_m_axis_tdata_reg <= m_axis_tdata_int; - temp_m_axis_tkeep_reg <= m_axis_tkeep_int; - temp_m_axis_tlast_reg <= m_axis_tlast_int; - temp_m_axis_tid_reg <= m_axis_tid_int; - temp_m_axis_tdest_reg <= m_axis_tdest_int; - temp_m_axis_tuser_reg <= m_axis_tuser_int; - end - - if (rst) begin - m_axis_tvalid_reg <= 1'b0; - m_axis_tready_int_reg <= 1'b0; - temp_m_axis_tvalid_reg <= 1'b0; - end -end - -endmodule - -`resetall diff --git a/src/rvvi/mac_ctrl_tx.sv b/src/rvvi/mac_ctrl_tx.sv deleted file mode 100644 index 3d321fd64..000000000 --- a/src/rvvi/mac_ctrl_tx.sv +++ /dev/null @@ -1,420 +0,0 @@ -/* - -Copyright (c) 2023 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * MAC control transmit - */ -module mac_ctrl_tx # -( - parameter DATA_WIDTH = 8, - parameter KEEP_ENABLE = DATA_WIDTH>8, - parameter KEEP_WIDTH = DATA_WIDTH/8, - parameter ID_ENABLE = 0, - parameter ID_WIDTH = 8, - parameter DEST_ENABLE = 0, - parameter DEST_WIDTH = 8, - parameter USER_ENABLE = 1, - parameter USER_WIDTH = 1, - parameter MCF_PARAMS_SIZE = 18 -) -( - input wire clk, - input wire rst, - - /* - * AXI stream input - */ - input wire [DATA_WIDTH-1:0] s_axis_tdata, - input wire [KEEP_WIDTH-1:0] s_axis_tkeep, - input wire s_axis_tvalid, - output wire s_axis_tready, - input wire s_axis_tlast, - input wire [ID_WIDTH-1:0] s_axis_tid, - input wire [DEST_WIDTH-1:0] s_axis_tdest, - input wire [USER_WIDTH-1:0] s_axis_tuser, - - /* - * AXI stream output - */ - output wire [DATA_WIDTH-1:0] m_axis_tdata, - output wire [KEEP_WIDTH-1:0] m_axis_tkeep, - output wire m_axis_tvalid, - input wire m_axis_tready, - output wire m_axis_tlast, - output wire [ID_WIDTH-1:0] m_axis_tid, - output wire [DEST_WIDTH-1:0] m_axis_tdest, - output wire [USER_WIDTH-1:0] m_axis_tuser, - - /* - * MAC control frame interface - */ - input wire mcf_valid, - output wire mcf_ready, - input wire [47:0] mcf_eth_dst, - input wire [47:0] mcf_eth_src, - input wire [15:0] mcf_eth_type, - input wire [15:0] mcf_opcode, - input wire [MCF_PARAMS_SIZE*8-1:0] mcf_params, - input wire [ID_WIDTH-1:0] mcf_id, - input wire [DEST_WIDTH-1:0] mcf_dest, - input wire [USER_WIDTH-1:0] mcf_user, - - /* - * Pause interface - */ - input wire tx_pause_req, - output wire tx_pause_ack, - - /* - * Status - */ - output wire stat_tx_mcf -); - -parameter BYTE_LANES = KEEP_ENABLE ? KEEP_WIDTH : 1; - -parameter HDR_SIZE = 60; - -parameter CYCLE_COUNT = (HDR_SIZE+BYTE_LANES-1)/BYTE_LANES; - -parameter PTR_WIDTH = $clog2(CYCLE_COUNT); - -parameter OFFSET = HDR_SIZE % BYTE_LANES; - -// check configuration -initial begin - if (BYTE_LANES * 8 != DATA_WIDTH) begin - $error("Error: AXI stream interface requires byte (8-bit) granularity (instance %m)"); - $finish; - end - - if (MCF_PARAMS_SIZE > 44) begin - $error("Error: Maximum MCF_PARAMS_SIZE is 44 bytes (instance %m)"); - $finish; - end -end - -/* - -MAC control frame - - Field Length - Destination MAC address 6 octets [01:80:C2:00:00:01] - Source MAC address 6 octets - Ethertype 2 octets [0x8808] - Opcode 2 octets - Parameters 0-44 octets - -This module manages the transmission of MAC control frames. Control frames -are accepted in parallel, serialized, and merged at a higher priority with -data traffic. - -*/ - -reg send_data_reg = 1'b0, send_data_next; -reg send_mcf_reg = 1'b0, send_mcf_next; -reg [PTR_WIDTH-1:0] ptr_reg = 0, ptr_next; - -reg s_axis_tready_reg = 1'b0, s_axis_tready_next; -reg mcf_ready_reg = 1'b0, mcf_ready_next; -reg tx_pause_ack_reg = 1'b0, tx_pause_ack_next; -reg stat_tx_mcf_reg = 1'b0, stat_tx_mcf_next; - -// internal datapath -reg [DATA_WIDTH-1:0] m_axis_tdata_int; -reg [KEEP_WIDTH-1:0] m_axis_tkeep_int; -reg m_axis_tvalid_int; -reg m_axis_tready_int_reg = 1'b0; -reg m_axis_tlast_int; -reg [ID_WIDTH-1:0] m_axis_tid_int; -reg [DEST_WIDTH-1:0] m_axis_tdest_int; -reg [USER_WIDTH-1:0] m_axis_tuser_int; -wire m_axis_tready_int_early; - -assign s_axis_tready = s_axis_tready_reg; -assign mcf_ready = mcf_ready_reg; -assign tx_pause_ack = tx_pause_ack_reg; -assign stat_tx_mcf = stat_tx_mcf_reg; - -integer k; - -always @* begin - send_data_next = send_data_reg; - send_mcf_next = send_mcf_reg; - ptr_next = ptr_reg; - - s_axis_tready_next = 1'b0; - mcf_ready_next = 1'b0; - tx_pause_ack_next = tx_pause_ack_reg; - stat_tx_mcf_next = 1'b0; - - m_axis_tdata_int = 0; - m_axis_tkeep_int = 0; - m_axis_tvalid_int = 1'b0; - m_axis_tlast_int = 1'b0; - m_axis_tid_int = 0; - m_axis_tdest_int = 0; - m_axis_tuser_int = 0; - - if (!send_data_reg && !send_mcf_reg) begin - m_axis_tdata_int = s_axis_tdata; - m_axis_tkeep_int = s_axis_tkeep; - m_axis_tvalid_int = 1'b0; - m_axis_tlast_int = s_axis_tlast; - m_axis_tid_int = s_axis_tid; - m_axis_tdest_int = s_axis_tdest; - m_axis_tuser_int = s_axis_tuser; - s_axis_tready_next = m_axis_tready_int_early && !tx_pause_req; - tx_pause_ack_next = tx_pause_req; - if (s_axis_tvalid && s_axis_tready) begin - s_axis_tready_next = m_axis_tready_int_early; - tx_pause_ack_next = 1'b0; - m_axis_tvalid_int = 1'b1; - if (s_axis_tlast) begin - s_axis_tready_next = m_axis_tready_int_early && !mcf_valid && !mcf_ready; - send_data_next = 1'b0; - end else begin - send_data_next = 1'b1; - end - end else if (mcf_valid) begin - s_axis_tready_next = 1'b0; - ptr_next = 0; - send_mcf_next = 1'b1; - mcf_ready_next = (CYCLE_COUNT == 1) && m_axis_tready_int_early; - end - end - - if (send_data_reg) begin - m_axis_tdata_int = s_axis_tdata; - m_axis_tkeep_int = s_axis_tkeep; - m_axis_tvalid_int = 1'b0; - m_axis_tlast_int = s_axis_tlast; - m_axis_tid_int = s_axis_tid; - m_axis_tdest_int = s_axis_tdest; - m_axis_tuser_int = s_axis_tuser; - s_axis_tready_next = m_axis_tready_int_early; - if (s_axis_tvalid && s_axis_tready) begin - m_axis_tvalid_int = 1'b1; - if (s_axis_tlast) begin - s_axis_tready_next = m_axis_tready_int_early && !tx_pause_req; - send_data_next = 1'b0; - if (mcf_valid) begin - s_axis_tready_next = 1'b0; - ptr_next = 0; - send_mcf_next = 1'b1; - mcf_ready_next = (CYCLE_COUNT == 1) && m_axis_tready_int_early; - end - end else begin - send_data_next = 1'b1; - end - end - end - - if (send_mcf_reg) begin - mcf_ready_next = (CYCLE_COUNT == 1 || ptr_reg == CYCLE_COUNT-1) && m_axis_tready_int_early; - if (m_axis_tready_int_reg) begin - ptr_next = ptr_reg + 1; - - m_axis_tvalid_int = 1'b1; - m_axis_tid_int = mcf_id; - m_axis_tdest_int = mcf_dest; - m_axis_tuser_int = mcf_user; - - `define _HEADER_FIELD_(offset, field) \ - if (ptr_reg == offset/BYTE_LANES) begin \ - m_axis_tdata_int[(offset%BYTE_LANES)*8 +: 8] = field; \ - m_axis_tkeep_int[offset%BYTE_LANES] = 1'b1; \ - end - - `_HEADER_FIELD_(0, mcf_eth_dst[5*8 +: 8]) - `_HEADER_FIELD_(1, mcf_eth_dst[4*8 +: 8]) - `_HEADER_FIELD_(2, mcf_eth_dst[3*8 +: 8]) - `_HEADER_FIELD_(3, mcf_eth_dst[2*8 +: 8]) - `_HEADER_FIELD_(4, mcf_eth_dst[1*8 +: 8]) - `_HEADER_FIELD_(5, mcf_eth_dst[0*8 +: 8]) - `_HEADER_FIELD_(6, mcf_eth_src[5*8 +: 8]) - `_HEADER_FIELD_(7, mcf_eth_src[4*8 +: 8]) - `_HEADER_FIELD_(8, mcf_eth_src[3*8 +: 8]) - `_HEADER_FIELD_(9, mcf_eth_src[2*8 +: 8]) - `_HEADER_FIELD_(10, mcf_eth_src[1*8 +: 8]) - `_HEADER_FIELD_(11, mcf_eth_src[0*8 +: 8]) - `_HEADER_FIELD_(12, mcf_eth_type[1*8 +: 8]) - `_HEADER_FIELD_(13, mcf_eth_type[0*8 +: 8]) - `_HEADER_FIELD_(14, mcf_opcode[1*8 +: 8]) - `_HEADER_FIELD_(15, mcf_opcode[0*8 +: 8]) - - for (k = 0; k < HDR_SIZE-16; k = k + 1) begin - if (ptr_reg == (16+k)/BYTE_LANES) begin - if (k < MCF_PARAMS_SIZE) begin - m_axis_tdata_int[((16+k)%BYTE_LANES)*8 +: 8] = mcf_params[k*8 +: 8]; - end else begin - m_axis_tdata_int[((16+k)%BYTE_LANES)*8 +: 8] = 0; - end - m_axis_tkeep_int[(16+k)%BYTE_LANES] = 1'b1; - end - end - - if (ptr_reg == (HDR_SIZE-1)/BYTE_LANES) begin - s_axis_tready_next = m_axis_tready_int_early && !tx_pause_req; - mcf_ready_next = 1'b0; - m_axis_tlast_int = 1'b1; - send_mcf_next = 1'b0; - stat_tx_mcf_next = 1'b1; - end else begin - mcf_ready_next = (ptr_next == CYCLE_COUNT-1) && m_axis_tready_int_early; - end - - `undef _HEADER_FIELD_ - end - end -end - -always @(posedge clk) begin - send_data_reg <= send_data_next; - send_mcf_reg <= send_mcf_next; - ptr_reg <= ptr_next; - - s_axis_tready_reg <= s_axis_tready_next; - mcf_ready_reg <= mcf_ready_next; - tx_pause_ack_reg <= tx_pause_ack_next; - stat_tx_mcf_reg <= stat_tx_mcf_next; - - if (rst) begin - send_data_reg <= 1'b0; - send_mcf_reg <= 1'b0; - ptr_reg <= 0; - s_axis_tready_reg <= 1'b0; - mcf_ready_reg <= 1'b0; - tx_pause_ack_reg <= 1'b0; - stat_tx_mcf_reg <= 1'b0; - end -end - -// output datapath logic -reg [DATA_WIDTH-1:0] m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg m_axis_tvalid_reg = 1'b0, m_axis_tvalid_next; -reg m_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] m_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] m_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -reg [DATA_WIDTH-1:0] temp_m_axis_tdata_reg = {DATA_WIDTH{1'b0}}; -reg [KEEP_WIDTH-1:0] temp_m_axis_tkeep_reg = {KEEP_WIDTH{1'b0}}; -reg temp_m_axis_tvalid_reg = 1'b0, temp_m_axis_tvalid_next; -reg temp_m_axis_tlast_reg = 1'b0; -reg [ID_WIDTH-1:0] temp_m_axis_tid_reg = {ID_WIDTH{1'b0}}; -reg [DEST_WIDTH-1:0] temp_m_axis_tdest_reg = {DEST_WIDTH{1'b0}}; -reg [USER_WIDTH-1:0] temp_m_axis_tuser_reg = {USER_WIDTH{1'b0}}; - -// datapath control -reg store_axis_int_to_output; -reg store_axis_int_to_temp; -reg store_axis_temp_to_output; - -assign m_axis_tdata = m_axis_tdata_reg; -assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1}}; -assign m_axis_tvalid = m_axis_tvalid_reg; -assign m_axis_tlast = m_axis_tlast_reg; -assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0}}; -assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0}}; -assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0}}; - -// enable ready input next cycle if output is ready or the temp reg will not be filled on the next cycle (output reg empty or no input) -assign m_axis_tready_int_early = m_axis_tready || (!temp_m_axis_tvalid_reg && (!m_axis_tvalid_reg || !m_axis_tvalid_int)); - -always @* begin - // transfer sink ready state to source - m_axis_tvalid_next = m_axis_tvalid_reg; - temp_m_axis_tvalid_next = temp_m_axis_tvalid_reg; - - store_axis_int_to_output = 1'b0; - store_axis_int_to_temp = 1'b0; - store_axis_temp_to_output = 1'b0; - - if (m_axis_tready_int_reg) begin - // input is ready - if (m_axis_tready || !m_axis_tvalid_reg) begin - // output is ready or currently not valid, transfer data to output - m_axis_tvalid_next = m_axis_tvalid_int; - store_axis_int_to_output = 1'b1; - end else begin - // output is not ready, store input in temp - temp_m_axis_tvalid_next = m_axis_tvalid_int; - store_axis_int_to_temp = 1'b1; - end - end else if (m_axis_tready) begin - // input is not ready, but output is ready - m_axis_tvalid_next = temp_m_axis_tvalid_reg; - temp_m_axis_tvalid_next = 1'b0; - store_axis_temp_to_output = 1'b1; - end -end - -always @(posedge clk) begin - m_axis_tvalid_reg <= m_axis_tvalid_next; - m_axis_tready_int_reg <= m_axis_tready_int_early; - temp_m_axis_tvalid_reg <= temp_m_axis_tvalid_next; - - // datapath - if (store_axis_int_to_output) begin - m_axis_tdata_reg <= m_axis_tdata_int; - m_axis_tkeep_reg <= m_axis_tkeep_int; - m_axis_tlast_reg <= m_axis_tlast_int; - m_axis_tid_reg <= m_axis_tid_int; - m_axis_tdest_reg <= m_axis_tdest_int; - m_axis_tuser_reg <= m_axis_tuser_int; - end else if (store_axis_temp_to_output) begin - m_axis_tdata_reg <= temp_m_axis_tdata_reg; - m_axis_tkeep_reg <= temp_m_axis_tkeep_reg; - m_axis_tlast_reg <= temp_m_axis_tlast_reg; - m_axis_tid_reg <= temp_m_axis_tid_reg; - m_axis_tdest_reg <= temp_m_axis_tdest_reg; - m_axis_tuser_reg <= temp_m_axis_tuser_reg; - end - - if (store_axis_int_to_temp) begin - temp_m_axis_tdata_reg <= m_axis_tdata_int; - temp_m_axis_tkeep_reg <= m_axis_tkeep_int; - temp_m_axis_tlast_reg <= m_axis_tlast_int; - temp_m_axis_tid_reg <= m_axis_tid_int; - temp_m_axis_tdest_reg <= m_axis_tdest_int; - temp_m_axis_tuser_reg <= m_axis_tuser_int; - end - - if (rst) begin - m_axis_tvalid_reg <= 1'b0; - m_axis_tready_int_reg <= 1'b0; - temp_m_axis_tvalid_reg <= 1'b0; - end -end - -endmodule - -`resetall diff --git a/src/rvvi/mac_pause_ctrl_rx.sv b/src/rvvi/mac_pause_ctrl_rx.sv deleted file mode 100644 index e95c07bf9..000000000 --- a/src/rvvi/mac_pause_ctrl_rx.sv +++ /dev/null @@ -1,220 +0,0 @@ -/* - -Copyright (c) 2023 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * PFC and pause frame receive handling - */ -module mac_pause_ctrl_rx # -( - parameter MCF_PARAMS_SIZE = 18, - parameter PFC_ENABLE = 1 -) -( - input wire clk, - input wire rst, - - /* - * MAC control frame interface - */ - input wire mcf_valid, - input wire [47:0] mcf_eth_dst, - input wire [47:0] mcf_eth_src, - input wire [15:0] mcf_eth_type, - input wire [15:0] mcf_opcode, - input wire [MCF_PARAMS_SIZE*8-1:0] mcf_params, - - /* - * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) - */ - input wire rx_lfc_en, - output wire rx_lfc_req, - input wire rx_lfc_ack, - - /* - * Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC) - */ - input wire [7:0] rx_pfc_en, - output wire [7:0] rx_pfc_req, - input wire [7:0] rx_pfc_ack, - - /* - * Configuration - */ - input wire [15:0] cfg_rx_lfc_opcode, - input wire cfg_rx_lfc_en, - input wire [15:0] cfg_rx_pfc_opcode, - input wire cfg_rx_pfc_en, - input wire [9:0] cfg_quanta_step, - input wire cfg_quanta_clk_en, - - /* - * Status - */ - output wire stat_rx_lfc_pkt, - output wire stat_rx_lfc_xon, - output wire stat_rx_lfc_xoff, - output wire stat_rx_lfc_paused, - output wire stat_rx_pfc_pkt, - output wire [7:0] stat_rx_pfc_xon, - output wire [7:0] stat_rx_pfc_xoff, - output wire [7:0] stat_rx_pfc_paused -); - -localparam QFB = 8; - -// check configuration -initial begin - if (MCF_PARAMS_SIZE < (PFC_ENABLE ? 18 : 2)) begin - $error("Error: MCF_PARAMS_SIZE too small for requested configuration (instance %m)"); - $finish; - end -end - -reg lfc_req_reg = 1'b0, lfc_req_next; -reg [7:0] pfc_req_reg = 8'd0, pfc_req_next; - -reg [16+QFB-1:0] lfc_quanta_reg = 0, lfc_quanta_next; -reg [16+QFB-1:0] pfc_quanta_reg[0:7], pfc_quanta_next[0:7]; - -reg stat_rx_lfc_pkt_reg = 1'b0, stat_rx_lfc_pkt_next; -reg stat_rx_lfc_xon_reg = 1'b0, stat_rx_lfc_xon_next; -reg stat_rx_lfc_xoff_reg = 1'b0, stat_rx_lfc_xoff_next; -reg stat_rx_pfc_pkt_reg = 1'b0, stat_rx_pfc_pkt_next; -reg [7:0] stat_rx_pfc_xon_reg = 0, stat_rx_pfc_xon_next; -reg [7:0] stat_rx_pfc_xoff_reg = 0, stat_rx_pfc_xoff_next; - -assign rx_lfc_req = lfc_req_reg; -assign rx_pfc_req = pfc_req_reg; - -assign stat_rx_lfc_pkt = stat_rx_lfc_pkt_reg; -assign stat_rx_lfc_xon = stat_rx_lfc_xon_reg; -assign stat_rx_lfc_xoff = stat_rx_lfc_xoff_reg; -assign stat_rx_lfc_paused = lfc_req_reg; -assign stat_rx_pfc_pkt = stat_rx_pfc_pkt_reg; -assign stat_rx_pfc_xon = stat_rx_pfc_xon_reg; -assign stat_rx_pfc_xoff = stat_rx_pfc_xoff_reg; -assign stat_rx_pfc_paused = pfc_req_reg; - -integer k; - -initial begin - for (k = 0; k < 8; k = k + 1) begin - pfc_quanta_reg[k] = 0; - end -end - -always @* begin - stat_rx_lfc_pkt_next = 1'b0; - stat_rx_lfc_xon_next = 1'b0; - stat_rx_lfc_xoff_next = 1'b0; - stat_rx_pfc_pkt_next = 1'b0; - stat_rx_pfc_xon_next = 0; - stat_rx_pfc_xoff_next = 0; - - if (cfg_quanta_clk_en && rx_lfc_ack) begin - if (lfc_quanta_reg > cfg_quanta_step) begin - lfc_quanta_next = lfc_quanta_reg - cfg_quanta_step; - end else begin - lfc_quanta_next = 0; - end - end else begin - lfc_quanta_next = lfc_quanta_reg; - end - - lfc_req_next = (lfc_quanta_reg != 0) && rx_lfc_en && cfg_rx_lfc_en; - - for (k = 0; k < 8; k = k + 1) begin - if (cfg_quanta_clk_en && rx_pfc_ack[k]) begin - if (pfc_quanta_reg[k] > cfg_quanta_step) begin - pfc_quanta_next[k] = pfc_quanta_reg[k] - cfg_quanta_step; - end else begin - pfc_quanta_next[k] = 0; - end - end else begin - pfc_quanta_next[k] = pfc_quanta_reg[k]; - end - - pfc_req_next[k] = (pfc_quanta_reg[k] != 0) && rx_pfc_en[k] && cfg_rx_pfc_en; - end - - if (mcf_valid) begin - if (mcf_opcode == cfg_rx_lfc_opcode && cfg_rx_lfc_en) begin - stat_rx_lfc_pkt_next = 1'b1; - stat_rx_lfc_xon_next = {mcf_params[7:0], mcf_params[15:8]} == 0; - stat_rx_lfc_xoff_next = {mcf_params[7:0], mcf_params[15:8]} != 0; - lfc_quanta_next = {mcf_params[7:0], mcf_params[15:8], {QFB{1'b0}}}; - end else if (PFC_ENABLE && mcf_opcode == cfg_rx_pfc_opcode && cfg_rx_pfc_en) begin - stat_rx_pfc_pkt_next = 1'b1; - for (k = 0; k < 8; k = k + 1) begin - if (mcf_params[k+8]) begin - stat_rx_pfc_xon_next[k] = {mcf_params[16+(k*16)+0 +: 8], mcf_params[16+(k*16)+8 +: 8]} == 0; - stat_rx_pfc_xoff_next[k] = {mcf_params[16+(k*16)+0 +: 8], mcf_params[16+(k*16)+8 +: 8]} != 0; - pfc_quanta_next[k] = {mcf_params[16+(k*16)+0 +: 8], mcf_params[16+(k*16)+8 +: 8], {QFB{1'b0}}}; - end - end - end - end -end - -always @(posedge clk) begin - lfc_req_reg <= lfc_req_next; - pfc_req_reg <= pfc_req_next; - - lfc_quanta_reg <= lfc_quanta_next; - for (k = 0; k < 8; k = k + 1) begin - pfc_quanta_reg[k] <= pfc_quanta_next[k]; - end - - stat_rx_lfc_pkt_reg <= stat_rx_lfc_pkt_next; - stat_rx_lfc_xon_reg <= stat_rx_lfc_xon_next; - stat_rx_lfc_xoff_reg <= stat_rx_lfc_xoff_next; - stat_rx_pfc_pkt_reg <= stat_rx_pfc_pkt_next; - stat_rx_pfc_xon_reg <= stat_rx_pfc_xon_next; - stat_rx_pfc_xoff_reg <= stat_rx_pfc_xoff_next; - - if (rst) begin - lfc_req_reg <= 1'b0; - pfc_req_reg <= 8'd0; - lfc_quanta_reg <= 0; - for (k = 0; k < 8; k = k + 1) begin - pfc_quanta_reg[k] <= 0; - end - - stat_rx_lfc_pkt_reg <= 1'b0; - stat_rx_lfc_xon_reg <= 1'b0; - stat_rx_lfc_xoff_reg <= 1'b0; - stat_rx_pfc_pkt_reg <= 1'b0; - stat_rx_pfc_xon_reg <= 0; - stat_rx_pfc_xoff_reg <= 0; - end -end - -endmodule - -`resetall diff --git a/src/rvvi/mac_pause_ctrl_tx.sv b/src/rvvi/mac_pause_ctrl_tx.sv deleted file mode 100644 index 20566d888..000000000 --- a/src/rvvi/mac_pause_ctrl_tx.sv +++ /dev/null @@ -1,312 +0,0 @@ -/* - -Copyright (c) 2023 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * PFC and pause frame transmit handling - */ -module mac_pause_ctrl_tx # -( - parameter MCF_PARAMS_SIZE = 18, - parameter PFC_ENABLE = 1 -) -( - input wire clk, - input wire rst, - - /* - * MAC control frame interface - */ - output wire mcf_valid, - input wire mcf_ready, - output wire [47:0] mcf_eth_dst, - output wire [47:0] mcf_eth_src, - output wire [15:0] mcf_eth_type, - output wire [15:0] mcf_opcode, - output wire [MCF_PARAMS_SIZE*8-1:0] mcf_params, - - /* - * Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE) - */ - input wire tx_lfc_req, - input wire tx_lfc_resend, - - /* - * Priority Flow Control (PFC) (IEEE 802.3 annex 31D) - */ - input wire [7:0] tx_pfc_req, - input wire tx_pfc_resend, - - /* - * Configuration - */ - input wire [47:0] cfg_tx_lfc_eth_dst, - input wire [47:0] cfg_tx_lfc_eth_src, - input wire [15:0] cfg_tx_lfc_eth_type, - input wire [15:0] cfg_tx_lfc_opcode, - input wire cfg_tx_lfc_en, - input wire [15:0] cfg_tx_lfc_quanta, - input wire [15:0] cfg_tx_lfc_refresh, - input wire [47:0] cfg_tx_pfc_eth_dst, - input wire [47:0] cfg_tx_pfc_eth_src, - input wire [15:0] cfg_tx_pfc_eth_type, - input wire [15:0] cfg_tx_pfc_opcode, - input wire cfg_tx_pfc_en, - input wire [8*16-1:0] cfg_tx_pfc_quanta, - input wire [8*16-1:0] cfg_tx_pfc_refresh, - input wire [9:0] cfg_quanta_step, - input wire cfg_quanta_clk_en, - - /* - * Status - */ - output wire stat_tx_lfc_pkt, - output wire stat_tx_lfc_xon, - output wire stat_tx_lfc_xoff, - output wire stat_tx_lfc_paused, - output wire stat_tx_pfc_pkt, - output wire [7:0] stat_tx_pfc_xon, - output wire [7:0] stat_tx_pfc_xoff, - output wire [7:0] stat_tx_pfc_paused -); - -localparam QFB = 8; - -// check configuration -initial begin - if (MCF_PARAMS_SIZE < (PFC_ENABLE ? 18 : 2)) begin - $error("Error: MCF_PARAMS_SIZE too small for requested configuration (instance %m)"); - $finish; - end -end - -reg lfc_req_reg = 1'b0, lfc_req_next; -reg lfc_act_reg = 1'b0, lfc_act_next; -reg lfc_send_reg = 1'b0, lfc_send_next; -reg [7:0] pfc_req_reg = 8'd0, pfc_req_next; -reg [7:0] pfc_act_reg = 8'd0, pfc_act_next; -reg [7:0] pfc_en_reg = 8'd0, pfc_en_next; -reg pfc_send_reg = 1'b0, pfc_send_next; - -reg [16+QFB-1:0] lfc_refresh_reg = 0, lfc_refresh_next; -reg [16+QFB-1:0] pfc_refresh_reg[0:7], pfc_refresh_next[0:7]; - -reg stat_tx_lfc_pkt_reg = 1'b0, stat_tx_lfc_pkt_next; -reg stat_tx_lfc_xon_reg = 1'b0, stat_tx_lfc_xon_next; -reg stat_tx_lfc_xoff_reg = 1'b0, stat_tx_lfc_xoff_next; -reg stat_tx_pfc_pkt_reg = 1'b0, stat_tx_pfc_pkt_next; -reg [7:0] stat_tx_pfc_xon_reg = 0, stat_tx_pfc_xon_next; -reg [7:0] stat_tx_pfc_xoff_reg = 0, stat_tx_pfc_xoff_next; - -// MAC control interface -reg mcf_pfc_sel_reg = PFC_ENABLE != 0, mcf_pfc_sel_next; -reg mcf_valid_reg = 1'b0, mcf_valid_next; - -wire [2*8-1:0] mcf_lfc_params; -assign mcf_lfc_params[16*0 +: 16] = lfc_req_reg ? {cfg_tx_lfc_quanta[0 +: 8], cfg_tx_lfc_quanta[8 +: 8]} : 0; - -wire [18*8-1:0] mcf_pfc_params; -assign mcf_pfc_params[16*0 +: 16] = {pfc_en_reg, 8'd0}; -assign mcf_pfc_params[16*1 +: 16] = pfc_req_reg[0] ? {cfg_tx_pfc_quanta[16*0+0 +: 8], cfg_tx_pfc_quanta[16*0+8 +: 8]} : 0; -assign mcf_pfc_params[16*2 +: 16] = pfc_req_reg[1] ? {cfg_tx_pfc_quanta[16*1+0 +: 8], cfg_tx_pfc_quanta[16*1+8 +: 8]} : 0; -assign mcf_pfc_params[16*3 +: 16] = pfc_req_reg[2] ? {cfg_tx_pfc_quanta[16*2+0 +: 8], cfg_tx_pfc_quanta[16*2+8 +: 8]} : 0; -assign mcf_pfc_params[16*4 +: 16] = pfc_req_reg[3] ? {cfg_tx_pfc_quanta[16*3+0 +: 8], cfg_tx_pfc_quanta[16*3+8 +: 8]} : 0; -assign mcf_pfc_params[16*5 +: 16] = pfc_req_reg[4] ? {cfg_tx_pfc_quanta[16*4+0 +: 8], cfg_tx_pfc_quanta[16*4+8 +: 8]} : 0; -assign mcf_pfc_params[16*6 +: 16] = pfc_req_reg[5] ? {cfg_tx_pfc_quanta[16*5+0 +: 8], cfg_tx_pfc_quanta[16*5+8 +: 8]} : 0; -assign mcf_pfc_params[16*7 +: 16] = pfc_req_reg[6] ? {cfg_tx_pfc_quanta[16*6+0 +: 8], cfg_tx_pfc_quanta[16*6+8 +: 8]} : 0; -assign mcf_pfc_params[16*8 +: 16] = pfc_req_reg[7] ? {cfg_tx_pfc_quanta[16*7+0 +: 8], cfg_tx_pfc_quanta[16*7+8 +: 8]} : 0; - -assign mcf_valid = mcf_valid_reg; -assign mcf_eth_dst = (PFC_ENABLE && mcf_pfc_sel_reg) ? cfg_tx_pfc_eth_dst : cfg_tx_lfc_eth_dst; -assign mcf_eth_src = (PFC_ENABLE && mcf_pfc_sel_reg) ? cfg_tx_pfc_eth_src : cfg_tx_lfc_eth_src; -assign mcf_eth_type = (PFC_ENABLE && mcf_pfc_sel_reg) ? cfg_tx_pfc_eth_type : cfg_tx_lfc_eth_type; -assign mcf_opcode = (PFC_ENABLE && mcf_pfc_sel_reg) ? cfg_tx_pfc_opcode : cfg_tx_lfc_opcode; -assign mcf_params = (PFC_ENABLE && mcf_pfc_sel_reg) ? mcf_pfc_params : mcf_lfc_params; - -assign stat_tx_lfc_pkt = stat_tx_lfc_pkt_reg; -assign stat_tx_lfc_xon = stat_tx_lfc_xon_reg; -assign stat_tx_lfc_xoff = stat_tx_lfc_xoff_reg; -assign stat_tx_lfc_paused = lfc_req_reg; -assign stat_tx_pfc_pkt = stat_tx_pfc_pkt_reg; -assign stat_tx_pfc_xon = stat_tx_pfc_xon_reg; -assign stat_tx_pfc_xoff = stat_tx_pfc_xoff_reg; -assign stat_tx_pfc_paused = pfc_req_reg; - -integer k; - -initial begin - for (k = 0; k < 8; k = k + 1) begin - pfc_refresh_reg[k] = 0; - end -end - -always @* begin - lfc_req_next = lfc_req_reg; - lfc_act_next = lfc_act_reg; - lfc_send_next = lfc_send_reg | tx_lfc_resend; - pfc_req_next = pfc_req_reg; - pfc_act_next = pfc_act_reg; - pfc_en_next = pfc_en_reg; - pfc_send_next = pfc_send_reg | tx_pfc_resend; - - mcf_pfc_sel_next = mcf_pfc_sel_reg; - mcf_valid_next = mcf_valid_reg && !mcf_ready; - - stat_tx_lfc_pkt_next = 1'b0; - stat_tx_lfc_xon_next = 1'b0; - stat_tx_lfc_xoff_next = 1'b0; - stat_tx_pfc_pkt_next = 1'b0; - stat_tx_pfc_xon_next = 0; - stat_tx_pfc_xoff_next = 0; - - if (cfg_quanta_clk_en) begin - if (lfc_refresh_reg > cfg_quanta_step) begin - lfc_refresh_next = lfc_refresh_reg - cfg_quanta_step; - end else begin - lfc_refresh_next = 0; - if (lfc_req_reg) begin - lfc_send_next = 1'b1; - end - end - end else begin - lfc_refresh_next = lfc_refresh_reg; - end - - for (k = 0; k < 8; k = k + 1) begin - if (cfg_quanta_clk_en) begin - if (pfc_refresh_reg[k] > cfg_quanta_step) begin - pfc_refresh_next[k] = pfc_refresh_reg[k] - cfg_quanta_step; - end else begin - pfc_refresh_next[k] = 0; - if (pfc_req_reg[k]) begin - pfc_send_next = 1'b1; - end - end - end else begin - pfc_refresh_next[k] = pfc_refresh_reg[k]; - end - end - - if (cfg_tx_lfc_en) begin - if (!mcf_valid_reg) begin - if (lfc_req_reg != tx_lfc_req) begin - lfc_req_next = tx_lfc_req; - lfc_act_next = lfc_act_reg | tx_lfc_req; - lfc_send_next = 1'b1; - end - - if (lfc_send_reg && !(PFC_ENABLE && cfg_tx_pfc_en && pfc_send_reg)) begin - mcf_pfc_sel_next = 1'b0; - mcf_valid_next = lfc_act_reg; - lfc_act_next = lfc_req_reg; - lfc_refresh_next = lfc_req_reg ? {cfg_tx_lfc_refresh, {QFB{1'b0}}} : 0; - lfc_send_next = 1'b0; - - stat_tx_lfc_pkt_next = lfc_act_reg; - stat_tx_lfc_xon_next = lfc_act_reg && !lfc_req_reg; - stat_tx_lfc_xoff_next = lfc_act_reg && lfc_req_reg; - end - end - end - - if (PFC_ENABLE && cfg_tx_pfc_en) begin - if (!mcf_valid_reg) begin - if (pfc_req_reg != tx_pfc_req) begin - pfc_req_next = tx_pfc_req; - pfc_act_next = pfc_act_reg | tx_pfc_req; - pfc_send_next = 1'b1; - end - - if (pfc_send_reg) begin - mcf_pfc_sel_next = 1'b1; - mcf_valid_next = pfc_act_reg != 0; - pfc_en_next = pfc_act_reg; - pfc_act_next = pfc_req_reg; - for (k = 0; k < 8; k = k + 1) begin - pfc_refresh_next[k] = pfc_req_reg[k] ? {cfg_tx_pfc_refresh[16*k +: 16], {QFB{1'b0}}} : 0; - end - pfc_send_next = 1'b0; - - stat_tx_pfc_pkt_next = pfc_act_reg != 0; - stat_tx_pfc_xon_next = pfc_act_reg & ~pfc_req_reg; - stat_tx_pfc_xoff_next = pfc_act_reg & pfc_req_reg; - end - end - end -end - -always @(posedge clk) begin - lfc_req_reg <= lfc_req_next; - lfc_act_reg <= lfc_act_next; - lfc_send_reg <= lfc_send_next; - pfc_req_reg <= pfc_req_next; - pfc_act_reg <= pfc_act_next; - pfc_en_reg <= pfc_en_next; - pfc_send_reg <= pfc_send_next; - - mcf_pfc_sel_reg <= mcf_pfc_sel_next; - mcf_valid_reg <= mcf_valid_next; - - lfc_refresh_reg <= lfc_refresh_next; - for (k = 0; k < 8; k = k + 1) begin - pfc_refresh_reg[k] <= pfc_refresh_next[k]; - end - - stat_tx_lfc_pkt_reg <= stat_tx_lfc_pkt_next; - stat_tx_lfc_xon_reg <= stat_tx_lfc_xon_next; - stat_tx_lfc_xoff_reg <= stat_tx_lfc_xoff_next; - stat_tx_pfc_pkt_reg <= stat_tx_pfc_pkt_next; - stat_tx_pfc_xon_reg <= stat_tx_pfc_xon_next; - stat_tx_pfc_xoff_reg <= stat_tx_pfc_xoff_next; - - if (rst) begin - lfc_req_reg <= 1'b0; - lfc_act_reg <= 1'b0; - lfc_send_reg <= 1'b0; - pfc_req_reg <= 0; - pfc_act_reg <= 0; - pfc_send_reg <= 0; - mcf_pfc_sel_reg <= PFC_ENABLE != 0; - mcf_valid_reg <= 1'b0; - lfc_refresh_reg <= 0; - for (k = 0; k < 8; k = k + 1) begin - pfc_refresh_reg[k] <= 0; - end - - stat_tx_lfc_pkt_reg <= 1'b0; - stat_tx_lfc_xon_reg <= 1'b0; - stat_tx_lfc_xoff_reg <= 1'b0; - stat_tx_pfc_pkt_reg <= 1'b0; - stat_tx_pfc_xon_reg <= 0; - stat_tx_pfc_xoff_reg <= 0; - end -end - -endmodule - -`resetall diff --git a/src/rvvi/mii_phy_if.sv b/src/rvvi/mii_phy_if.sv deleted file mode 100644 index f3857ed06..000000000 --- a/src/rvvi/mii_phy_if.sv +++ /dev/null @@ -1,140 +0,0 @@ -/* - -Copyright (c) 2019 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * MII PHY interface - */ -module mii_phy_if # -( - // target ("SIM", "GENERIC", "XILINX", "ALTERA") - parameter TARGET = "GENERIC", - // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") - // Use BUFR for Virtex-5, Virtex-6, 7-series - // Use BUFG for Ultrascale - // Use BUFIO2 for Spartan-6 - parameter CLOCK_INPUT_STYLE = "BUFIO2" -) -( - input wire rst, - - /* - * MII interface to MAC - */ - output wire mac_mii_rx_clk, - output wire mac_mii_rx_rst, - output wire [3:0] mac_mii_rxd, - output wire mac_mii_rx_dv, - output wire mac_mii_rx_er, - output wire mac_mii_tx_clk, - output wire mac_mii_tx_rst, -(* mark_debug = "true" *) input wire [3:0] mac_mii_txd, -(* mark_debug = "true" *) input wire mac_mii_tx_en, - input wire mac_mii_tx_er, - - /* - * MII interface to PHY - */ - input wire phy_mii_rx_clk, - input wire [3:0] phy_mii_rxd, - input wire phy_mii_rx_dv, - input wire phy_mii_rx_er, - input wire phy_mii_tx_clk, - output wire [3:0] phy_mii_txd, - output wire phy_mii_tx_en, - output wire phy_mii_tx_er -); - -ssio_sdr_in # -( - .TARGET(TARGET), - .CLOCK_INPUT_STYLE(CLOCK_INPUT_STYLE), - .WIDTH(6) -) -rx_ssio_sdr_inst ( - .input_clk(phy_mii_rx_clk), - .input_d({phy_mii_rxd, phy_mii_rx_dv, phy_mii_rx_er}), - .output_clk(mac_mii_rx_clk), - .output_q({mac_mii_rxd, mac_mii_rx_dv, mac_mii_rx_er}) -); - -(* IOB = "TRUE" *) -reg [3:0] phy_mii_txd_reg = 4'd0; -(* IOB = "TRUE" *) -reg phy_mii_tx_en_reg = 1'b0, phy_mii_tx_er_reg = 1'b0; - -assign phy_mii_txd = phy_mii_txd_reg; -assign phy_mii_tx_en = phy_mii_tx_en_reg; -assign phy_mii_tx_er = phy_mii_tx_er_reg; - -always @(posedge mac_mii_tx_clk) begin - phy_mii_txd_reg <= mac_mii_txd; - phy_mii_tx_en_reg <= mac_mii_tx_en; - phy_mii_tx_er_reg <= mac_mii_tx_er; -end - -generate - -if (TARGET == "XILINX") begin - BUFG - mii_bufg_inst ( - .I(phy_mii_tx_clk), - .O(mac_mii_tx_clk) - ); -end else begin - assign mac_mii_tx_clk = phy_mii_tx_clk; -end - -endgenerate - -// reset sync -reg [3:0] tx_rst_reg = 4'hf; -assign mac_mii_tx_rst = tx_rst_reg[0]; - -always @(posedge mac_mii_tx_clk or posedge rst) begin - if (rst) begin - tx_rst_reg <= 4'hf; - end else begin - tx_rst_reg <= {1'b0, tx_rst_reg[3:1]}; - end -end - -reg [3:0] rx_rst_reg = 4'hf; -assign mac_mii_rx_rst = rx_rst_reg[0]; - -always @(posedge mac_mii_rx_clk or posedge rst) begin - if (rst) begin - rx_rst_reg <= 4'hf; - end else begin - rx_rst_reg <= {1'b0, rx_rst_reg[3:1]}; - end -end - -endmodule - -`resetall diff --git a/src/rvvi/ssio_ddr_in.sv b/src/rvvi/ssio_ddr_in.sv deleted file mode 100644 index 5060f4d27..000000000 --- a/src/rvvi/ssio_ddr_in.sv +++ /dev/null @@ -1,150 +0,0 @@ -/* - -Copyright (c) 2016-2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * Generic source synchronous DDR input - */ -module ssio_ddr_in # -( - // target ("SIM", "GENERIC", "XILINX", "ALTERA") - parameter TARGET = "GENERIC", - // IODDR style ("IODDR", "IODDR2") - // Use IODDR for Virtex-4, Virtex-5, Virtex-6, 7 Series, Ultrascale - // Use IODDR2 for Spartan-6 - parameter IODDR_STYLE = "IODDR2", - // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") - // Use BUFR for Virtex-6, 7-series - // Use BUFG for Virtex-5, Spartan-6, Ultrascale - parameter CLOCK_INPUT_STYLE = "BUFG", - // Width of register in bits - parameter WIDTH = 1 -) -( - input wire input_clk, - - input wire [WIDTH-1:0] input_d, - - output wire output_clk, - - output wire [WIDTH-1:0] output_q1, - output wire [WIDTH-1:0] output_q2 -); - -wire clk_int; -wire clk_io; - -generate - -if (TARGET == "XILINX") begin - - // use Xilinx clocking primitives - - if (CLOCK_INPUT_STYLE == "BUFG") begin - - // buffer RX clock - BUFG - clk_bufg ( - .I(input_clk), - .O(clk_int) - ); - - // pass through RX clock to logic and input buffers - assign clk_io = clk_int; - assign output_clk = clk_int; - - end else if (CLOCK_INPUT_STYLE == "BUFR") begin - - assign clk_int = input_clk; - - // pass through RX clock to input buffers - BUFIO - clk_bufio ( - .I(clk_int), - .O(clk_io) - ); - - // pass through RX clock to logic - BUFR #( - .BUFR_DIVIDE("BYPASS") - ) - clk_bufr ( - .I(clk_int), - .O(output_clk), - .CE(1'b1), - .CLR(1'b0) - ); - - end else if (CLOCK_INPUT_STYLE == "BUFIO") begin - - assign clk_int = input_clk; - - // pass through RX clock to input buffers - BUFIO - clk_bufio ( - .I(clk_int), - .O(clk_io) - ); - - // pass through RX clock to MAC - BUFG - clk_bufg ( - .I(clk_int), - .O(output_clk) - ); - - end - -end else begin - - // pass through RX clock to input buffers - assign clk_io = input_clk; - - // pass through RX clock to logic - assign clk_int = input_clk; - assign output_clk = clk_int; - -end - -endgenerate - -iddr #( - .TARGET(TARGET), - .IODDR_STYLE(IODDR_STYLE), - .WIDTH(WIDTH) -) -data_iddr_inst ( - .clk(clk_io), - .d(input_d), - .q1(output_q1), - .q2(output_q2) -); - -endmodule - -`resetall diff --git a/src/rvvi/ssio_sdr_in.sv b/src/rvvi/ssio_sdr_in.sv deleted file mode 100644 index 351cadc1d..000000000 --- a/src/rvvi/ssio_sdr_in.sv +++ /dev/null @@ -1,166 +0,0 @@ -/* - -Copyright (c) 2016-2018 Alex Forencich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -*/ - -// Language: Verilog 2001 - -`resetall -`default_nettype none - -/* - * Generic source synchronous SDR input - */ -module ssio_sdr_in # -( - // target ("SIM", "GENERIC", "XILINX", "ALTERA") - parameter TARGET = "GENERIC", - // Clock input style ("BUFG", "BUFR", "BUFIO", "BUFIO2") - // Use BUFR for Virtex-5, Virtex-6, 7-series - // Use BUFG for Ultrascale - // Use BUFIO2 for Spartan-6 - parameter CLOCK_INPUT_STYLE = "BUFIO2", - // Width of register in bits - parameter WIDTH = 1 -) -( - input wire input_clk, - - input wire [WIDTH-1:0] input_d, - - output wire output_clk, - - output wire [WIDTH-1:0] output_q -); - -wire clk_int; -wire clk_io; - -generate - -if (TARGET == "XILINX") begin - - // use Xilinx clocking primitives - - if (CLOCK_INPUT_STYLE == "BUFG") begin - - // buffer RX clock - BUFG - clk_bufg ( - .I(input_clk), - .O(clk_int) - ); - - // pass through RX clock to logic and input buffers - assign clk_io = clk_int; - assign output_clk = clk_int; - - end else if (CLOCK_INPUT_STYLE == "BUFR") begin - - assign clk_int = input_clk; - - // pass through RX clock to input buffers - BUFIO - clk_bufio ( - .I(clk_int), - .O(clk_io) - ); - - // pass through RX clock to logic - BUFR #( - .BUFR_DIVIDE("BYPASS") - ) - clk_bufr ( - .I(clk_int), - .O(output_clk), - .CE(1'b1), - .CLR(1'b0) - ); - - end else if (CLOCK_INPUT_STYLE == "BUFIO") begin - - assign clk_int = input_clk; - - // pass through RX clock to input buffers - BUFIO - clk_bufio ( - .I(clk_int), - .O(clk_io) - ); - - // pass through RX clock to MAC - BUFG - clk_bufg ( - .I(clk_int), - .O(output_clk) - ); - - end else if (CLOCK_INPUT_STYLE == "BUFIO2") begin - - // pass through RX clock to input buffers - BUFIO2 #( - .DIVIDE(1), - .DIVIDE_BYPASS("TRUE"), - .I_INVERT("FALSE"), - .USE_DOUBLER("FALSE") - ) - clk_bufio ( - .I(input_clk), - .DIVCLK(clk_int), - .IOCLK(clk_io), - .SERDESSTROBE() - ); - - // pass through RX clock to MAC - BUFG - clk_bufg ( - .I(clk_int), - .O(output_clk) - ); - - end - -end else begin - - // pass through RX clock to input buffers - assign clk_io = input_clk; - - // pass through RX clock to logic - assign clk_int = input_clk; - assign output_clk = clk_int; - -end - -endgenerate - -(* IOB = "TRUE" *) -reg [WIDTH-1:0] output_q_reg = {WIDTH{1'b0}}; - -assign output_q = output_q_reg; - -always @(posedge clk_io) begin - output_q_reg <= input_d; -end - -endmodule - -`resetall From 9471dcd296d7ba0dfe4bf8c791cc5f4db8242618 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 19 Jul 2024 17:08:47 -0500 Subject: [PATCH 70/95] Refactored the fpga and testbench so the RVVI can be synthesized cleanly and simulated without any major code changes. Adds three new configuration parameters to control enabling the RVVI packetizer and how much latency should exist between packets and the initial startup delay. --- .gitignore | 1 + config/derivlist.txt | 4 ++ config/rv32e/config.vh | 5 ++ config/rv32gc/config.vh | 5 ++ config/rv32i/config.vh | 5 ++ config/rv32imc/config.vh | 5 ++ config/rv64gc/config.vh | 5 ++ config/rv64i/config.vh | 5 ++ config/shared/parameter-defs.vh | 5 +- fpga/src/fpgaTopArtyA7.sv | 83 +++++++++++++++++++++++++++++- sim/questa/wally.do | 2 +- sim/verilator/Makefile | 6 +-- src/cvw.sv | 5 ++ src/hazard/hazard.sv | 4 +- src/rvvi/packetizer.sv | 7 +-- src/rvvi/rvvisynth.sv | 42 +++++++++------ src/wally/wallypipelinedcore.sv | 4 +- src/wally/wallypipelinedsoc.sv | 4 +- testbench/common/loggers.sv | 4 +- testbench/testbench.sv | 91 ++++++++++++++++++++++++++++++--- testbench/wallywrapper.sv | 6 +-- 21 files changed, 253 insertions(+), 45 deletions(-) diff --git a/.gitignore b/.gitignore index 9a5f1668c..3c4918418 100644 --- a/.gitignore +++ b/.gitignore @@ -237,3 +237,4 @@ tests/functcov tests/functcov/* tests/functcov/*/* sim/vcs/simprofile* +/fpga/rvvidaemon/rvvidaemon diff --git a/config/derivlist.txt b/config/derivlist.txt index 174ca5191..9535e9833 100644 --- a/config/derivlist.txt +++ b/config/derivlist.txt @@ -56,6 +56,10 @@ EXT_MEM_RANGE 64'h0FFFFFFF SDC_SUPPORTED 1 PLIC_SDC_ID 32'd20 BPRED_SIZE 32'd12 +RVVI_SYNTH_SUPPORTED 1 +RVVI_INIT_TIME_OUT 32'd100000000 +RVVI_PACKET_DELAY 32'd350 + # The syn configurations are trimmed down for faster synthesis. deriv syn_rv32e rv32e diff --git a/config/rv32e/config.vh b/config/rv32e/config.vh index 4ec0123d1..1234bbcdf 100644 --- a/config/rv32e/config.vh +++ b/config/rv32e/config.vh @@ -225,4 +225,9 @@ localparam DIVCOPIES = 32'd4; // Memory synthesis configuration localparam logic USE_SRAM = 0; +// debug tools +localparam logic RVVI_SYNTH_SUPPORTED = 0; +localparam [31:0] RVVI_INIT_TIME_OUT = 32'd4; +localparam [31:0] RVVI_PACKET_DELAY = 32'd2; + `include "config-shared.vh" diff --git a/config/rv32gc/config.vh b/config/rv32gc/config.vh index c861759d9..9f5809383 100644 --- a/config/rv32gc/config.vh +++ b/config/rv32gc/config.vh @@ -225,4 +225,9 @@ localparam DIVCOPIES = 32'd2; // Memory synthesis configuration localparam logic USE_SRAM = 0; +// debug tools +localparam logic RVVI_SYNTH_SUPPORTED = 0; +localparam [31:0] RVVI_INIT_TIME_OUT = 32'd4; +localparam [31:0] RVVI_PACKET_DELAY = 32'd2; + `include "config-shared.vh" diff --git a/config/rv32i/config.vh b/config/rv32i/config.vh index 01818afc2..6bfea805e 100644 --- a/config/rv32i/config.vh +++ b/config/rv32i/config.vh @@ -225,4 +225,9 @@ localparam DIVCOPIES = 32'd4; // Memory synthesis configuration localparam logic USE_SRAM = 0; +// debug tools +localparam logic RVVI_SYNTH_SUPPORTED = 0; +localparam [31:0] RVVI_INIT_TIME_OUT = 32'd4; +localparam [31:0] RVVI_PACKET_DELAY = 32'd2; + `include "config-shared.vh" diff --git a/config/rv32imc/config.vh b/config/rv32imc/config.vh index 05a8fd242..3918c702c 100644 --- a/config/rv32imc/config.vh +++ b/config/rv32imc/config.vh @@ -225,4 +225,9 @@ localparam DIVCOPIES = 32'd4; // Memory synthesis configuration localparam logic USE_SRAM = 0; +// debug tools +localparam logic RVVI_SYNTH_SUPPORTED = 0; +localparam [31:0] RVVI_INIT_TIME_OUT = 32'd4; +localparam [31:0] RVVI_PACKET_DELAY = 32'd2; + `include "config-shared.vh" diff --git a/config/rv64gc/config.vh b/config/rv64gc/config.vh index b8ed8dc47..86036aaa7 100644 --- a/config/rv64gc/config.vh +++ b/config/rv64gc/config.vh @@ -225,4 +225,9 @@ localparam DIVCOPIES = 32'd4; // Memory synthesis configuration localparam logic USE_SRAM = 0; +// debug tools +localparam logic RVVI_SYNTH_SUPPORTED = 0; +localparam [31:0] RVVI_INIT_TIME_OUT = 32'd4; +localparam [31:0] RVVI_PACKET_DELAY = 32'd2; + `include "config-shared.vh" diff --git a/config/rv64i/config.vh b/config/rv64i/config.vh index 94360877f..0e13f9ea1 100644 --- a/config/rv64i/config.vh +++ b/config/rv64i/config.vh @@ -225,4 +225,9 @@ localparam DIVCOPIES = 32'd4; // Memory synthesis configuration localparam logic USE_SRAM = 0; +// debug tools +localparam logic RVVI_SYNTH_SUPPORTED = 0; +localparam [31:0] RVVI_INIT_TIME_OUT = 32'd4; +localparam [31:0] RVVI_PACKET_DELAY = 32'd2; + `include "config-shared.vh" diff --git a/config/shared/parameter-defs.vh b/config/shared/parameter-defs.vh index 3dd067b34..099f49287 100644 --- a/config/shared/parameter-defs.vh +++ b/config/shared/parameter-defs.vh @@ -199,5 +199,8 @@ localparam cvw_t P = '{ FPDUR : FPDUR, DURLEN : DURLEN, DIVb : DIVb, - DIVBLEN : DIVBLEN + DIVBLEN : DIVBLEN, + RVVI_SYNTH_SUPPORTED : RVVI_SYNTH_SUPPORTED, + RVVI_INIT_TIME_OUT : RVVI_INIT_TIME_OUT, + RVVI_PACKET_DELAY : RVVI_PACKET_DELAY }; diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index e5a706d0d..7fe0a13b0 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -513,7 +513,7 @@ module fpgaTop .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN, - .UARTSin, .UARTSout, .SDCIntr, .RVVIStall); + .UARTSin, .UARTSout, .SDCIntr, .ExternalStall(RVVIStall)); // ahb lite to axi bridge @@ -1116,10 +1116,89 @@ module fpgaTop .device_temp(device_temp)); localparam MAX_CSRS = 3; + localparam TOTAL_CSRS = 36; + + // pipeline controlls + logic StallE, StallM, StallW, FlushE, FlushM, FlushW; + // required + logic [P.XLEN-1:0] PCM; + logic InstrValidM; + logic [31:0] InstrRawD; + logic [63:0] Mcycle, Minstret; + logic TrapM; + logic [1:0] PrivilegeModeW; + // registers gpr and fpr + logic GPRWen, FPRWen; + logic [4:0] GPRAddr, FPRAddr; + logic [P.XLEN-1:0] GPRValue, FPRValue; + logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0]; + (* mark_debug = "true" *) logic valid; logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; - rvvisynth #(P, MAX_CSRS) rvvisynth(.clk(CPUCLK), .reset(bus_struct_reset), .valid, .rvvi); + assign StallE = fpgaTop.wallypipelinedsoc.core.StallE; + assign StallM = fpgaTop.wallypipelinedsoc.core.StallM; + assign StallW = fpgaTop.wallypipelinedsoc.core.StallW; + assign FlushE = fpgaTop.wallypipelinedsoc.core.FlushE; + assign FlushM = fpgaTop.wallypipelinedsoc.core.FlushM; + assign FlushW = fpgaTop.wallypipelinedsoc.core.FlushW; + assign InstrValidM = fpgaTop.wallypipelinedsoc.core.ieu.InstrValidM; + assign InstrRawD = fpgaTop.wallypipelinedsoc.core.ifu.InstrRawD; + assign PCM = fpgaTop.wallypipelinedsoc.core.ifu.PCM; + assign Mcycle = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; + assign Minstret = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; + assign TrapM = fpgaTop.wallypipelinedsoc.core.TrapM; + assign PrivilegeModeW = fpgaTop.wallypipelinedsoc.core.priv.priv.privmode.PrivilegeModeW; + assign GPRAddr = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.a3; + assign GPRWen = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.we3; + assign GPRValue = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.wd3; + assign FPRAddr = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.a4; + assign FPRWen = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.we4; + assign FPRValue = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.wd4; + + assign CSRArray[0] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 + assign CSRArray[1] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 + assign CSRArray[2] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 + assign CSRArray[3] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 + assign CSRArray[4] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 + assign CSRArray[5] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 + assign CSRArray[6] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 + assign CSRArray[7] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 + assign CSRArray[8] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 + assign CSRArray[9] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 + assign CSRArray[10] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 + assign CSRArray[11] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A + assign CSRArray[12] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 + assign CSRArray[13] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 + assign CSRArray[14] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 + assign CSRArray[15] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 + assign CSRArray[16] = 0; // 12'hF11 + assign CSRArray[17] = 0; // 12'hF12 + assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 + assign CSRArray[19] = 0; // 12'hF15 + assign CSRArray[20] = 0; // 12'h34A + // supervisor CSRs + assign CSRArray[21] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 + assign CSRArray[22] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 + assign CSRArray[23] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 + assign CSRArray[24] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 + assign CSRArray[25] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 + assign CSRArray[26] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A + assign CSRArray[27] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 + assign CSRArray[28] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 + assign CSRArray[29] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 + assign CSRArray[30] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 + assign CSRArray[31] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 + assign CSRArray[32] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D + // user CSRs + assign CSRArray[33] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 + assign CSRArray[34] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 + assign CSRArray[35] = {fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW, fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 + + rvvisynth #(P, MAX_CSRS) rvvisynth(.clk(CPUCLK), .reset(bus_struct_reset), .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, + .PCM, .InstrValidM, .InstrRawD, .Mcycle, .Minstret, .TrapM, + .PrivilegeModeW, .GPRWen, .FPRWen, .GPRAddr, .FPRAddr, .GPRValue, .FPRValue, .CSRArray, + .valid, .rvvi); // axi 4 write data channel (* mark_debug = "true" *) logic [31:0] RvviAxiWdata; diff --git a/sim/questa/wally.do b/sim/questa/wally.do index a0e6fdbb6..71a25856d 100644 --- a/sim/questa/wally.do +++ b/sim/questa/wally.do @@ -193,7 +193,7 @@ set temp3 [lindex $PlusArgs 3] # "Extra checking for conflicts with always_comb done at vopt time" # because vsim will run vopt -vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared ${lockstepvoptstring} ${FCdefineIDV_INCLUDE_TRACE2COV} ${FCdefineINCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${rvviFiles} ${idvFiles} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${riscvISACOVsrc} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 +vlog -lint -work ${WKDIR} +incdir+${CONFIG}/${CFG} +incdir+${CONFIG}/deriv/${CFG} +incdir+${CONFIG}/shared ${lockstepvoptstring} ${FCdefineIDV_INCLUDE_TRACE2COV} ${FCdefineINCLUDE_TRACE2COV} ${ImperasPubInc} ${ImperasPrivInc} ${rvviFiles} ${idvFiles} ${FCdefineCOVER_BASE_RV64I} ${FCdefineCOVER_LEVEL_DV_PR_EXT} ${FCdefineCOVER_RV64I} ${FCdefineCOVER_RV64M} ${FCdefineCOVER_RV64A} ${FCdefineCOVER_RV64F} ${FCdefineCOVER_RV64D} ${FCdefineCOVER_RV64ZICSR} ${FCdefineCOVER_RV64C} ${riscvISACOVsrc} ${SRC}/cvw.sv ${TB}/${TESTBENCH}.sv ${TB}/common/*.sv ${SRC}/*/*.sv ${SRC}/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv -suppress 2583 -suppress 7063,2596,13286 # start and run simulation # remove +acc flag for faster sim during regressions if there is no need to access internal signals diff --git a/sim/verilator/Makefile b/sim/verilator/Makefile index ba8470548..e6bde7b41 100644 --- a/sim/verilator/Makefile +++ b/sim/verilator/Makefile @@ -25,7 +25,7 @@ TARGET=$(WORKING_DIR)/target # INCLUDE_PATH are pathes that Verilator should search for files it needs INCLUDE_PATH="-I${WALLY}/config/shared" "-I${WALLY}/config/$(WALLYCONF)" "-I${WALLY}/config/deriv/$(WALLYCONF)" # SOURCES are source files -SOURCES=${WALLY}/src/cvw.sv ${WALLY}/testbench/${TESTBENCH}.sv ${WALLY}/testbench/common/*.sv ${WALLY}/src/*/*.sv ${WALLY}/src/*/*/*.sv +SOURCES=${WALLY}/src/cvw.sv ${WALLY}/testbench/${TESTBENCH}.sv ${WALLY}/testbench/common/*.sv ${WALLY}/src/*/*.sv ${WALLY}/src/*/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*.sv ${WALLY}/addins/verilog-ethernet/*/*/*/*.sv # DEPENDENCIES are configuration files and source files, which leads to recompilation of executables DEPENDENCIES=${WALLY}/config/shared/*.vh $(SOURCES) @@ -45,7 +45,7 @@ default: run run: wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH} mkdir -p $(VERILATOR_DIR)/logs wkdir/$(WALLYCONF)_$(TEST)/V${TESTBENCH} ${ARGTEST} - + profile: obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF) $(VERILATOR_DIR)/obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF) ${ARGTEST} mv gmon.out gmon_$(WALLYCONF).out @@ -82,4 +82,4 @@ obj_dir_profiling/V${TESTBENCH}_$(WALLYCONF): $(DEPENDENCIES) $(SOURCES) clean: - rm -rf $(VERILATOR_DIR)/wkdir $(VERILATOR_DIR)/obj_dir_profiling $(VERILATOR_DIR)/logs $(VERILATOR_DIR)/logs_profiling \ No newline at end of file + rm -rf $(VERILATOR_DIR)/wkdir $(VERILATOR_DIR)/obj_dir_profiling $(VERILATOR_DIR)/logs $(VERILATOR_DIR)/logs_profiling diff --git a/src/cvw.sv b/src/cvw.sv index a06feb0b9..612996654 100644 --- a/src/cvw.sv +++ b/src/cvw.sv @@ -294,6 +294,11 @@ typedef struct packed { int DURLEN ; int DIVb ; int DIVBLEN ; + +// debug tools + logic RVVI_SYNTH_SUPPORTED; + logic [31:0] RVVI_INIT_TIME_OUT; + logic [31:0] RVVI_PACKET_DELAY; } cvw_t; endpackage diff --git a/src/hazard/hazard.sv b/src/hazard/hazard.sv index ed3b6da3a..46ff433cf 100644 --- a/src/hazard/hazard.sv +++ b/src/hazard/hazard.sv @@ -31,7 +31,7 @@ module hazard import cvw::*; #(parameter cvw_t P) ( input logic BPWrongE, CSRWriteFenceM, RetM, TrapM, input logic StructuralStallD, input logic LSUStallM, IFUStallF, - input logic FPUStallD, RVVIStall, + input logic FPUStallD, ExternalStall, input logic DivBusyE, FDivBusyE, input logic wfiM, IntPendingM, // Stall & flush outputs @@ -89,7 +89,7 @@ module hazard import cvw::*; #(parameter cvw_t P) ( // Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1. // assign StallWCause = ((IFUStallF & ~FlushDCause) | LSUStallM) & ~FlushWCause; // Because FlushWCause is a strict subset of FlushDCause, FlushWCause is factored out. - assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause) | RVVIStall; + assign StallWCause = (IFUStallF & ~FlushDCause) | (LSUStallM & ~FlushWCause) | ExternalStall; // Stall each stage for cause or if the next stage is stalled // coverage off: StallFCause is always 0 diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 0d33947c1..cf99b9038 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -100,11 +100,8 @@ module packetizer import cvw::*; #(parameter cvw_t P, // have to count at least 250 ms after reset pulled to wait for the phy to actually be ready // at 20MHz 250 ms is 250e-3 / (1/20e6) = 5,000,000. counter #(32) rstcounter(m_axi_aclk, RstCountRst, RstCountEn, RstCount); - assign CountFlag = RstCount == 32'd100000000; - //assign CountFlag = RstCount == 32'd10; - //assign DelayFlag = RstCount == 32'd800; - assign DelayFlag = RstCount == 32'd350; - //assign DelayFlag = RstCount == 32'd0; + assign CountFlag = RstCount == P.RVVI_INIT_TIME_OUT; + assign DelayFlag = RstCount == P.RVVI_PACKET_DELAY; counter #(32) framecounter(m_axi_aclk, ~m_axi_aresetn, (RvviAxiWready & RvviAxiWlast), FrameCount); diff --git a/src/rvvi/rvvisynth.sv b/src/rvvi/rvvisynth.sv index 16b214e18..7700cc615 100644 --- a/src/rvvi/rvvisynth.sv +++ b/src/rvvi/rvvisynth.sv @@ -27,32 +27,38 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`define FPGA 1 +`define FPGA 0 module rvvisynth import cvw::*; #(parameter cvw_t P, - parameter integer MAX_CSRS)( + parameter integer MAX_CSRS, TOTAL_CSRS = 36)( input logic clk, reset, + input logic StallE, StallM, StallW, FlushE, FlushM, FlushW, + // required + input logic [P.XLEN-1:0] PCM, + input logic InstrValidM, + input logic [31:0] InstrRawD, + input logic [63:0] Mcycle, Minstret, + input logic TrapM, + input logic [1:0] PrivilegeModeW, + // registers gpr and fpr + input logic GPRWen, FPRWen, + input logic [4:0] GPRAddr, FPRAddr, + input logic [P.XLEN-1:0] GPRValue, FPRValue, + input logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0], output logic valid, output logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi ); - localparam TOTAL_CSRS = 36; - // pipeline controlls - logic StallE, StallM, StallW, FlushE, FlushM, FlushW; + // required - logic [P.XLEN-1:0] PCM, PCW; - logic InstrValidM, InstrValidW; - logic [31:0] InstrRawD, InstrRawE, InstrRawM, InstrRawW; - logic [63:0] Mcycle, Minstret; - logic TrapM, TrapW; - logic [1:0] PrivilegeModeW; + logic [P.XLEN-1:0] PCW; + logic InstrValidW; + logic [31:0] InstrRawE, InstrRawM, InstrRawW; + logic TrapW; + // registers gpr and fpr - logic GPRWen, FPRWen; - logic [4:0] GPRAddr, FPRAddr; - logic [P.XLEN-1:0] GPRValue, FPRValue; logic [P.XLEN-1:0] XLENZeros; - logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0]; logic [TOTAL_CSRS-1:0] CSRArrayWen; logic [P.XLEN-1:0] CSRValue [MAX_CSRS-1:0]; logic [TOTAL_CSRS-1:0] CSRWen [MAX_CSRS-1:0]; @@ -61,10 +67,11 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, logic [11:0] CSRCount; logic [177+P.XLEN-1:0] Required; logic [10+2*P.XLEN-1:0] Registers; - logic [MAX_CSRS*(P.XLEN+12)-1:0] CSRs; + logic [MAX_CSRS*(P.XLEN+12)-1:0] CSRs; // get signals from the core. if (`FPGA) begin +/* -----\/----- EXCLUDED -----\/----- assign StallE = fpgaTop.wallypipelinedsoc.core.StallE; assign StallM = fpgaTop.wallypipelinedsoc.core.StallM; assign StallW = fpgaTop.wallypipelinedsoc.core.StallW; @@ -123,7 +130,9 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, assign CSRArray[33] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 assign CSRArray[34] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 assign CSRArray[35] = {fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW, fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 + -----/\----- EXCLUDED -----/\----- */ end else begin // if (`FPGA) +/* -----\/----- EXCLUDED -----\/----- assign StallE = dut.core.StallE; assign StallM = dut.core.StallM; assign StallW = dut.core.StallW; @@ -182,6 +191,7 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, assign CSRArray[33] = dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 assign CSRArray[34] = dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 assign CSRArray[35] = {dut.core.priv.priv.csr.csru.csru.FRM_REGW, dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 + -----/\----- EXCLUDED -----/\----- */ end // diff --git a/src/wally/wallypipelinedcore.sv b/src/wally/wallypipelinedcore.sv index 30efbe90b..fac30193c 100644 --- a/src/wally/wallypipelinedcore.sv +++ b/src/wally/wallypipelinedcore.sv @@ -45,7 +45,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( output logic [3:0] HPROT, output logic [1:0] HTRANS, output logic HMASTLOCK, - input logic RVVIStall + input logic ExternalStall ); logic StallF, StallD, StallE, StallM, StallW; @@ -275,7 +275,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) ( .BPWrongE, .CSRWriteFenceM, .RetM, .TrapM, .StructuralStallD, .LSUStallM, .IFUStallF, - .FPUStallD, .RVVIStall, + .FPUStallD, .ExternalStall, .DivBusyE, .FDivBusyE, .wfiM, .IntPendingM, // Stall & flush outputs diff --git a/src/wally/wallypipelinedsoc.sv b/src/wally/wallypipelinedsoc.sv index 236a653fb..bda183bf9 100644 --- a/src/wally/wallypipelinedsoc.sv +++ b/src/wally/wallypipelinedsoc.sv @@ -37,7 +37,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( output logic HSELEXT, output logic HSELEXTSDC, // fpga debug signals - input logic RVVIStall, + input logic ExternalStall, // outputs to external memory, shared with uncore memory output logic HCLK, HRESETn, output logic [P.PA_BITS-1:0] HADDR, @@ -77,7 +77,7 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) ( wallypipelinedcore #(P) core(.clk, .reset, .MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTIME_CLINT, .HRDATA, .HREADY, .HRESP, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, - .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .RVVIStall + .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .ExternalStall ); // instantiate uncore if a bus interface exists diff --git a/testbench/common/loggers.sv b/testbench/common/loggers.sv index b8a6389cb..967cf672b 100644 --- a/testbench/common/loggers.sv +++ b/testbench/common/loggers.sv @@ -261,11 +261,11 @@ module loggers import cvw::*; #(parameter cvw_t P, $fwrite(file, "BEGIN %s\n", memfilename); $fwrite(CFIfile, "BEGIN %s\n", memfilename); end - if(dut.core.ifu.InstrClassM[0] & ~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin + if(dut.core.ifu.IClassM[0] & ~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin direction = PCSrcM ? "t" : "n"; $fwrite(file, "%h %s\n", dut.core.PCM, direction); end - if((|dut.core.ifu.InstrClassM) & ~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin + if((|dut.core.ifu.IClassM) & ~dut.core.StallW & ~dut.core.FlushW & dut.core.InstrValidM) begin direction = PCSrcM ? "t" : "n"; $fwrite(CFIfile, "%h %s\n", dut.core.PCM, direction); end diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 098280423..a109b1c6f 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -580,7 +580,8 @@ module testbench; assign SDCIntr = 1'b0; end - wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .RVVIStall, .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC, + wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .ExternalStall(RVVIStall), + .HRDATAEXT, .HREADYEXT, .HRESPEXT, .HSELEXT, .HSELEXTSDC, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN, .UARTSin, .UARTSout, .SDCIntr, .SPIIn, .SPIOut, .SPICS); @@ -590,12 +591,91 @@ module testbench; clk = 1'b1; # 5; clk = 1'b0; # 5; end - if(`RVVI_SYNTH_SUPPORTED) begin : rvvi_synth + if(P.RVVI_SYNTH_SUPPORTED) begin : rvvi_synth localparam MAX_CSRS = 3; logic valid; logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; - rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .rvvi); + localparam TOTAL_CSRS = 36; + + // pipeline controlls + logic StallE, StallM, StallW, FlushE, FlushM, FlushW; + // required + logic [P.XLEN-1:0] PCM; + logic InstrValidM; + logic [31:0] InstrRawD; + logic [63:0] Mcycle, Minstret; + logic TrapM; + logic [1:0] PrivilegeModeW; + // registers gpr and fpr + logic GPRWen, FPRWen; + logic [4:0] GPRAddr, FPRAddr; + logic [P.XLEN-1:0] GPRValue, FPRValue; + logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0]; + + assign StallE = dut.core.StallE; + assign StallM = dut.core.StallM; + assign StallW = dut.core.StallW; + assign FlushE = dut.core.FlushE; + assign FlushM = dut.core.FlushM; + assign FlushW = dut.core.FlushW; + assign InstrValidM = dut.core.ieu.InstrValidM; + assign InstrRawD = dut.core.ifu.InstrRawD; + assign PCM = dut.core.ifu.PCM; + assign Mcycle = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; + assign Minstret = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; + assign TrapM = dut.core.TrapM; + assign PrivilegeModeW = dut.core.priv.priv.privmode.PrivilegeModeW; + assign GPRAddr = dut.core.ieu.dp.regf.a3; + assign GPRWen = dut.core.ieu.dp.regf.we3; + assign GPRValue = dut.core.ieu.dp.regf.wd3; + assign FPRAddr = dut.core.fpu.fpu.fregfile.a4; + assign FPRWen = dut.core.fpu.fpu.fregfile.we4; + assign FPRValue = dut.core.fpu.fpu.fregfile.wd4; + + assign CSRArray[0] = dut.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 + assign CSRArray[1] = dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 + assign CSRArray[2] = dut.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 + assign CSRArray[3] = dut.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 + assign CSRArray[4] = dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 + assign CSRArray[5] = dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 + assign CSRArray[6] = dut.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 + assign CSRArray[7] = dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 + assign CSRArray[8] = dut.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 + assign CSRArray[9] = dut.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 + assign CSRArray[10] = dut.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 + assign CSRArray[11] = dut.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A + assign CSRArray[12] = dut.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 + assign CSRArray[13] = dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 + assign CSRArray[14] = dut.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 + assign CSRArray[15] = dut.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 + assign CSRArray[16] = 0; // 12'hF11 + assign CSRArray[17] = 0; // 12'hF12 + assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 + assign CSRArray[19] = 0; // 12'hF15 + assign CSRArray[20] = 0; // 12'h34A + // supervisor CSRs + assign CSRArray[21] = dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 + assign CSRArray[22] = dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 + assign CSRArray[23] = dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 + assign CSRArray[24] = dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 + assign CSRArray[25] = dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 + assign CSRArray[26] = dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A + assign CSRArray[27] = dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 + assign CSRArray[28] = dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 + assign CSRArray[29] = dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 + assign CSRArray[30] = dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 + assign CSRArray[31] = dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 + assign CSRArray[32] = dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D + // user CSRs + assign CSRArray[33] = dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 + assign CSRArray[34] = dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 + assign CSRArray[35] = {dut.core.priv.priv.csr.csru.csru.FRM_REGW, dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 + + rvvisynth #(P, MAX_CSRS, TOTAL_CSRS) rvvisynth(.clk, .reset, .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, + .PCM, .InstrValidM, .InstrRawD, .Mcycle, .Minstret, .TrapM, + .PrivilegeModeW, .GPRWen, .FPRWen, .GPRAddr, .FPRAddr, .GPRValue, .FPRValue, .CSRArray, + .valid, .rvvi); // axi 4 write data channel logic [31:0] RvviAxiWdata; @@ -618,12 +698,11 @@ module testbench; .tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), .rx_axis_tlast(), .rx_axis_tuser(), - // *** update these - .mii_rx_clk(clk), // *** need to be the mii clock + .mii_rx_clk(clk), .mii_rxd('0), .mii_rx_dv('0), .mii_rx_er('0), - .mii_tx_clk(clk), // *** needs to be the mii clock + .mii_tx_clk(clk), .mii_txd, .mii_tx_en, .mii_tx_er, diff --git a/testbench/wallywrapper.sv b/testbench/wallywrapper.sv index 234a11fdf..0cf6940fb 100644 --- a/testbench/wallywrapper.sv +++ b/testbench/wallywrapper.sv @@ -57,7 +57,7 @@ module wallywrapper; logic HREADY; logic HSELEXT; logic HSELEXTSDC; - logic RVVIStall; + logic ExternalStall; // instantiate device to be tested assign GPIOIN = 0; @@ -67,9 +67,9 @@ module wallywrapper; assign HRESPEXT = 0; assign HRDATAEXT = 0; - assign RVVIStall = '0; + assign ExternalStall = '0; - wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .RVVIStall, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, .HSELEXTSDC, + wallypipelinedsoc #(P) dut(.clk, .reset_ext, .reset, .ExternalStall, .HRDATAEXT,.HREADYEXT, .HRESPEXT,.HSELEXT, .HSELEXTSDC, .HCLK, .HRESETn, .HADDR, .HWDATA, .HWSTRB, .HWRITE, .HSIZE, .HBURST, .HPROT, .HTRANS, .HMASTLOCK, .HREADY, .TIMECLK(1'b0), .GPIOIN, .GPIOOUT, .GPIOEN, .UARTSin, .UARTSout, .SPIIn, .SPIOut, .SPICS, .SDCIntr); From 00840e489372abf6669eb6ffb69a98803ab443f8 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Fri, 19 Jul 2024 17:35:30 -0500 Subject: [PATCH 71/95] Made the fpga top level configurable between rvvi synth and not. --- fpga/constraints/small-debug.xdc | 50 +------- fpga/src/fpgaTopArtyA7.sv | 200 ++++++++++++++++--------------- 2 files changed, 108 insertions(+), 142 deletions(-) diff --git a/fpga/constraints/small-debug.xdc b/fpga/constraints/small-debug.xdc index ce824620b..6fef2ba79 100644 --- a/fpga/constraints/small-debug.xdc +++ b/fpga/constraints/small-debug.xdc @@ -21,60 +21,22 @@ set_property port_width 32 [get_debug_ports u_ila_0/probe0] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0] connect_debug_port u_ila_0/probe0 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][0]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][1]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][2]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][3]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][4]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][5]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][6]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][7]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][8]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][9]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][10]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][11]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][12]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][13]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][14]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][15]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][16]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][17]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][18]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][19]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][20]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][21]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][22]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][23]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][24]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][25]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][26]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][27]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][28]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][29]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][30]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][31]} ]] + create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe1] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe1] -connect_debug_port u_ila_0/probe1 [get_nets [list RvviAxiWlast ]] +connect_debug_port u_ila_0/probe1 [get_nets [list wallypipelinedsoc/core/InstrValidM ]] create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe2] +set_property port_width 64 [get_debug_ports u_ila_0/probe2] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe2] -connect_debug_port u_ila_0/probe2 [get_nets [list wallypipelinedsoc/core/InstrValidM ]] +connect_debug_port u_ila_0/probe2 [get_nets [list {wallypipelinedsoc/core/PCM[0]} {wallypipelinedsoc/core/PCM[1]} {wallypipelinedsoc/core/PCM[2]} {wallypipelinedsoc/core/PCM[3]} {wallypipelinedsoc/core/PCM[4]} {wallypipelinedsoc/core/PCM[5]} {wallypipelinedsoc/core/PCM[6]} {wallypipelinedsoc/core/PCM[7]} {wallypipelinedsoc/core/PCM[8]} {wallypipelinedsoc/core/PCM[9]} {wallypipelinedsoc/core/PCM[10]} {wallypipelinedsoc/core/PCM[11]} {wallypipelinedsoc/core/PCM[12]} {wallypipelinedsoc/core/PCM[13]} {wallypipelinedsoc/core/PCM[14]} {wallypipelinedsoc/core/PCM[15]} {wallypipelinedsoc/core/PCM[16]} {wallypipelinedsoc/core/PCM[17]} {wallypipelinedsoc/core/PCM[18]} {wallypipelinedsoc/core/PCM[19]} {wallypipelinedsoc/core/PCM[20]} {wallypipelinedsoc/core/PCM[21]} {wallypipelinedsoc/core/PCM[22]} {wallypipelinedsoc/core/PCM[23]} {wallypipelinedsoc/core/PCM[24]} {wallypipelinedsoc/core/PCM[25]} {wallypipelinedsoc/core/PCM[26]} {wallypipelinedsoc/core/PCM[27]} {wallypipelinedsoc/core/PCM[28]} {wallypipelinedsoc/core/PCM[29]} {wallypipelinedsoc/core/PCM[30]} {wallypipelinedsoc/core/PCM[31]} {wallypipelinedsoc/core/PCM[32]} {wallypipelinedsoc/core/PCM[33]} {wallypipelinedsoc/core/PCM[34]} {wallypipelinedsoc/core/PCM[35]} {wallypipelinedsoc/core/PCM[36]} {wallypipelinedsoc/core/PCM[37]} {wallypipelinedsoc/core/PCM[38]} {wallypipelinedsoc/core/PCM[39]} {wallypipelinedsoc/core/PCM[40]} {wallypipelinedsoc/core/PCM[41]} {wallypipelinedsoc/core/PCM[42]} {wallypipelinedsoc/core/PCM[43]} {wallypipelinedsoc/core/PCM[44]} {wallypipelinedsoc/core/PCM[45]} {wallypipelinedsoc/core/PCM[46]} {wallypipelinedsoc/core/PCM[47]} {wallypipelinedsoc/core/PCM[48]} {wallypipelinedsoc/core/PCM[49]} {wallypipelinedsoc/core/PCM[50]} {wallypipelinedsoc/core/PCM[51]} {wallypipelinedsoc/core/PCM[52]} {wallypipelinedsoc/core/PCM[53]} {wallypipelinedsoc/core/PCM[54]} {wallypipelinedsoc/core/PCM[55]} {wallypipelinedsoc/core/PCM[56]} {wallypipelinedsoc/core/PCM[57]} {wallypipelinedsoc/core/PCM[58]} {wallypipelinedsoc/core/PCM[59]} {wallypipelinedsoc/core/PCM[60]} {wallypipelinedsoc/core/PCM[61]} {wallypipelinedsoc/core/PCM[62]} {wallypipelinedsoc/core/PCM[63]} ]] + create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe3] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe3] -connect_debug_port u_ila_0/probe3 [get_nets [list {RvviAxiRlast}]] - -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe4] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe4] -connect_debug_port u_ila_0/probe4 [get_nets [list {RvviAxiRvalid}]] - -create_debug_port u_ila_0 probe -set_property port_width 4 [get_debug_ports u_ila_0/probe5] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe5] -connect_debug_port u_ila_0/probe5 [get_nets [list {packetizer/CurrState[0]} {packetizer/CurrState[1]} {packetizer/CurrState[2]} {packetizer/CurrState[3]}]] - -create_debug_port u_ila_0 probe -set_property port_width 64 [get_debug_ports u_ila_0/probe6] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6] -connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/PCM[0]} {wallypipelinedsoc/core/PCM[1]} {wallypipelinedsoc/core/PCM[2]} {wallypipelinedsoc/core/PCM[3]} {wallypipelinedsoc/core/PCM[4]} {wallypipelinedsoc/core/PCM[5]} {wallypipelinedsoc/core/PCM[6]} {wallypipelinedsoc/core/PCM[7]} {wallypipelinedsoc/core/PCM[8]} {wallypipelinedsoc/core/PCM[9]} {wallypipelinedsoc/core/PCM[10]} {wallypipelinedsoc/core/PCM[11]} {wallypipelinedsoc/core/PCM[12]} {wallypipelinedsoc/core/PCM[13]} {wallypipelinedsoc/core/PCM[14]} {wallypipelinedsoc/core/PCM[15]} {wallypipelinedsoc/core/PCM[16]} {wallypipelinedsoc/core/PCM[17]} {wallypipelinedsoc/core/PCM[18]} {wallypipelinedsoc/core/PCM[19]} {wallypipelinedsoc/core/PCM[20]} {wallypipelinedsoc/core/PCM[21]} {wallypipelinedsoc/core/PCM[22]} {wallypipelinedsoc/core/PCM[23]} {wallypipelinedsoc/core/PCM[24]} {wallypipelinedsoc/core/PCM[25]} {wallypipelinedsoc/core/PCM[26]} {wallypipelinedsoc/core/PCM[27]} {wallypipelinedsoc/core/PCM[28]} {wallypipelinedsoc/core/PCM[29]} {wallypipelinedsoc/core/PCM[30]} {wallypipelinedsoc/core/PCM[31]} {wallypipelinedsoc/core/PCM[32]} {wallypipelinedsoc/core/PCM[33]} {wallypipelinedsoc/core/PCM[34]} {wallypipelinedsoc/core/PCM[35]} {wallypipelinedsoc/core/PCM[36]} {wallypipelinedsoc/core/PCM[37]} {wallypipelinedsoc/core/PCM[38]} {wallypipelinedsoc/core/PCM[39]} {wallypipelinedsoc/core/PCM[40]} {wallypipelinedsoc/core/PCM[41]} {wallypipelinedsoc/core/PCM[42]} {wallypipelinedsoc/core/PCM[43]} {wallypipelinedsoc/core/PCM[44]} {wallypipelinedsoc/core/PCM[45]} {wallypipelinedsoc/core/PCM[46]} {wallypipelinedsoc/core/PCM[47]} {wallypipelinedsoc/core/PCM[48]} {wallypipelinedsoc/core/PCM[49]} {wallypipelinedsoc/core/PCM[50]} {wallypipelinedsoc/core/PCM[51]} {wallypipelinedsoc/core/PCM[52]} {wallypipelinedsoc/core/PCM[53]} {wallypipelinedsoc/core/PCM[54]} {wallypipelinedsoc/core/PCM[55]} {wallypipelinedsoc/core/PCM[56]} {wallypipelinedsoc/core/PCM[57]} {wallypipelinedsoc/core/PCM[58]} {wallypipelinedsoc/core/PCM[59]} {wallypipelinedsoc/core/PCM[60]} {wallypipelinedsoc/core/PCM[61]} {wallypipelinedsoc/core/PCM[62]} {wallypipelinedsoc/core/PCM[63]} ]] - -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe7] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7] -connect_debug_port u_ila_0/probe7 [get_nets [list {RvviAxiWvalid}]] - -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe8] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe8] -connect_debug_port u_ila_0/probe8 [get_nets [list {RVVIStall}]] - -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe9] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe9] -connect_debug_port u_ila_0/probe9 [get_nets [list {valid}]] - -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe10] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe10] -connect_debug_port u_ila_0/probe10 [get_nets [list {RvviAxiWready}]] - -create_debug_port u_ila_0 probe -set_property port_width 3 [get_debug_ports u_ila_0/probe11] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe11] -connect_debug_port u_ila_0/probe11 [get_nets [list {triggergen/CurrState[0]} {triggergen/CurrState[1]} {triggergen/CurrState[2]}]] +connect_debug_port u_ila_0/probe3 [get_nets [list {RVVIStall}]] # the debug hub has issues with the clocks from the mmcm so lets give up an connect to the 100Mhz input clock. diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index 7fe0a13b0..48a02fb89 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -78,7 +78,7 @@ module fpgaTop wire CPUCLK; wire c0_ddr4_ui_clk_sync_rst; -(* mark_debug = "true" *) wire bus_struct_reset; + wire bus_struct_reset; wire peripheral_reset; wire interconnect_aresetn; wire peripheral_aresetn; @@ -1114,109 +1114,110 @@ module fpgaTop .init_calib_complete(c0_init_calib_complete), .device_temp(device_temp)); - - localparam MAX_CSRS = 3; - localparam TOTAL_CSRS = 36; - - // pipeline controlls - logic StallE, StallM, StallW, FlushE, FlushM, FlushW; - // required - logic [P.XLEN-1:0] PCM; - logic InstrValidM; - logic [31:0] InstrRawD; - logic [63:0] Mcycle, Minstret; - logic TrapM; - logic [1:0] PrivilegeModeW; - // registers gpr and fpr - logic GPRWen, FPRWen; - logic [4:0] GPRAddr, FPRAddr; - logic [P.XLEN-1:0] GPRValue, FPRValue; - logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0]; -(* mark_debug = "true" *) logic valid; - logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; + if(P.RVVI_SYNTH_SUPPORTED) begin : rvvi_synth + localparam MAX_CSRS = 3; + localparam TOTAL_CSRS = 36; + + // pipeline controlls + logic StallE, StallM, StallW, FlushE, FlushM, FlushW; + // required + logic [P.XLEN-1:0] PCM; + logic InstrValidM; + logic [31:0] InstrRawD; + logic [63:0] Mcycle, Minstret; + logic TrapM; + logic [1:0] PrivilegeModeW; + // registers gpr and fpr + logic GPRWen, FPRWen; + logic [4:0] GPRAddr, FPRAddr; + logic [P.XLEN-1:0] GPRValue, FPRValue; + logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0]; - assign StallE = fpgaTop.wallypipelinedsoc.core.StallE; - assign StallM = fpgaTop.wallypipelinedsoc.core.StallM; - assign StallW = fpgaTop.wallypipelinedsoc.core.StallW; - assign FlushE = fpgaTop.wallypipelinedsoc.core.FlushE; - assign FlushM = fpgaTop.wallypipelinedsoc.core.FlushM; - assign FlushW = fpgaTop.wallypipelinedsoc.core.FlushW; - assign InstrValidM = fpgaTop.wallypipelinedsoc.core.ieu.InstrValidM; - assign InstrRawD = fpgaTop.wallypipelinedsoc.core.ifu.InstrRawD; - assign PCM = fpgaTop.wallypipelinedsoc.core.ifu.PCM; - assign Mcycle = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; - assign Minstret = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; - assign TrapM = fpgaTop.wallypipelinedsoc.core.TrapM; - assign PrivilegeModeW = fpgaTop.wallypipelinedsoc.core.priv.priv.privmode.PrivilegeModeW; - assign GPRAddr = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.a3; - assign GPRWen = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.we3; - assign GPRValue = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.wd3; - assign FPRAddr = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.a4; - assign FPRWen = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.we4; - assign FPRValue = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.wd4; + logic valid; + logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; - assign CSRArray[0] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 - assign CSRArray[1] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 - assign CSRArray[2] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 - assign CSRArray[3] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 - assign CSRArray[4] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 - assign CSRArray[5] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 - assign CSRArray[6] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 - assign CSRArray[7] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 - assign CSRArray[8] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 - assign CSRArray[9] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 - assign CSRArray[10] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 - assign CSRArray[11] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A - assign CSRArray[12] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 - assign CSRArray[13] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 - assign CSRArray[14] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 - assign CSRArray[15] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 - assign CSRArray[16] = 0; // 12'hF11 - assign CSRArray[17] = 0; // 12'hF12 - assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 - assign CSRArray[19] = 0; // 12'hF15 - assign CSRArray[20] = 0; // 12'h34A - // supervisor CSRs - assign CSRArray[21] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 - assign CSRArray[22] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 - assign CSRArray[23] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 - assign CSRArray[24] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 - assign CSRArray[25] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 - assign CSRArray[26] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A - assign CSRArray[27] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 - assign CSRArray[28] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 - assign CSRArray[29] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 - assign CSRArray[30] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 - assign CSRArray[31] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 - assign CSRArray[32] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D - // user CSRs - assign CSRArray[33] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 - assign CSRArray[34] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 - assign CSRArray[35] = {fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW, fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 + assign StallE = fpgaTop.wallypipelinedsoc.core.StallE; + assign StallM = fpgaTop.wallypipelinedsoc.core.StallM; + assign StallW = fpgaTop.wallypipelinedsoc.core.StallW; + assign FlushE = fpgaTop.wallypipelinedsoc.core.FlushE; + assign FlushM = fpgaTop.wallypipelinedsoc.core.FlushM; + assign FlushW = fpgaTop.wallypipelinedsoc.core.FlushW; + assign InstrValidM = fpgaTop.wallypipelinedsoc.core.ieu.InstrValidM; + assign InstrRawD = fpgaTop.wallypipelinedsoc.core.ifu.InstrRawD; + assign PCM = fpgaTop.wallypipelinedsoc.core.ifu.PCM; + assign Mcycle = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; + assign Minstret = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; + assign TrapM = fpgaTop.wallypipelinedsoc.core.TrapM; + assign PrivilegeModeW = fpgaTop.wallypipelinedsoc.core.priv.priv.privmode.PrivilegeModeW; + assign GPRAddr = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.a3; + assign GPRWen = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.we3; + assign GPRValue = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.wd3; + assign FPRAddr = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.a4; + assign FPRWen = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.we4; + assign FPRValue = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.wd4; - rvvisynth #(P, MAX_CSRS) rvvisynth(.clk(CPUCLK), .reset(bus_struct_reset), .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, - .PCM, .InstrValidM, .InstrRawD, .Mcycle, .Minstret, .TrapM, - .PrivilegeModeW, .GPRWen, .FPRWen, .GPRAddr, .FPRAddr, .GPRValue, .FPRValue, .CSRArray, - .valid, .rvvi); + assign CSRArray[0] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 + assign CSRArray[1] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 + assign CSRArray[2] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 + assign CSRArray[3] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 + assign CSRArray[4] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 + assign CSRArray[5] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 + assign CSRArray[6] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 + assign CSRArray[7] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 + assign CSRArray[8] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 + assign CSRArray[9] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 + assign CSRArray[10] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 + assign CSRArray[11] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A + assign CSRArray[12] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 + assign CSRArray[13] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 + assign CSRArray[14] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 + assign CSRArray[15] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 + assign CSRArray[16] = 0; // 12'hF11 + assign CSRArray[17] = 0; // 12'hF12 + assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 + assign CSRArray[19] = 0; // 12'hF15 + assign CSRArray[20] = 0; // 12'h34A + // supervisor CSRs + assign CSRArray[21] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 + assign CSRArray[22] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 + assign CSRArray[23] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 + assign CSRArray[24] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 + assign CSRArray[25] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 + assign CSRArray[26] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A + assign CSRArray[27] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 + assign CSRArray[28] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 + assign CSRArray[29] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 + assign CSRArray[30] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 + assign CSRArray[31] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 + assign CSRArray[32] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D + // user CSRs + assign CSRArray[33] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 + assign CSRArray[34] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 + assign CSRArray[35] = {fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW, fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 - // axi 4 write data channel -(* mark_debug = "true" *) logic [31:0] RvviAxiWdata; -(* mark_debug = "true" *) logic [3:0] RvviAxiWstrb; -(* mark_debug = "true" *) logic RvviAxiWlast; -(* mark_debug = "true" *) logic RvviAxiWvalid; -(* mark_debug = "true" *) logic RvviAxiWready; + rvvisynth #(P, MAX_CSRS) rvvisynth(.clk(CPUCLK), .reset(bus_struct_reset), .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, + .PCM, .InstrValidM, .InstrRawD, .Mcycle, .Minstret, .TrapM, + .PrivilegeModeW, .GPRWen, .FPRWen, .GPRAddr, .FPRAddr, .GPRValue, .FPRValue, .CSRArray, + .valid, .rvvi); -(* mark_debug = "true" *) logic [31:0] RvviAxiRdata; - logic [3:0] RvviAxiRstrb; -(* mark_debug = "true" *) logic RvviAxiRlast; -(* mark_debug = "true" *) logic RvviAxiRvalid; -(* mark_debug = "true" *) logic IlaTrigger; - + // axi 4 write data channel + logic [31:0] RvviAxiWdata; + logic [3:0] RvviAxiWstrb; + logic RvviAxiWlast; + logic RvviAxiWvalid; + logic RvviAxiWready; + + logic [31:0] RvviAxiRdata; + logic [3:0] RvviAxiRstrb; + logic RvviAxiRlast; + logic RvviAxiRvalid; + (* mark_debug = "true" *) logic IlaTrigger; + - logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; - logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; + logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; + logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(CPUCLK), .m_axi_aresetn(~bus_struct_reset), .RVVIStall, .RvviAxiWdata, .RvviAxiWstrb, .RvviAxiWlast, .RvviAxiWvalid, .RvviAxiWready); @@ -1242,8 +1243,11 @@ module fpgaTop .cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1) ); - triggergen triggergen(.clk(CPUCLK), .reset(bus_struct_reset), .RvviAxiRdata, - .RvviAxiRstrb, .RvviAxiRlast, .RvviAxiRvalid, .IlaTrigger); + triggergen triggergen(.clk(CPUCLK), .reset(bus_struct_reset), .RvviAxiRdata, + .RvviAxiRstrb, .RvviAxiRlast, .RvviAxiRvalid, .IlaTrigger); + end else begin // if (P.RVVI_SYNTH_SUPPORTED) + assign RVVIStall = '0; + end //assign phy_reset_n = ~bus_struct_reset; assign phy_reset_n = ~1'b0; From 24609f0b7f5f89ede712adcc7a38a1ee83c03360 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 22 Jul 2024 10:51:13 -0500 Subject: [PATCH 72/95] Now have configurations to switch between supporting RVVI over ethernet. --- config/derivlist.txt | 2 +- fpga/constraints/small-debug-rvvi.xdc | 83 +++++++++++++++++++++++++++ fpga/constraints/small-debug.xdc | 56 ++++++++++++------ fpga/src/fpgaTopArtyA7.sv | 9 +-- 4 files changed, 126 insertions(+), 24 deletions(-) create mode 100644 fpga/constraints/small-debug-rvvi.xdc diff --git a/config/derivlist.txt b/config/derivlist.txt index 9535e9833..177cac54f 100644 --- a/config/derivlist.txt +++ b/config/derivlist.txt @@ -56,7 +56,7 @@ EXT_MEM_RANGE 64'h0FFFFFFF SDC_SUPPORTED 1 PLIC_SDC_ID 32'd20 BPRED_SIZE 32'd12 -RVVI_SYNTH_SUPPORTED 1 +RVVI_SYNTH_SUPPORTED 0 RVVI_INIT_TIME_OUT 32'd100000000 RVVI_PACKET_DELAY 32'd350 diff --git a/fpga/constraints/small-debug-rvvi.xdc b/fpga/constraints/small-debug-rvvi.xdc new file mode 100644 index 000000000..f8ebbfe0d --- /dev/null +++ b/fpga/constraints/small-debug-rvvi.xdc @@ -0,0 +1,83 @@ +create_debug_core u_ila_0 ila +set_property C_DATA_DEPTH 8192 [get_debug_cores u_ila_0] +set_property C_TRIGIN_EN true [get_debug_cores u_ila_0] +set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0] +set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0] +set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0] +set_property C_EN_STRG_QUAL true [get_debug_cores u_ila_0 ] +set_property C_ADV_TRIGGER true [get_debug_cores u_ila_0 ] +set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0 ] +set_property ALL_PROBE_SAME_MU_CNT 4 [get_debug_cores u_ila_0 ] +create_debug_port u_ila_0 trig_in +create_debug_port u_ila_0 trig_in_ack +#set_property port_width 1 [get_debug_ports u_ila_0/trig_in] +#set_property port_width 1 [get_debug_ports u_ila_0/trig_in_ack] +#set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/trig_in] +connect_debug_port u_ila_0/trig_in [get_nets IlaTrigger] +#connect_debug_port u_ila_0/trig_in_ack [get_nets IlaTriggerAck] +connect_debug_port u_ila_0/clk [get_nets CPUCLK] + +set_property port_width 32 [get_debug_ports u_ila_0/probe0] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0] +connect_debug_port u_ila_0/probe0 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][0]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][1]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][2]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][3]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][4]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][5]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][6]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][7]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][8]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][9]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][10]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][11]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][12]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][13]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][14]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][15]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][16]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][17]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][18]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][19]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][20]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][21]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][22]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][23]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][24]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][25]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][26]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][27]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][28]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][29]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][30]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][31]} ]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe1] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe1] +connect_debug_port u_ila_0/probe1 [get_nets [list rvvi_synth/RvviAxiWlast ]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe2] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe2] +connect_debug_port u_ila_0/probe2 [get_nets [list wallypipelinedsoc/core/InstrValidM ]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe3] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe3] +connect_debug_port u_ila_0/probe3 [get_nets [list {rvvi_synth/RvviAxiRlast}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe4] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe4] +connect_debug_port u_ila_0/probe4 [get_nets [list {rvvi_synth/RvviAxiRvalid}]] + +create_debug_port u_ila_0 probe +set_property port_width 4 [get_debug_ports u_ila_0/probe5] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe5] +connect_debug_port u_ila_0/probe5 [get_nets [list {rvvi_synth/packetizer/CurrState[0]} {rvvi_synth/packetizer/CurrState[1]} {rvvi_synth/packetizer/CurrState[2]} {rvvi_synth/packetizer/CurrState[3]}]] + +create_debug_port u_ila_0 probe +set_property port_width 64 [get_debug_ports u_ila_0/probe6] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6] +connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/PCM[0]} {wallypipelinedsoc/core/PCM[1]} {wallypipelinedsoc/core/PCM[2]} {wallypipelinedsoc/core/PCM[3]} {wallypipelinedsoc/core/PCM[4]} {wallypipelinedsoc/core/PCM[5]} {wallypipelinedsoc/core/PCM[6]} {wallypipelinedsoc/core/PCM[7]} {wallypipelinedsoc/core/PCM[8]} {wallypipelinedsoc/core/PCM[9]} {wallypipelinedsoc/core/PCM[10]} {wallypipelinedsoc/core/PCM[11]} {wallypipelinedsoc/core/PCM[12]} {wallypipelinedsoc/core/PCM[13]} {wallypipelinedsoc/core/PCM[14]} {wallypipelinedsoc/core/PCM[15]} {wallypipelinedsoc/core/PCM[16]} {wallypipelinedsoc/core/PCM[17]} {wallypipelinedsoc/core/PCM[18]} {wallypipelinedsoc/core/PCM[19]} {wallypipelinedsoc/core/PCM[20]} {wallypipelinedsoc/core/PCM[21]} {wallypipelinedsoc/core/PCM[22]} {wallypipelinedsoc/core/PCM[23]} {wallypipelinedsoc/core/PCM[24]} {wallypipelinedsoc/core/PCM[25]} {wallypipelinedsoc/core/PCM[26]} {wallypipelinedsoc/core/PCM[27]} {wallypipelinedsoc/core/PCM[28]} {wallypipelinedsoc/core/PCM[29]} {wallypipelinedsoc/core/PCM[30]} {wallypipelinedsoc/core/PCM[31]} {wallypipelinedsoc/core/PCM[32]} {wallypipelinedsoc/core/PCM[33]} {wallypipelinedsoc/core/PCM[34]} {wallypipelinedsoc/core/PCM[35]} {wallypipelinedsoc/core/PCM[36]} {wallypipelinedsoc/core/PCM[37]} {wallypipelinedsoc/core/PCM[38]} {wallypipelinedsoc/core/PCM[39]} {wallypipelinedsoc/core/PCM[40]} {wallypipelinedsoc/core/PCM[41]} {wallypipelinedsoc/core/PCM[42]} {wallypipelinedsoc/core/PCM[43]} {wallypipelinedsoc/core/PCM[44]} {wallypipelinedsoc/core/PCM[45]} {wallypipelinedsoc/core/PCM[46]} {wallypipelinedsoc/core/PCM[47]} {wallypipelinedsoc/core/PCM[48]} {wallypipelinedsoc/core/PCM[49]} {wallypipelinedsoc/core/PCM[50]} {wallypipelinedsoc/core/PCM[51]} {wallypipelinedsoc/core/PCM[52]} {wallypipelinedsoc/core/PCM[53]} {wallypipelinedsoc/core/PCM[54]} {wallypipelinedsoc/core/PCM[55]} {wallypipelinedsoc/core/PCM[56]} {wallypipelinedsoc/core/PCM[57]} {wallypipelinedsoc/core/PCM[58]} {wallypipelinedsoc/core/PCM[59]} {wallypipelinedsoc/core/PCM[60]} {wallypipelinedsoc/core/PCM[61]} {wallypipelinedsoc/core/PCM[62]} {wallypipelinedsoc/core/PCM[63]} ]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe7] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7] +connect_debug_port u_ila_0/probe7 [get_nets [list {rvvi_synth/RvviAxiWvalid}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe8] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe8] +connect_debug_port u_ila_0/probe8 [get_nets [list {RVVIStall}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe9] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe9] +connect_debug_port u_ila_0/probe9 [get_nets [list {rvvi_synth/valid}]] + +create_debug_port u_ila_0 probe +set_property port_width 1 [get_debug_ports u_ila_0/probe10] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe10] +connect_debug_port u_ila_0/probe10 [get_nets [list {rvvi_synth/RvviAxiWready}]] + +create_debug_port u_ila_0 probe +set_property port_width 3 [get_debug_ports u_ila_0/probe11] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe11] +connect_debug_port u_ila_0/probe11 [get_nets [list {rvvi_synth/triggergen/CurrState[0]} {rvvi_synth/triggergen/CurrState[1]} {rvvi_synth/triggergen/CurrState[2]}]] + + +# the debug hub has issues with the clocks from the mmcm so lets give up an connect to the 100Mhz input clock. +#connect_debug_port dbg_hub/clk [get_nets default_100mhz_clk] +connect_debug_port dbg_hub/clk [get_nets CPUCLK] + diff --git a/fpga/constraints/small-debug.xdc b/fpga/constraints/small-debug.xdc index 6fef2ba79..b73581ab7 100644 --- a/fpga/constraints/small-debug.xdc +++ b/fpga/constraints/small-debug.xdc @@ -1,45 +1,63 @@ create_debug_core u_ila_0 ila -set_property C_DATA_DEPTH 8192 [get_debug_cores u_ila_0] -set_property C_TRIGIN_EN true [get_debug_cores u_ila_0] + + + + +set_property C_DATA_DEPTH 1024 [get_debug_cores u_ila_0] +set_property C_TRIGIN_EN false [get_debug_cores u_ila_0] set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0] +set_property C_ADV_TRIGGER false [get_debug_cores u_ila_0] set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0] +set_property C_EN_STRG_QUAL false [get_debug_cores u_ila_0] set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0] +set_property ALL_PROBE_SAME_MU_CNT 1 [get_debug_cores u_ila_0] +startgroup set_property C_EN_STRG_QUAL true [get_debug_cores u_ila_0 ] set_property C_ADV_TRIGGER true [get_debug_cores u_ila_0 ] set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0 ] set_property ALL_PROBE_SAME_MU_CNT 4 [get_debug_cores u_ila_0 ] -create_debug_port u_ila_0 trig_in -create_debug_port u_ila_0 trig_in_ack -#set_property port_width 1 [get_debug_ports u_ila_0/trig_in] -#set_property port_width 1 [get_debug_ports u_ila_0/trig_in_ack] -#set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/trig_in] -connect_debug_port u_ila_0/trig_in [get_nets IlaTrigger] -#connect_debug_port u_ila_0/trig_in_ack [get_nets IlaTriggerAck] +endgroup connect_debug_port u_ila_0/clk [get_nets CPUCLK] -set_property port_width 32 [get_debug_ports u_ila_0/probe0] +set_property port_width 64 [get_debug_ports u_ila_0/probe0] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0] -connect_debug_port u_ila_0/probe0 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][0]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][1]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][2]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][3]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][4]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][5]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][6]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][7]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][8]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][9]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][10]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][11]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][12]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][13]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][14]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][15]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][16]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][17]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][18]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][19]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][20]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][21]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][22]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][23]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][24]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][25]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][26]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][27]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][28]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][29]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][30]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][31]} ]] - +connect_debug_port u_ila_0/probe0 [get_nets [list {wallypipelinedsoc/core/PCM[0]} {wallypipelinedsoc/core/PCM[1]} {wallypipelinedsoc/core/PCM[2]} {wallypipelinedsoc/core/PCM[3]} {wallypipelinedsoc/core/PCM[4]} {wallypipelinedsoc/core/PCM[5]} {wallypipelinedsoc/core/PCM[6]} {wallypipelinedsoc/core/PCM[7]} {wallypipelinedsoc/core/PCM[8]} {wallypipelinedsoc/core/PCM[9]} {wallypipelinedsoc/core/PCM[10]} {wallypipelinedsoc/core/PCM[11]} {wallypipelinedsoc/core/PCM[12]} {wallypipelinedsoc/core/PCM[13]} {wallypipelinedsoc/core/PCM[14]} {wallypipelinedsoc/core/PCM[15]} {wallypipelinedsoc/core/PCM[16]} {wallypipelinedsoc/core/PCM[17]} {wallypipelinedsoc/core/PCM[18]} {wallypipelinedsoc/core/PCM[19]} {wallypipelinedsoc/core/PCM[20]} {wallypipelinedsoc/core/PCM[21]} {wallypipelinedsoc/core/PCM[22]} {wallypipelinedsoc/core/PCM[23]} {wallypipelinedsoc/core/PCM[24]} {wallypipelinedsoc/core/PCM[25]} {wallypipelinedsoc/core/PCM[26]} {wallypipelinedsoc/core/PCM[27]} {wallypipelinedsoc/core/PCM[28]} {wallypipelinedsoc/core/PCM[29]} {wallypipelinedsoc/core/PCM[30]} {wallypipelinedsoc/core/PCM[31]} {wallypipelinedsoc/core/PCM[32]} {wallypipelinedsoc/core/PCM[33]} {wallypipelinedsoc/core/PCM[34]} {wallypipelinedsoc/core/PCM[35]} {wallypipelinedsoc/core/PCM[36]} {wallypipelinedsoc/core/PCM[37]} {wallypipelinedsoc/core/PCM[38]} {wallypipelinedsoc/core/PCM[39]} {wallypipelinedsoc/core/PCM[40]} {wallypipelinedsoc/core/PCM[41]} {wallypipelinedsoc/core/PCM[42]} {wallypipelinedsoc/core/PCM[43]} {wallypipelinedsoc/core/PCM[44]} {wallypipelinedsoc/core/PCM[45]} {wallypipelinedsoc/core/PCM[46]} {wallypipelinedsoc/core/PCM[47]} {wallypipelinedsoc/core/PCM[48]} {wallypipelinedsoc/core/PCM[49]} {wallypipelinedsoc/core/PCM[50]} {wallypipelinedsoc/core/PCM[51]} {wallypipelinedsoc/core/PCM[52]} {wallypipelinedsoc/core/PCM[53]} {wallypipelinedsoc/core/PCM[54]} {wallypipelinedsoc/core/PCM[55]} {wallypipelinedsoc/core/PCM[56]} {wallypipelinedsoc/core/PCM[57]} {wallypipelinedsoc/core/PCM[58]} {wallypipelinedsoc/core/PCM[59]} {wallypipelinedsoc/core/PCM[60]} {wallypipelinedsoc/core/PCM[61]} {wallypipelinedsoc/core/PCM[62]} {wallypipelinedsoc/core/PCM[63]} ]] create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe1] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe1] -connect_debug_port u_ila_0/probe1 [get_nets [list wallypipelinedsoc/core/InstrValidM ]] +connect_debug_port u_ila_0/probe1 [get_nets [list wallypipelinedsoc/core/TrapM ]] create_debug_port u_ila_0 probe -set_property port_width 64 [get_debug_ports u_ila_0/probe2] +set_property port_width 1 [get_debug_ports u_ila_0/probe2] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe2] -connect_debug_port u_ila_0/probe2 [get_nets [list {wallypipelinedsoc/core/PCM[0]} {wallypipelinedsoc/core/PCM[1]} {wallypipelinedsoc/core/PCM[2]} {wallypipelinedsoc/core/PCM[3]} {wallypipelinedsoc/core/PCM[4]} {wallypipelinedsoc/core/PCM[5]} {wallypipelinedsoc/core/PCM[6]} {wallypipelinedsoc/core/PCM[7]} {wallypipelinedsoc/core/PCM[8]} {wallypipelinedsoc/core/PCM[9]} {wallypipelinedsoc/core/PCM[10]} {wallypipelinedsoc/core/PCM[11]} {wallypipelinedsoc/core/PCM[12]} {wallypipelinedsoc/core/PCM[13]} {wallypipelinedsoc/core/PCM[14]} {wallypipelinedsoc/core/PCM[15]} {wallypipelinedsoc/core/PCM[16]} {wallypipelinedsoc/core/PCM[17]} {wallypipelinedsoc/core/PCM[18]} {wallypipelinedsoc/core/PCM[19]} {wallypipelinedsoc/core/PCM[20]} {wallypipelinedsoc/core/PCM[21]} {wallypipelinedsoc/core/PCM[22]} {wallypipelinedsoc/core/PCM[23]} {wallypipelinedsoc/core/PCM[24]} {wallypipelinedsoc/core/PCM[25]} {wallypipelinedsoc/core/PCM[26]} {wallypipelinedsoc/core/PCM[27]} {wallypipelinedsoc/core/PCM[28]} {wallypipelinedsoc/core/PCM[29]} {wallypipelinedsoc/core/PCM[30]} {wallypipelinedsoc/core/PCM[31]} {wallypipelinedsoc/core/PCM[32]} {wallypipelinedsoc/core/PCM[33]} {wallypipelinedsoc/core/PCM[34]} {wallypipelinedsoc/core/PCM[35]} {wallypipelinedsoc/core/PCM[36]} {wallypipelinedsoc/core/PCM[37]} {wallypipelinedsoc/core/PCM[38]} {wallypipelinedsoc/core/PCM[39]} {wallypipelinedsoc/core/PCM[40]} {wallypipelinedsoc/core/PCM[41]} {wallypipelinedsoc/core/PCM[42]} {wallypipelinedsoc/core/PCM[43]} {wallypipelinedsoc/core/PCM[44]} {wallypipelinedsoc/core/PCM[45]} {wallypipelinedsoc/core/PCM[46]} {wallypipelinedsoc/core/PCM[47]} {wallypipelinedsoc/core/PCM[48]} {wallypipelinedsoc/core/PCM[49]} {wallypipelinedsoc/core/PCM[50]} {wallypipelinedsoc/core/PCM[51]} {wallypipelinedsoc/core/PCM[52]} {wallypipelinedsoc/core/PCM[53]} {wallypipelinedsoc/core/PCM[54]} {wallypipelinedsoc/core/PCM[55]} {wallypipelinedsoc/core/PCM[56]} {wallypipelinedsoc/core/PCM[57]} {wallypipelinedsoc/core/PCM[58]} {wallypipelinedsoc/core/PCM[59]} {wallypipelinedsoc/core/PCM[60]} {wallypipelinedsoc/core/PCM[61]} {wallypipelinedsoc/core/PCM[62]} {wallypipelinedsoc/core/PCM[63]} ]] - +connect_debug_port u_ila_0/probe2 [get_nets [list wallypipelinedsoc/core/InstrValidM ]] create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe3] +set_property port_width 32 [get_debug_ports u_ila_0/probe3] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe3] -connect_debug_port u_ila_0/probe3 [get_nets [list {RVVIStall}]] +connect_debug_port u_ila_0/probe3 [get_nets [list {wallypipelinedsoc/core/InstrM[0]} {wallypipelinedsoc/core/InstrM[1]} {wallypipelinedsoc/core/InstrM[2]} {wallypipelinedsoc/core/InstrM[3]} {wallypipelinedsoc/core/InstrM[4]} {wallypipelinedsoc/core/InstrM[5]} {wallypipelinedsoc/core/InstrM[6]} {wallypipelinedsoc/core/InstrM[7]} {wallypipelinedsoc/core/InstrM[8]} {wallypipelinedsoc/core/InstrM[9]} {wallypipelinedsoc/core/InstrM[10]} {wallypipelinedsoc/core/InstrM[11]} {wallypipelinedsoc/core/InstrM[12]} {wallypipelinedsoc/core/InstrM[13]} {wallypipelinedsoc/core/InstrM[14]} {wallypipelinedsoc/core/InstrM[15]} {wallypipelinedsoc/core/InstrM[16]} {wallypipelinedsoc/core/InstrM[17]} {wallypipelinedsoc/core/InstrM[18]} {wallypipelinedsoc/core/InstrM[19]} {wallypipelinedsoc/core/InstrM[20]} {wallypipelinedsoc/core/InstrM[21]} {wallypipelinedsoc/core/InstrM[22]} {wallypipelinedsoc/core/InstrM[23]} {wallypipelinedsoc/core/InstrM[24]} {wallypipelinedsoc/core/InstrM[25]} {wallypipelinedsoc/core/InstrM[26]} {wallypipelinedsoc/core/InstrM[27]} {wallypipelinedsoc/core/InstrM[28]} {wallypipelinedsoc/core/InstrM[29]} {wallypipelinedsoc/core/InstrM[30]} {wallypipelinedsoc/core/InstrM[31]} ]] +create_debug_port u_ila_0 probe +set_property port_width 2 [get_debug_ports u_ila_0/probe4] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe4] +connect_debug_port u_ila_0/probe4 [get_nets [list {wallypipelinedsoc/core/lsu/MemRWM[0]} {wallypipelinedsoc/core/lsu/MemRWM[1]} ]] + +create_debug_port u_ila_0 probe +set_property port_width 64 [get_debug_ports u_ila_0/probe5] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe5] +connect_debug_port u_ila_0/probe5 [get_nets [list {wallypipelinedsoc/core/lsu/IEUAdrM[0]} {wallypipelinedsoc/core/lsu/IEUAdrM[1]} {wallypipelinedsoc/core/lsu/IEUAdrM[2]} {wallypipelinedsoc/core/lsu/IEUAdrM[3]} {wallypipelinedsoc/core/lsu/IEUAdrM[4]} {wallypipelinedsoc/core/lsu/IEUAdrM[5]} {wallypipelinedsoc/core/lsu/IEUAdrM[6]} {wallypipelinedsoc/core/lsu/IEUAdrM[7]} {wallypipelinedsoc/core/lsu/IEUAdrM[8]} {wallypipelinedsoc/core/lsu/IEUAdrM[9]} {wallypipelinedsoc/core/lsu/IEUAdrM[10]} {wallypipelinedsoc/core/lsu/IEUAdrM[11]} {wallypipelinedsoc/core/lsu/IEUAdrM[12]} {wallypipelinedsoc/core/lsu/IEUAdrM[13]} {wallypipelinedsoc/core/lsu/IEUAdrM[14]} {wallypipelinedsoc/core/lsu/IEUAdrM[15]} {wallypipelinedsoc/core/lsu/IEUAdrM[16]} {wallypipelinedsoc/core/lsu/IEUAdrM[17]} {wallypipelinedsoc/core/lsu/IEUAdrM[18]} {wallypipelinedsoc/core/lsu/IEUAdrM[19]} {wallypipelinedsoc/core/lsu/IEUAdrM[20]} {wallypipelinedsoc/core/lsu/IEUAdrM[21]} {wallypipelinedsoc/core/lsu/IEUAdrM[22]} {wallypipelinedsoc/core/lsu/IEUAdrM[23]} {wallypipelinedsoc/core/lsu/IEUAdrM[24]} {wallypipelinedsoc/core/lsu/IEUAdrM[25]} {wallypipelinedsoc/core/lsu/IEUAdrM[26]} {wallypipelinedsoc/core/lsu/IEUAdrM[27]} {wallypipelinedsoc/core/lsu/IEUAdrM[28]} {wallypipelinedsoc/core/lsu/IEUAdrM[29]} {wallypipelinedsoc/core/lsu/IEUAdrM[30]} {wallypipelinedsoc/core/lsu/IEUAdrM[31]} {wallypipelinedsoc/core/lsu/IEUAdrM[32]} {wallypipelinedsoc/core/lsu/IEUAdrM[33]} {wallypipelinedsoc/core/lsu/IEUAdrM[34]} {wallypipelinedsoc/core/lsu/IEUAdrM[35]} {wallypipelinedsoc/core/lsu/IEUAdrM[36]} {wallypipelinedsoc/core/lsu/IEUAdrM[37]} {wallypipelinedsoc/core/lsu/IEUAdrM[38]} {wallypipelinedsoc/core/lsu/IEUAdrM[39]} {wallypipelinedsoc/core/lsu/IEUAdrM[40]} {wallypipelinedsoc/core/lsu/IEUAdrM[41]} {wallypipelinedsoc/core/lsu/IEUAdrM[42]} {wallypipelinedsoc/core/lsu/IEUAdrM[43]} {wallypipelinedsoc/core/lsu/IEUAdrM[44]} {wallypipelinedsoc/core/lsu/IEUAdrM[45]} {wallypipelinedsoc/core/lsu/IEUAdrM[46]} {wallypipelinedsoc/core/lsu/IEUAdrM[47]} {wallypipelinedsoc/core/lsu/IEUAdrM[48]} {wallypipelinedsoc/core/lsu/IEUAdrM[49]} {wallypipelinedsoc/core/lsu/IEUAdrM[50]} {wallypipelinedsoc/core/lsu/IEUAdrM[51]} {wallypipelinedsoc/core/lsu/IEUAdrM[52]} {wallypipelinedsoc/core/lsu/IEUAdrM[53]} {wallypipelinedsoc/core/lsu/IEUAdrM[54]} {wallypipelinedsoc/core/lsu/IEUAdrM[55]} {wallypipelinedsoc/core/lsu/IEUAdrM[56]} {wallypipelinedsoc/core/lsu/IEUAdrM[57]} {wallypipelinedsoc/core/lsu/IEUAdrM[58]} {wallypipelinedsoc/core/lsu/IEUAdrM[59]} {wallypipelinedsoc/core/lsu/IEUAdrM[60]} {wallypipelinedsoc/core/lsu/IEUAdrM[61]} {wallypipelinedsoc/core/lsu/IEUAdrM[62]} {wallypipelinedsoc/core/lsu/IEUAdrM[63]} ]] + +create_debug_port u_ila_0 probe +set_property port_width 64 [get_debug_ports u_ila_0/probe6] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6] +connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/lsu/ReadDataM[0]} {wallypipelinedsoc/core/lsu/ReadDataM[1]} {wallypipelinedsoc/core/lsu/ReadDataM[2]} {wallypipelinedsoc/core/lsu/ReadDataM[3]} {wallypipelinedsoc/core/lsu/ReadDataM[4]} {wallypipelinedsoc/core/lsu/ReadDataM[5]} {wallypipelinedsoc/core/lsu/ReadDataM[6]} {wallypipelinedsoc/core/lsu/ReadDataM[7]} {wallypipelinedsoc/core/lsu/ReadDataM[8]} {wallypipelinedsoc/core/lsu/ReadDataM[9]} {wallypipelinedsoc/core/lsu/ReadDataM[10]} {wallypipelinedsoc/core/lsu/ReadDataM[11]} {wallypipelinedsoc/core/lsu/ReadDataM[12]} {wallypipelinedsoc/core/lsu/ReadDataM[13]} {wallypipelinedsoc/core/lsu/ReadDataM[14]} {wallypipelinedsoc/core/lsu/ReadDataM[15]} {wallypipelinedsoc/core/lsu/ReadDataM[16]} {wallypipelinedsoc/core/lsu/ReadDataM[17]} {wallypipelinedsoc/core/lsu/ReadDataM[18]} {wallypipelinedsoc/core/lsu/ReadDataM[19]} {wallypipelinedsoc/core/lsu/ReadDataM[20]} {wallypipelinedsoc/core/lsu/ReadDataM[21]} {wallypipelinedsoc/core/lsu/ReadDataM[22]} {wallypipelinedsoc/core/lsu/ReadDataM[23]} {wallypipelinedsoc/core/lsu/ReadDataM[24]} {wallypipelinedsoc/core/lsu/ReadDataM[25]} {wallypipelinedsoc/core/lsu/ReadDataM[26]} {wallypipelinedsoc/core/lsu/ReadDataM[27]} {wallypipelinedsoc/core/lsu/ReadDataM[28]} {wallypipelinedsoc/core/lsu/ReadDataM[29]} {wallypipelinedsoc/core/lsu/ReadDataM[30]} {wallypipelinedsoc/core/lsu/ReadDataM[31]} {wallypipelinedsoc/core/lsu/ReadDataM[32]} {wallypipelinedsoc/core/lsu/ReadDataM[33]} {wallypipelinedsoc/core/lsu/ReadDataM[34]} {wallypipelinedsoc/core/lsu/ReadDataM[35]} {wallypipelinedsoc/core/lsu/ReadDataM[36]} {wallypipelinedsoc/core/lsu/ReadDataM[37]} {wallypipelinedsoc/core/lsu/ReadDataM[38]} {wallypipelinedsoc/core/lsu/ReadDataM[39]} {wallypipelinedsoc/core/lsu/ReadDataM[40]} {wallypipelinedsoc/core/lsu/ReadDataM[41]} {wallypipelinedsoc/core/lsu/ReadDataM[42]} {wallypipelinedsoc/core/lsu/ReadDataM[43]} {wallypipelinedsoc/core/lsu/ReadDataM[44]} {wallypipelinedsoc/core/lsu/ReadDataM[45]} {wallypipelinedsoc/core/lsu/ReadDataM[46]} {wallypipelinedsoc/core/lsu/ReadDataM[47]} {wallypipelinedsoc/core/lsu/ReadDataM[48]} {wallypipelinedsoc/core/lsu/ReadDataM[49]} {wallypipelinedsoc/core/lsu/ReadDataM[50]} {wallypipelinedsoc/core/lsu/ReadDataM[51]} {wallypipelinedsoc/core/lsu/ReadDataM[52]} {wallypipelinedsoc/core/lsu/ReadDataM[53]} {wallypipelinedsoc/core/lsu/ReadDataM[54]} {wallypipelinedsoc/core/lsu/ReadDataM[55]} {wallypipelinedsoc/core/lsu/ReadDataM[56]} {wallypipelinedsoc/core/lsu/ReadDataM[57]} {wallypipelinedsoc/core/lsu/ReadDataM[58]} {wallypipelinedsoc/core/lsu/ReadDataM[59]} {wallypipelinedsoc/core/lsu/ReadDataM[60]} {wallypipelinedsoc/core/lsu/ReadDataM[61]} {wallypipelinedsoc/core/lsu/ReadDataM[62]} {wallypipelinedsoc/core/lsu/ReadDataM[63]} ]] + +create_debug_port u_ila_0 probe +set_property port_width 64 [get_debug_ports u_ila_0/probe7] +set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7] +connect_debug_port u_ila_0/probe7 [get_nets [list {wallypipelinedsoc/core/lsu/WriteDataM[0]} {wallypipelinedsoc/core/lsu/WriteDataM[1]} {wallypipelinedsoc/core/lsu/WriteDataM[2]} {wallypipelinedsoc/core/lsu/WriteDataM[3]} {wallypipelinedsoc/core/lsu/WriteDataM[4]} {wallypipelinedsoc/core/lsu/WriteDataM[5]} {wallypipelinedsoc/core/lsu/WriteDataM[6]} {wallypipelinedsoc/core/lsu/WriteDataM[7]} {wallypipelinedsoc/core/lsu/WriteDataM[8]} {wallypipelinedsoc/core/lsu/WriteDataM[9]} {wallypipelinedsoc/core/lsu/WriteDataM[10]} {wallypipelinedsoc/core/lsu/WriteDataM[11]} {wallypipelinedsoc/core/lsu/WriteDataM[12]} {wallypipelinedsoc/core/lsu/WriteDataM[13]} {wallypipelinedsoc/core/lsu/WriteDataM[14]} {wallypipelinedsoc/core/lsu/WriteDataM[15]} {wallypipelinedsoc/core/lsu/WriteDataM[16]} {wallypipelinedsoc/core/lsu/WriteDataM[17]} {wallypipelinedsoc/core/lsu/WriteDataM[18]} {wallypipelinedsoc/core/lsu/WriteDataM[19]} {wallypipelinedsoc/core/lsu/WriteDataM[20]} {wallypipelinedsoc/core/lsu/WriteDataM[21]} {wallypipelinedsoc/core/lsu/WriteDataM[22]} {wallypipelinedsoc/core/lsu/WriteDataM[23]} {wallypipelinedsoc/core/lsu/WriteDataM[24]} {wallypipelinedsoc/core/lsu/WriteDataM[25]} {wallypipelinedsoc/core/lsu/WriteDataM[26]} {wallypipelinedsoc/core/lsu/WriteDataM[27]} {wallypipelinedsoc/core/lsu/WriteDataM[28]} {wallypipelinedsoc/core/lsu/WriteDataM[29]} {wallypipelinedsoc/core/lsu/WriteDataM[30]} {wallypipelinedsoc/core/lsu/WriteDataM[31]} {wallypipelinedsoc/core/lsu/WriteDataM[32]} {wallypipelinedsoc/core/lsu/WriteDataM[33]} {wallypipelinedsoc/core/lsu/WriteDataM[34]} {wallypipelinedsoc/core/lsu/WriteDataM[35]} {wallypipelinedsoc/core/lsu/WriteDataM[36]} {wallypipelinedsoc/core/lsu/WriteDataM[37]} {wallypipelinedsoc/core/lsu/WriteDataM[38]} {wallypipelinedsoc/core/lsu/WriteDataM[39]} {wallypipelinedsoc/core/lsu/WriteDataM[40]} {wallypipelinedsoc/core/lsu/WriteDataM[41]} {wallypipelinedsoc/core/lsu/WriteDataM[42]} {wallypipelinedsoc/core/lsu/WriteDataM[43]} {wallypipelinedsoc/core/lsu/WriteDataM[44]} {wallypipelinedsoc/core/lsu/WriteDataM[45]} {wallypipelinedsoc/core/lsu/WriteDataM[46]} {wallypipelinedsoc/core/lsu/WriteDataM[47]} {wallypipelinedsoc/core/lsu/WriteDataM[48]} {wallypipelinedsoc/core/lsu/WriteDataM[49]} {wallypipelinedsoc/core/lsu/WriteDataM[50]} {wallypipelinedsoc/core/lsu/WriteDataM[51]} {wallypipelinedsoc/core/lsu/WriteDataM[52]} {wallypipelinedsoc/core/lsu/WriteDataM[53]} {wallypipelinedsoc/core/lsu/WriteDataM[54]} {wallypipelinedsoc/core/lsu/WriteDataM[55]} {wallypipelinedsoc/core/lsu/WriteDataM[56]} {wallypipelinedsoc/core/lsu/WriteDataM[57]} {wallypipelinedsoc/core/lsu/WriteDataM[58]} {wallypipelinedsoc/core/lsu/WriteDataM[59]} {wallypipelinedsoc/core/lsu/WriteDataM[60]} {wallypipelinedsoc/core/lsu/WriteDataM[61]} {wallypipelinedsoc/core/lsu/WriteDataM[62]} {wallypipelinedsoc/core/lsu/WriteDataM[63]} ]] # the debug hub has issues with the clocks from the mmcm so lets give up an connect to the 100Mhz input clock. #connect_debug_port dbg_hub/clk [get_nets default_100mhz_clk] connect_debug_port dbg_hub/clk [get_nets CPUCLK] - diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index 48a02fb89..4fe8ce183 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -1115,6 +1115,9 @@ module fpgaTop .init_calib_complete(c0_init_calib_complete), .device_temp(device_temp)); + (* mark_debug = "true" *) logic IlaTrigger; + + if(P.RVVI_SYNTH_SUPPORTED) begin : rvvi_synth localparam MAX_CSRS = 3; localparam TOTAL_CSRS = 36; @@ -1212,9 +1215,6 @@ module fpgaTop logic [3:0] RvviAxiRstrb; logic RvviAxiRlast; logic RvviAxiRvalid; - (* mark_debug = "true" *) logic IlaTrigger; - - logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; @@ -1246,11 +1246,12 @@ module fpgaTop triggergen triggergen(.clk(CPUCLK), .reset(bus_struct_reset), .RvviAxiRdata, .RvviAxiRstrb, .RvviAxiRlast, .RvviAxiRvalid, .IlaTrigger); end else begin // if (P.RVVI_SYNTH_SUPPORTED) + assign IlaTrigger = '0; assign RVVIStall = '0; end //assign phy_reset_n = ~bus_struct_reset; assign phy_reset_n = ~1'b0; - + endmodule From efa99940c5a397f41cb571b03718008eac962610 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 22 Jul 2024 12:19:37 -0500 Subject: [PATCH 73/95] Added option to use rvvi ila --- fpga/generator/wally.tcl | 1 + 1 file changed, 1 insertion(+) diff --git a/fpga/generator/wally.tcl b/fpga/generator/wally.tcl index eff0a6cb9..9df775646 100644 --- a/fpga/generator/wally.tcl +++ b/fpga/generator/wally.tcl @@ -90,6 +90,7 @@ write_verilog -force -mode funcsim sim/syn-funcsim.v if {$board=="ArtyA7"} { source ../constraints/small-debug.xdc + #source ../constraints/small-debug-rvvi.xdc } else { # source ../constraints/vcu-small-debug.xdc From 35e69944fa3ae046ab321115ba37050ad447f443 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 22 Jul 2024 12:22:41 -0500 Subject: [PATCH 74/95] Cleaned up rvvisynth.sv --- src/rvvi/rvvisynth.sv | 126 ------------------------------------------ 1 file changed, 126 deletions(-) diff --git a/src/rvvi/rvvisynth.sv b/src/rvvi/rvvisynth.sv index 7700cc615..cbf7c30bf 100644 --- a/src/rvvi/rvvisynth.sv +++ b/src/rvvi/rvvisynth.sv @@ -69,132 +69,6 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, logic [10+2*P.XLEN-1:0] Registers; logic [MAX_CSRS*(P.XLEN+12)-1:0] CSRs; - // get signals from the core. - if (`FPGA) begin -/* -----\/----- EXCLUDED -----\/----- - assign StallE = fpgaTop.wallypipelinedsoc.core.StallE; - assign StallM = fpgaTop.wallypipelinedsoc.core.StallM; - assign StallW = fpgaTop.wallypipelinedsoc.core.StallW; - assign FlushE = fpgaTop.wallypipelinedsoc.core.FlushE; - assign FlushM = fpgaTop.wallypipelinedsoc.core.FlushM; - assign FlushW = fpgaTop.wallypipelinedsoc.core.FlushW; - assign InstrValidM = fpgaTop.wallypipelinedsoc.core.ieu.InstrValidM; - assign InstrRawD = fpgaTop.wallypipelinedsoc.core.ifu.InstrRawD; - assign PCM = fpgaTop.wallypipelinedsoc.core.ifu.PCM; - assign Mcycle = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; - assign Minstret = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; - assign TrapM = fpgaTop.wallypipelinedsoc.core.TrapM; - assign PrivilegeModeW = fpgaTop.wallypipelinedsoc.core.priv.priv.privmode.PrivilegeModeW; - assign GPRAddr = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.a3; - assign GPRWen = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.we3; - assign GPRValue = fpgaTop.wallypipelinedsoc.core.ieu.dp.regf.wd3; - assign FPRAddr = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.a4; - assign FPRWen = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.we4; - assign FPRValue = fpgaTop.wallypipelinedsoc.core.fpu.fpu.fregfile.wd4; - - assign CSRArray[0] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 - assign CSRArray[1] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 - assign CSRArray[2] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 - assign CSRArray[3] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 - assign CSRArray[4] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 - assign CSRArray[5] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 - assign CSRArray[6] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 - assign CSRArray[7] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 - assign CSRArray[8] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 - assign CSRArray[9] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 - assign CSRArray[10] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 - assign CSRArray[11] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A - assign CSRArray[12] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 - assign CSRArray[13] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 - assign CSRArray[14] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 - assign CSRArray[15] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 - assign CSRArray[16] = 0; // 12'hF11 - assign CSRArray[17] = 0; // 12'hF12 - assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 - assign CSRArray[19] = 0; // 12'hF15 - assign CSRArray[20] = 0; // 12'h34A - // supervisor CSRs - assign CSRArray[21] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 - assign CSRArray[22] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 - assign CSRArray[23] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 - assign CSRArray[24] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 - assign CSRArray[25] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 - assign CSRArray[26] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A - assign CSRArray[27] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 - assign CSRArray[28] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 - assign CSRArray[29] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 - assign CSRArray[30] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 - assign CSRArray[31] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 - assign CSRArray[32] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D - // user CSRs - assign CSRArray[33] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 - assign CSRArray[34] = fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 - assign CSRArray[35] = {fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FRM_REGW, fpgaTop.wallypipelinedsoc.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 - -----/\----- EXCLUDED -----/\----- */ - end else begin // if (`FPGA) -/* -----\/----- EXCLUDED -----\/----- - assign StallE = dut.core.StallE; - assign StallM = dut.core.StallM; - assign StallW = dut.core.StallW; - assign FlushE = dut.core.FlushE; - assign FlushM = dut.core.FlushM; - assign FlushW = dut.core.FlushW; - assign InstrValidM = dut.core.ieu.InstrValidM; - assign InstrRawD = dut.core.ifu.InstrRawD; - assign PCM = dut.core.ifu.PCM; - assign Mcycle = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; - assign Minstret = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; - assign TrapM = dut.core.TrapM; - assign PrivilegeModeW = dut.core.priv.priv.privmode.PrivilegeModeW; - assign GPRAddr = dut.core.ieu.dp.regf.a3; - assign GPRWen = dut.core.ieu.dp.regf.we3; - assign GPRValue = dut.core.ieu.dp.regf.wd3; - assign FPRAddr = dut.core.fpu.fpu.fregfile.a4; - assign FPRWen = dut.core.fpu.fpu.fregfile.we4; - assign FPRValue = dut.core.fpu.fpu.fregfile.wd4; - - assign CSRArray[0] = dut.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 - assign CSRArray[1] = dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 - assign CSRArray[2] = dut.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 - assign CSRArray[3] = dut.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 - assign CSRArray[4] = dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 - assign CSRArray[5] = dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 - assign CSRArray[6] = dut.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 - assign CSRArray[7] = dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 - assign CSRArray[8] = dut.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 - assign CSRArray[9] = dut.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 - assign CSRArray[10] = dut.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 - assign CSRArray[11] = dut.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A - assign CSRArray[12] = dut.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 - assign CSRArray[13] = dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 - assign CSRArray[14] = dut.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 - assign CSRArray[15] = dut.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 - assign CSRArray[16] = 0; // 12'hF11 - assign CSRArray[17] = 0; // 12'hF12 - assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 - assign CSRArray[19] = 0; // 12'hF15 - assign CSRArray[20] = 0; // 12'h34A - // supervisor CSRs - assign CSRArray[21] = dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 - assign CSRArray[22] = dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 - assign CSRArray[23] = dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 - assign CSRArray[24] = dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 - assign CSRArray[25] = dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 - assign CSRArray[26] = dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A - assign CSRArray[27] = dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 - assign CSRArray[28] = dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 - assign CSRArray[29] = dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 - assign CSRArray[30] = dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 - assign CSRArray[31] = dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 - assign CSRArray[32] = dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D - // user CSRs - assign CSRArray[33] = dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 - assign CSRArray[34] = dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 - assign CSRArray[35] = {dut.core.priv.priv.csr.csru.csru.FRM_REGW, dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 - -----/\----- EXCLUDED -----/\----- */ - end - - // assign XLENZeros = '0; // start out easy and just populate Required From 3c065568331b162e2b30b899bef8e972a017b1ce Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 22 Jul 2024 16:12:06 -0500 Subject: [PATCH 75/95] Updated the verilog-ethernet repo to remove most of the warnings. Updated the fpga constraints so the ILA is more useful when using RVVI. --- addins/verilog-ethernet | 2 +- fpga/constraints/small-debug-rvvi.xdc | 43 ++++++++++----------------- src/rvvi/rvvisynth.sv | 2 +- 3 files changed, 18 insertions(+), 29 deletions(-) diff --git a/addins/verilog-ethernet b/addins/verilog-ethernet index 43990ab4f..471394b80 160000 --- a/addins/verilog-ethernet +++ b/addins/verilog-ethernet @@ -1 +1 @@ -Subproject commit 43990ab4fd0c8d34dbc1be5cd8d4f3ed3e33f853 +Subproject commit 471394b80c95a4859cd55a0f253d5ea502371e98 diff --git a/fpga/constraints/small-debug-rvvi.xdc b/fpga/constraints/small-debug-rvvi.xdc index f8ebbfe0d..0441f4fa2 100644 --- a/fpga/constraints/small-debug-rvvi.xdc +++ b/fpga/constraints/small-debug-rvvi.xdc @@ -9,7 +9,7 @@ set_property C_ADV_TRIGGER true [get_debug_cores u_ila_0 ] set_property ALL_PROBE_SAME_MU true [get_debug_cores u_ila_0 ] set_property ALL_PROBE_SAME_MU_CNT 4 [get_debug_cores u_ila_0 ] create_debug_port u_ila_0 trig_in -create_debug_port u_ila_0 trig_in_ack +create_debug_port u_ila_0 trig_in_ack #set_property port_width 1 [get_debug_ports u_ila_0/trig_in] #set_property port_width 1 [get_debug_ports u_ila_0/trig_in_ack] #set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/trig_in] @@ -17,14 +17,14 @@ connect_debug_port u_ila_0/trig_in [get_nets IlaTrigger] #connect_debug_port u_ila_0/trig_in_ack [get_nets IlaTriggerAck] connect_debug_port u_ila_0/clk [get_nets CPUCLK] -set_property port_width 32 [get_debug_ports u_ila_0/probe0] +set_property port_width 64 [get_debug_ports u_ila_0/probe0] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe0] -connect_debug_port u_ila_0/probe0 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][0]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][1]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][2]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][3]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][4]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][5]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][6]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][7]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][8]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][9]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][10]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][11]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][12]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][13]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][14]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][15]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][16]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][17]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][18]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][19]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][20]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][21]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][22]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][23]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][24]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][25]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][26]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][27]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][28]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][29]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][30]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][31]} ]] +connect_debug_port u_ila_0/probe0 [get_nets [list {wallypipelinedsoc/core/PCM[0]} {wallypipelinedsoc/core/PCM[1]} {wallypipelinedsoc/core/PCM[2]} {wallypipelinedsoc/core/PCM[3]} {wallypipelinedsoc/core/PCM[4]} {wallypipelinedsoc/core/PCM[5]} {wallypipelinedsoc/core/PCM[6]} {wallypipelinedsoc/core/PCM[7]} {wallypipelinedsoc/core/PCM[8]} {wallypipelinedsoc/core/PCM[9]} {wallypipelinedsoc/core/PCM[10]} {wallypipelinedsoc/core/PCM[11]} {wallypipelinedsoc/core/PCM[12]} {wallypipelinedsoc/core/PCM[13]} {wallypipelinedsoc/core/PCM[14]} {wallypipelinedsoc/core/PCM[15]} {wallypipelinedsoc/core/PCM[16]} {wallypipelinedsoc/core/PCM[17]} {wallypipelinedsoc/core/PCM[18]} {wallypipelinedsoc/core/PCM[19]} {wallypipelinedsoc/core/PCM[20]} {wallypipelinedsoc/core/PCM[21]} {wallypipelinedsoc/core/PCM[22]} {wallypipelinedsoc/core/PCM[23]} {wallypipelinedsoc/core/PCM[24]} {wallypipelinedsoc/core/PCM[25]} {wallypipelinedsoc/core/PCM[26]} {wallypipelinedsoc/core/PCM[27]} {wallypipelinedsoc/core/PCM[28]} {wallypipelinedsoc/core/PCM[29]} {wallypipelinedsoc/core/PCM[30]} {wallypipelinedsoc/core/PCM[31]} {wallypipelinedsoc/core/PCM[32]} {wallypipelinedsoc/core/PCM[33]} {wallypipelinedsoc/core/PCM[34]} {wallypipelinedsoc/core/PCM[35]} {wallypipelinedsoc/core/PCM[36]} {wallypipelinedsoc/core/PCM[37]} {wallypipelinedsoc/core/PCM[38]} {wallypipelinedsoc/core/PCM[39]} {wallypipelinedsoc/core/PCM[40]} {wallypipelinedsoc/core/PCM[41]} {wallypipelinedsoc/core/PCM[42]} {wallypipelinedsoc/core/PCM[43]} {wallypipelinedsoc/core/PCM[44]} {wallypipelinedsoc/core/PCM[45]} {wallypipelinedsoc/core/PCM[46]} {wallypipelinedsoc/core/PCM[47]} {wallypipelinedsoc/core/PCM[48]} {wallypipelinedsoc/core/PCM[49]} {wallypipelinedsoc/core/PCM[50]} {wallypipelinedsoc/core/PCM[51]} {wallypipelinedsoc/core/PCM[52]} {wallypipelinedsoc/core/PCM[53]} {wallypipelinedsoc/core/PCM[54]} {wallypipelinedsoc/core/PCM[55]} {wallypipelinedsoc/core/PCM[56]} {wallypipelinedsoc/core/PCM[57]} {wallypipelinedsoc/core/PCM[58]} {wallypipelinedsoc/core/PCM[59]} {wallypipelinedsoc/core/PCM[60]} {wallypipelinedsoc/core/PCM[61]} {wallypipelinedsoc/core/PCM[62]} {wallypipelinedsoc/core/PCM[63]} ]] create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe1] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe1] -connect_debug_port u_ila_0/probe1 [get_nets [list rvvi_synth/RvviAxiWlast ]] +connect_debug_port u_ila_0/probe1 [get_nets [list wallypipelinedsoc/core/TrapM ]] create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe2] @@ -32,50 +32,39 @@ set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe2] connect_debug_port u_ila_0/probe2 [get_nets [list wallypipelinedsoc/core/InstrValidM ]] create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe3] +set_property port_width 32 [get_debug_ports u_ila_0/probe3] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe3] -connect_debug_port u_ila_0/probe3 [get_nets [list {rvvi_synth/RvviAxiRlast}]] +connect_debug_port u_ila_0/probe3 [get_nets [list {wallypipelinedsoc/core/InstrM[0]} {wallypipelinedsoc/core/InstrM[1]} {wallypipelinedsoc/core/InstrM[2]} {wallypipelinedsoc/core/InstrM[3]} {wallypipelinedsoc/core/InstrM[4]} {wallypipelinedsoc/core/InstrM[5]} {wallypipelinedsoc/core/InstrM[6]} {wallypipelinedsoc/core/InstrM[7]} {wallypipelinedsoc/core/InstrM[8]} {wallypipelinedsoc/core/InstrM[9]} {wallypipelinedsoc/core/InstrM[10]} {wallypipelinedsoc/core/InstrM[11]} {wallypipelinedsoc/core/InstrM[12]} {wallypipelinedsoc/core/InstrM[13]} {wallypipelinedsoc/core/InstrM[14]} {wallypipelinedsoc/core/InstrM[15]} {wallypipelinedsoc/core/InstrM[16]} {wallypipelinedsoc/core/InstrM[17]} {wallypipelinedsoc/core/InstrM[18]} {wallypipelinedsoc/core/InstrM[19]} {wallypipelinedsoc/core/InstrM[20]} {wallypipelinedsoc/core/InstrM[21]} {wallypipelinedsoc/core/InstrM[22]} {wallypipelinedsoc/core/InstrM[23]} {wallypipelinedsoc/core/InstrM[24]} {wallypipelinedsoc/core/InstrM[25]} {wallypipelinedsoc/core/InstrM[26]} {wallypipelinedsoc/core/InstrM[27]} {wallypipelinedsoc/core/InstrM[28]} {wallypipelinedsoc/core/InstrM[29]} {wallypipelinedsoc/core/InstrM[30]} {wallypipelinedsoc/core/InstrM[31]} ]] create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe4] +set_property port_width 2 [get_debug_ports u_ila_0/probe4] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe4] -connect_debug_port u_ila_0/probe4 [get_nets [list {rvvi_synth/RvviAxiRvalid}]] +connect_debug_port u_ila_0/probe4 [get_nets [list {wallypipelinedsoc/core/lsu/MemRWM[0]} {wallypipelinedsoc/core/lsu/MemRWM[1]} ]] create_debug_port u_ila_0 probe -set_property port_width 4 [get_debug_ports u_ila_0/probe5] +set_property port_width 64 [get_debug_ports u_ila_0/probe5] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe5] -connect_debug_port u_ila_0/probe5 [get_nets [list {rvvi_synth/packetizer/CurrState[0]} {rvvi_synth/packetizer/CurrState[1]} {rvvi_synth/packetizer/CurrState[2]} {rvvi_synth/packetizer/CurrState[3]}]] +connect_debug_port u_ila_0/probe5 [get_nets [list {wallypipelinedsoc/core/lsu/IEUAdrM[0]} {wallypipelinedsoc/core/lsu/IEUAdrM[1]} {wallypipelinedsoc/core/lsu/IEUAdrM[2]} {wallypipelinedsoc/core/lsu/IEUAdrM[3]} {wallypipelinedsoc/core/lsu/IEUAdrM[4]} {wallypipelinedsoc/core/lsu/IEUAdrM[5]} {wallypipelinedsoc/core/lsu/IEUAdrM[6]} {wallypipelinedsoc/core/lsu/IEUAdrM[7]} {wallypipelinedsoc/core/lsu/IEUAdrM[8]} {wallypipelinedsoc/core/lsu/IEUAdrM[9]} {wallypipelinedsoc/core/lsu/IEUAdrM[10]} {wallypipelinedsoc/core/lsu/IEUAdrM[11]} {wallypipelinedsoc/core/lsu/IEUAdrM[12]} {wallypipelinedsoc/core/lsu/IEUAdrM[13]} {wallypipelinedsoc/core/lsu/IEUAdrM[14]} {wallypipelinedsoc/core/lsu/IEUAdrM[15]} {wallypipelinedsoc/core/lsu/IEUAdrM[16]} {wallypipelinedsoc/core/lsu/IEUAdrM[17]} {wallypipelinedsoc/core/lsu/IEUAdrM[18]} {wallypipelinedsoc/core/lsu/IEUAdrM[19]} {wallypipelinedsoc/core/lsu/IEUAdrM[20]} {wallypipelinedsoc/core/lsu/IEUAdrM[21]} {wallypipelinedsoc/core/lsu/IEUAdrM[22]} {wallypipelinedsoc/core/lsu/IEUAdrM[23]} {wallypipelinedsoc/core/lsu/IEUAdrM[24]} {wallypipelinedsoc/core/lsu/IEUAdrM[25]} {wallypipelinedsoc/core/lsu/IEUAdrM[26]} {wallypipelinedsoc/core/lsu/IEUAdrM[27]} {wallypipelinedsoc/core/lsu/IEUAdrM[28]} {wallypipelinedsoc/core/lsu/IEUAdrM[29]} {wallypipelinedsoc/core/lsu/IEUAdrM[30]} {wallypipelinedsoc/core/lsu/IEUAdrM[31]} {wallypipelinedsoc/core/lsu/IEUAdrM[32]} {wallypipelinedsoc/core/lsu/IEUAdrM[33]} {wallypipelinedsoc/core/lsu/IEUAdrM[34]} {wallypipelinedsoc/core/lsu/IEUAdrM[35]} {wallypipelinedsoc/core/lsu/IEUAdrM[36]} {wallypipelinedsoc/core/lsu/IEUAdrM[37]} {wallypipelinedsoc/core/lsu/IEUAdrM[38]} {wallypipelinedsoc/core/lsu/IEUAdrM[39]} {wallypipelinedsoc/core/lsu/IEUAdrM[40]} {wallypipelinedsoc/core/lsu/IEUAdrM[41]} {wallypipelinedsoc/core/lsu/IEUAdrM[42]} {wallypipelinedsoc/core/lsu/IEUAdrM[43]} {wallypipelinedsoc/core/lsu/IEUAdrM[44]} {wallypipelinedsoc/core/lsu/IEUAdrM[45]} {wallypipelinedsoc/core/lsu/IEUAdrM[46]} {wallypipelinedsoc/core/lsu/IEUAdrM[47]} {wallypipelinedsoc/core/lsu/IEUAdrM[48]} {wallypipelinedsoc/core/lsu/IEUAdrM[49]} {wallypipelinedsoc/core/lsu/IEUAdrM[50]} {wallypipelinedsoc/core/lsu/IEUAdrM[51]} {wallypipelinedsoc/core/lsu/IEUAdrM[52]} {wallypipelinedsoc/core/lsu/IEUAdrM[53]} {wallypipelinedsoc/core/lsu/IEUAdrM[54]} {wallypipelinedsoc/core/lsu/IEUAdrM[55]} {wallypipelinedsoc/core/lsu/IEUAdrM[56]} {wallypipelinedsoc/core/lsu/IEUAdrM[57]} {wallypipelinedsoc/core/lsu/IEUAdrM[58]} {wallypipelinedsoc/core/lsu/IEUAdrM[59]} {wallypipelinedsoc/core/lsu/IEUAdrM[60]} {wallypipelinedsoc/core/lsu/IEUAdrM[61]} {wallypipelinedsoc/core/lsu/IEUAdrM[62]} {wallypipelinedsoc/core/lsu/IEUAdrM[63]} ]] create_debug_port u_ila_0 probe set_property port_width 64 [get_debug_ports u_ila_0/probe6] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe6] -connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/PCM[0]} {wallypipelinedsoc/core/PCM[1]} {wallypipelinedsoc/core/PCM[2]} {wallypipelinedsoc/core/PCM[3]} {wallypipelinedsoc/core/PCM[4]} {wallypipelinedsoc/core/PCM[5]} {wallypipelinedsoc/core/PCM[6]} {wallypipelinedsoc/core/PCM[7]} {wallypipelinedsoc/core/PCM[8]} {wallypipelinedsoc/core/PCM[9]} {wallypipelinedsoc/core/PCM[10]} {wallypipelinedsoc/core/PCM[11]} {wallypipelinedsoc/core/PCM[12]} {wallypipelinedsoc/core/PCM[13]} {wallypipelinedsoc/core/PCM[14]} {wallypipelinedsoc/core/PCM[15]} {wallypipelinedsoc/core/PCM[16]} {wallypipelinedsoc/core/PCM[17]} {wallypipelinedsoc/core/PCM[18]} {wallypipelinedsoc/core/PCM[19]} {wallypipelinedsoc/core/PCM[20]} {wallypipelinedsoc/core/PCM[21]} {wallypipelinedsoc/core/PCM[22]} {wallypipelinedsoc/core/PCM[23]} {wallypipelinedsoc/core/PCM[24]} {wallypipelinedsoc/core/PCM[25]} {wallypipelinedsoc/core/PCM[26]} {wallypipelinedsoc/core/PCM[27]} {wallypipelinedsoc/core/PCM[28]} {wallypipelinedsoc/core/PCM[29]} {wallypipelinedsoc/core/PCM[30]} {wallypipelinedsoc/core/PCM[31]} {wallypipelinedsoc/core/PCM[32]} {wallypipelinedsoc/core/PCM[33]} {wallypipelinedsoc/core/PCM[34]} {wallypipelinedsoc/core/PCM[35]} {wallypipelinedsoc/core/PCM[36]} {wallypipelinedsoc/core/PCM[37]} {wallypipelinedsoc/core/PCM[38]} {wallypipelinedsoc/core/PCM[39]} {wallypipelinedsoc/core/PCM[40]} {wallypipelinedsoc/core/PCM[41]} {wallypipelinedsoc/core/PCM[42]} {wallypipelinedsoc/core/PCM[43]} {wallypipelinedsoc/core/PCM[44]} {wallypipelinedsoc/core/PCM[45]} {wallypipelinedsoc/core/PCM[46]} {wallypipelinedsoc/core/PCM[47]} {wallypipelinedsoc/core/PCM[48]} {wallypipelinedsoc/core/PCM[49]} {wallypipelinedsoc/core/PCM[50]} {wallypipelinedsoc/core/PCM[51]} {wallypipelinedsoc/core/PCM[52]} {wallypipelinedsoc/core/PCM[53]} {wallypipelinedsoc/core/PCM[54]} {wallypipelinedsoc/core/PCM[55]} {wallypipelinedsoc/core/PCM[56]} {wallypipelinedsoc/core/PCM[57]} {wallypipelinedsoc/core/PCM[58]} {wallypipelinedsoc/core/PCM[59]} {wallypipelinedsoc/core/PCM[60]} {wallypipelinedsoc/core/PCM[61]} {wallypipelinedsoc/core/PCM[62]} {wallypipelinedsoc/core/PCM[63]} ]] +connect_debug_port u_ila_0/probe6 [get_nets [list {wallypipelinedsoc/core/lsu/ReadDataM[0]} {wallypipelinedsoc/core/lsu/ReadDataM[1]} {wallypipelinedsoc/core/lsu/ReadDataM[2]} {wallypipelinedsoc/core/lsu/ReadDataM[3]} {wallypipelinedsoc/core/lsu/ReadDataM[4]} {wallypipelinedsoc/core/lsu/ReadDataM[5]} {wallypipelinedsoc/core/lsu/ReadDataM[6]} {wallypipelinedsoc/core/lsu/ReadDataM[7]} {wallypipelinedsoc/core/lsu/ReadDataM[8]} {wallypipelinedsoc/core/lsu/ReadDataM[9]} {wallypipelinedsoc/core/lsu/ReadDataM[10]} {wallypipelinedsoc/core/lsu/ReadDataM[11]} {wallypipelinedsoc/core/lsu/ReadDataM[12]} {wallypipelinedsoc/core/lsu/ReadDataM[13]} {wallypipelinedsoc/core/lsu/ReadDataM[14]} {wallypipelinedsoc/core/lsu/ReadDataM[15]} {wallypipelinedsoc/core/lsu/ReadDataM[16]} {wallypipelinedsoc/core/lsu/ReadDataM[17]} {wallypipelinedsoc/core/lsu/ReadDataM[18]} {wallypipelinedsoc/core/lsu/ReadDataM[19]} {wallypipelinedsoc/core/lsu/ReadDataM[20]} {wallypipelinedsoc/core/lsu/ReadDataM[21]} {wallypipelinedsoc/core/lsu/ReadDataM[22]} {wallypipelinedsoc/core/lsu/ReadDataM[23]} {wallypipelinedsoc/core/lsu/ReadDataM[24]} {wallypipelinedsoc/core/lsu/ReadDataM[25]} {wallypipelinedsoc/core/lsu/ReadDataM[26]} {wallypipelinedsoc/core/lsu/ReadDataM[27]} {wallypipelinedsoc/core/lsu/ReadDataM[28]} {wallypipelinedsoc/core/lsu/ReadDataM[29]} {wallypipelinedsoc/core/lsu/ReadDataM[30]} {wallypipelinedsoc/core/lsu/ReadDataM[31]} {wallypipelinedsoc/core/lsu/ReadDataM[32]} {wallypipelinedsoc/core/lsu/ReadDataM[33]} {wallypipelinedsoc/core/lsu/ReadDataM[34]} {wallypipelinedsoc/core/lsu/ReadDataM[35]} {wallypipelinedsoc/core/lsu/ReadDataM[36]} {wallypipelinedsoc/core/lsu/ReadDataM[37]} {wallypipelinedsoc/core/lsu/ReadDataM[38]} {wallypipelinedsoc/core/lsu/ReadDataM[39]} {wallypipelinedsoc/core/lsu/ReadDataM[40]} {wallypipelinedsoc/core/lsu/ReadDataM[41]} {wallypipelinedsoc/core/lsu/ReadDataM[42]} {wallypipelinedsoc/core/lsu/ReadDataM[43]} {wallypipelinedsoc/core/lsu/ReadDataM[44]} {wallypipelinedsoc/core/lsu/ReadDataM[45]} {wallypipelinedsoc/core/lsu/ReadDataM[46]} {wallypipelinedsoc/core/lsu/ReadDataM[47]} {wallypipelinedsoc/core/lsu/ReadDataM[48]} {wallypipelinedsoc/core/lsu/ReadDataM[49]} {wallypipelinedsoc/core/lsu/ReadDataM[50]} {wallypipelinedsoc/core/lsu/ReadDataM[51]} {wallypipelinedsoc/core/lsu/ReadDataM[52]} {wallypipelinedsoc/core/lsu/ReadDataM[53]} {wallypipelinedsoc/core/lsu/ReadDataM[54]} {wallypipelinedsoc/core/lsu/ReadDataM[55]} {wallypipelinedsoc/core/lsu/ReadDataM[56]} {wallypipelinedsoc/core/lsu/ReadDataM[57]} {wallypipelinedsoc/core/lsu/ReadDataM[58]} {wallypipelinedsoc/core/lsu/ReadDataM[59]} {wallypipelinedsoc/core/lsu/ReadDataM[60]} {wallypipelinedsoc/core/lsu/ReadDataM[61]} {wallypipelinedsoc/core/lsu/ReadDataM[62]} {wallypipelinedsoc/core/lsu/ReadDataM[63]} ]] create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe7] +set_property port_width 64 [get_debug_ports u_ila_0/probe7] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe7] -connect_debug_port u_ila_0/probe7 [get_nets [list {rvvi_synth/RvviAxiWvalid}]] +connect_debug_port u_ila_0/probe7 [get_nets [list {wallypipelinedsoc/core/lsu/WriteDataM[0]} {wallypipelinedsoc/core/lsu/WriteDataM[1]} {wallypipelinedsoc/core/lsu/WriteDataM[2]} {wallypipelinedsoc/core/lsu/WriteDataM[3]} {wallypipelinedsoc/core/lsu/WriteDataM[4]} {wallypipelinedsoc/core/lsu/WriteDataM[5]} {wallypipelinedsoc/core/lsu/WriteDataM[6]} {wallypipelinedsoc/core/lsu/WriteDataM[7]} {wallypipelinedsoc/core/lsu/WriteDataM[8]} {wallypipelinedsoc/core/lsu/WriteDataM[9]} {wallypipelinedsoc/core/lsu/WriteDataM[10]} {wallypipelinedsoc/core/lsu/WriteDataM[11]} {wallypipelinedsoc/core/lsu/WriteDataM[12]} {wallypipelinedsoc/core/lsu/WriteDataM[13]} {wallypipelinedsoc/core/lsu/WriteDataM[14]} {wallypipelinedsoc/core/lsu/WriteDataM[15]} {wallypipelinedsoc/core/lsu/WriteDataM[16]} {wallypipelinedsoc/core/lsu/WriteDataM[17]} {wallypipelinedsoc/core/lsu/WriteDataM[18]} {wallypipelinedsoc/core/lsu/WriteDataM[19]} {wallypipelinedsoc/core/lsu/WriteDataM[20]} {wallypipelinedsoc/core/lsu/WriteDataM[21]} {wallypipelinedsoc/core/lsu/WriteDataM[22]} {wallypipelinedsoc/core/lsu/WriteDataM[23]} {wallypipelinedsoc/core/lsu/WriteDataM[24]} {wallypipelinedsoc/core/lsu/WriteDataM[25]} {wallypipelinedsoc/core/lsu/WriteDataM[26]} {wallypipelinedsoc/core/lsu/WriteDataM[27]} {wallypipelinedsoc/core/lsu/WriteDataM[28]} {wallypipelinedsoc/core/lsu/WriteDataM[29]} {wallypipelinedsoc/core/lsu/WriteDataM[30]} {wallypipelinedsoc/core/lsu/WriteDataM[31]} {wallypipelinedsoc/core/lsu/WriteDataM[32]} {wallypipelinedsoc/core/lsu/WriteDataM[33]} {wallypipelinedsoc/core/lsu/WriteDataM[34]} {wallypipelinedsoc/core/lsu/WriteDataM[35]} {wallypipelinedsoc/core/lsu/WriteDataM[36]} {wallypipelinedsoc/core/lsu/WriteDataM[37]} {wallypipelinedsoc/core/lsu/WriteDataM[38]} {wallypipelinedsoc/core/lsu/WriteDataM[39]} {wallypipelinedsoc/core/lsu/WriteDataM[40]} {wallypipelinedsoc/core/lsu/WriteDataM[41]} {wallypipelinedsoc/core/lsu/WriteDataM[42]} {wallypipelinedsoc/core/lsu/WriteDataM[43]} {wallypipelinedsoc/core/lsu/WriteDataM[44]} {wallypipelinedsoc/core/lsu/WriteDataM[45]} {wallypipelinedsoc/core/lsu/WriteDataM[46]} {wallypipelinedsoc/core/lsu/WriteDataM[47]} {wallypipelinedsoc/core/lsu/WriteDataM[48]} {wallypipelinedsoc/core/lsu/WriteDataM[49]} {wallypipelinedsoc/core/lsu/WriteDataM[50]} {wallypipelinedsoc/core/lsu/WriteDataM[51]} {wallypipelinedsoc/core/lsu/WriteDataM[52]} {wallypipelinedsoc/core/lsu/WriteDataM[53]} {wallypipelinedsoc/core/lsu/WriteDataM[54]} {wallypipelinedsoc/core/lsu/WriteDataM[55]} {wallypipelinedsoc/core/lsu/WriteDataM[56]} {wallypipelinedsoc/core/lsu/WriteDataM[57]} {wallypipelinedsoc/core/lsu/WriteDataM[58]} {wallypipelinedsoc/core/lsu/WriteDataM[59]} {wallypipelinedsoc/core/lsu/WriteDataM[60]} {wallypipelinedsoc/core/lsu/WriteDataM[61]} {wallypipelinedsoc/core/lsu/WriteDataM[62]} {wallypipelinedsoc/core/lsu/WriteDataM[63]} ]] create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe8] +set_property port_width 32 [get_debug_ports u_ila_0/probe8] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe8] -connect_debug_port u_ila_0/probe8 [get_nets [list {RVVIStall}]] +connect_debug_port u_ila_0/probe8 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][0]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][1]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][2]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][3]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][4]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][5]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][6]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][7]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][8]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][9]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][10]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][11]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][12]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][13]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][14]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][15]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][16]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][17]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][18]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][19]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][20]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][21]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][22]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][23]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][24]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][25]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][26]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][27]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][28]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][29]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][30]} {wallypipelinedsoc/core/priv.priv/csr/HPMCOUNTER_REGW[0][31]} ]] create_debug_port u_ila_0 probe set_property port_width 1 [get_debug_ports u_ila_0/probe9] set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe9] -connect_debug_port u_ila_0/probe9 [get_nets [list {rvvi_synth/valid}]] - -create_debug_port u_ila_0 probe -set_property port_width 1 [get_debug_ports u_ila_0/probe10] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe10] -connect_debug_port u_ila_0/probe10 [get_nets [list {rvvi_synth/RvviAxiWready}]] - -create_debug_port u_ila_0 probe -set_property port_width 3 [get_debug_ports u_ila_0/probe11] -set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe11] -connect_debug_port u_ila_0/probe11 [get_nets [list {rvvi_synth/triggergen/CurrState[0]} {rvvi_synth/triggergen/CurrState[1]} {rvvi_synth/triggergen/CurrState[2]}]] - +connect_debug_port u_ila_0/probe9 [get_nets [list {RVVIStall}]] # the debug hub has issues with the clocks from the mmcm so lets give up an connect to the 100Mhz input clock. #connect_debug_port dbg_hub/clk [get_nets default_100mhz_clk] diff --git a/src/rvvi/rvvisynth.sv b/src/rvvi/rvvisynth.sv index cbf7c30bf..5ee8b8c52 100644 --- a/src/rvvi/rvvisynth.sv +++ b/src/rvvi/rvvisynth.sv @@ -44,7 +44,7 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, input logic GPRWen, FPRWen, input logic [4:0] GPRAddr, FPRAddr, input logic [P.XLEN-1:0] GPRValue, FPRValue, - input logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0], + input var logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0], output logic valid, output logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi ); From 5381e1f3950a74122059f89ecafe26a85dc18019 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Mon, 22 Jul 2024 17:44:04 -0500 Subject: [PATCH 76/95] Updated for a better ILA rvvi debugger. --- config/derivlist.txt | 4 ++-- fpga/constraints/small-debug-rvvi.xdc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/derivlist.txt b/config/derivlist.txt index 01ad315e5..048adcb21 100644 --- a/config/derivlist.txt +++ b/config/derivlist.txt @@ -57,9 +57,9 @@ EXT_MEM_RANGE 64'h0FFFFFFF SDC_SUPPORTED 1 PLIC_SDC_ID 32'd20 BPRED_SIZE 32'd12 -RVVI_SYNTH_SUPPORTED 0 +RVVI_SYNTH_SUPPORTED 1 RVVI_INIT_TIME_OUT 32'd100000000 -RVVI_PACKET_DELAY 32'd350 +RVVI_PACKET_DELAY 32'd400 # The syn configurations are trimmed down for faster synthesis. diff --git a/fpga/constraints/small-debug-rvvi.xdc b/fpga/constraints/small-debug-rvvi.xdc index 0441f4fa2..629cde561 100644 --- a/fpga/constraints/small-debug-rvvi.xdc +++ b/fpga/constraints/small-debug-rvvi.xdc @@ -1,5 +1,5 @@ create_debug_core u_ila_0 ila -set_property C_DATA_DEPTH 8192 [get_debug_cores u_ila_0] +set_property C_DATA_DEPTH 4096 [get_debug_cores u_ila_0] set_property C_TRIGIN_EN true [get_debug_cores u_ila_0] set_property C_TRIGOUT_EN false [get_debug_cores u_ila_0] set_property C_INPUT_PIPE_STAGES 0 [get_debug_cores u_ila_0] From b30656447f9e20838cd66445dac7ab254fbd73ea Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 23 Jul 2024 12:23:04 -0500 Subject: [PATCH 77/95] Resolved more lint errors in the rvvi synthesized hardware. --- src/rvvi/csrindextoaddr.sv | 77 +++++++++++++++++++++++++++++++++++++ src/rvvi/packetizer.sv | 2 +- src/wally/csrindextoaddr.sv | 77 ------------------------------------- 3 files changed, 78 insertions(+), 78 deletions(-) create mode 100644 src/rvvi/csrindextoaddr.sv delete mode 100644 src/wally/csrindextoaddr.sv diff --git a/src/rvvi/csrindextoaddr.sv b/src/rvvi/csrindextoaddr.sv new file mode 100644 index 000000000..0a843f491 --- /dev/null +++ b/src/rvvi/csrindextoaddr.sv @@ -0,0 +1,77 @@ +/////////////////////////////////////////// +// csrindextoaddr.sv +// +// Written: Rose Thompson ross1728@gmail.com +// Created: 24 January 2024 +// Modified: 24 January 2024 +// +// Purpose: Converts the rvvi CSR index into the CSR address +// +// Documentation: +// +// A component of the CORE-V-WALLY configurable RISC-V project. +// +// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module csrindextoaddr #(parameter TOTAL_CSRS = 36) ( + input logic [TOTAL_CSRS-1:0] CSRWen, + output logic [11:0] CSRAddr); + + always_comb begin + case(CSRWen) + 36'h0_0000_0000: CSRAddr = 12'h000; + 36'h0_0000_0001: CSRAddr = 12'h300; + 36'h0_0000_0002: CSRAddr = 12'h310; + 36'h0_0000_0004: CSRAddr = 12'h305; + 36'h0_0000_0008: CSRAddr = 12'h341; + 36'h0_0000_0010: CSRAddr = 12'h306; + 36'h0_0000_0020: CSRAddr = 12'h320; + 36'h0_0000_0040: CSRAddr = 12'h302; + 36'h0_0000_0080: CSRAddr = 12'h303; + 36'h0_0000_0100: CSRAddr = 12'h344; + 36'h0_0000_0200: CSRAddr = 12'h304; + 36'h0_0000_0400: CSRAddr = 12'h301; + 36'h0_0000_0800: CSRAddr = 12'h30A; + 36'h0_0000_1000: CSRAddr = 12'hF14; + 36'h0_0000_2000: CSRAddr = 12'h340; + 36'h0_0000_4000: CSRAddr = 12'h342; + 36'h0_0000_8000: CSRAddr = 12'h343; + 36'h0_0001_0000: CSRAddr = 12'hF11; + 36'h0_0002_0000: CSRAddr = 12'hF12; + 36'h0_0004_0000: CSRAddr = 12'hF13; + 36'h0_0008_0000: CSRAddr = 12'hF15; + 36'h0_0010_0000: CSRAddr = 12'h34A; + 36'h0_0020_0000: CSRAddr = 12'h100; + 36'h0_0040_0000: CSRAddr = 12'h104; + 36'h0_0080_0000: CSRAddr = 12'h105; + 36'h0_0100_0000: CSRAddr = 12'h141; + 36'h0_0200_0000: CSRAddr = 12'h106; + 36'h0_0400_0000: CSRAddr = 12'h10A; + 36'h0_0800_0000: CSRAddr = 12'h180; + 36'h0_1000_0000: CSRAddr = 12'h140; + 36'h0_2000_0000: CSRAddr = 12'h143; + 36'h0_4000_0000: CSRAddr = 12'h142; + 36'h0_8000_0000: CSRAddr = 12'h144; + 36'h1_0000_0000: CSRAddr = 12'h14D; + 36'h2_0000_0000: CSRAddr = 12'h001; + 36'h4_0000_0000: CSRAddr = 12'h002; + 36'h8_0000_0000: CSRAddr = 12'h003; + default : CSRAddr = 12'h000; + endcase + end +endmodule + diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index cf99b9038..97c57415e 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -129,7 +129,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, assign Tag = 32'b0; assign EthType = 16'h005c; - assign RvviAxiWdata = TotalFrameWords[WordCount]; + assign RvviAxiWdata = TotalFrameWords[WordCount[4:0]]; assign RvviAxiWstrb = '1; assign RvviAxiWlast = BurstDone & (CurrState == STATE_TRANS); assign RvviAxiWvalid = (CurrState == STATE_TRANS); diff --git a/src/wally/csrindextoaddr.sv b/src/wally/csrindextoaddr.sv deleted file mode 100644 index 8b2d9e6b7..000000000 --- a/src/wally/csrindextoaddr.sv +++ /dev/null @@ -1,77 +0,0 @@ -/////////////////////////////////////////// -// csrindextoaddr.sv -// -// Written: Rose Thompson ross1728@gmail.com -// Created: 24 January 2024 -// Modified: 24 January 2024 -// -// Purpose: Converts the rvvi CSR index into the CSR address -// -// Documentation: -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -module csrindextoaddr #(parameter TOTAL_CSRS = 36) ( - input logic [TOTAL_CSRS-1:0] CSRWen, - output logic [11:0] CSRAddr); - - always_comb begin - case(CSRWen) - 36'h0_0000_0000: CSRAddr = 13'h000; - 36'h0_0000_0001: CSRAddr = 13'h300; - 36'h0_0000_0002: CSRAddr = 13'h310; - 36'h0_0000_0004: CSRAddr = 13'h305; - 36'h0_0000_0008: CSRAddr = 13'h341; - 36'h0_0000_0010: CSRAddr = 13'h306; - 36'h0_0000_0020: CSRAddr = 13'h320; - 36'h0_0000_0040: CSRAddr = 13'h302; - 36'h0_0000_0080: CSRAddr = 13'h303; - 36'h0_0000_0100: CSRAddr = 13'h344; - 36'h0_0000_0200: CSRAddr = 13'h304; - 36'h0_0000_0400: CSRAddr = 13'h301; - 36'h0_0000_0800: CSRAddr = 13'h30A; - 36'h0_0000_1000: CSRAddr = 13'hF14; - 36'h0_0000_2000: CSRAddr = 13'h340; - 36'h0_0000_4000: CSRAddr = 13'h342; - 36'h0_0000_8000: CSRAddr = 13'h343; - 36'h0_0001_0000: CSRAddr = 13'hF11; - 36'h0_0002_0000: CSRAddr = 13'hF12; - 36'h0_0004_0000: CSRAddr = 13'hF13; - 36'h0_0008_0000: CSRAddr = 13'hF15; - 36'h0_0010_0000: CSRAddr = 13'h34A; - 36'h0_0020_0000: CSRAddr = 13'h100; - 36'h0_0040_0000: CSRAddr = 13'h104; - 36'h0_0080_0000: CSRAddr = 13'h105; - 36'h0_0100_0000: CSRAddr = 13'h141; - 36'h0_0200_0000: CSRAddr = 13'h106; - 36'h0_0400_0000: CSRAddr = 13'h10A; - 36'h0_0800_0000: CSRAddr = 13'h180; - 36'h0_1000_0000: CSRAddr = 13'h140; - 36'h0_2000_0000: CSRAddr = 13'h143; - 36'h0_4000_0000: CSRAddr = 13'h142; - 36'h0_8000_0000: CSRAddr = 13'h144; - 36'h1_0000_0000: CSRAddr = 13'h14D; - 36'h2_0000_0000: CSRAddr = 13'h001; - 36'h4_0000_0000: CSRAddr = 13'h002; - 36'h8_0000_0000: CSRAddr = 13'h003; - default : CSRAddr = 13'h000; - endcase - end -endmodule - From d706b5b898db74e6af1f2cdee87b0348e23dc6d0 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 23 Jul 2024 12:26:03 -0500 Subject: [PATCH 78/95] Fixed bus width error. Have to check this FPGA to make sure this didn't break anything. --- src/rvvi/packetizer.sv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 97c57415e..54dc9a27f 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -42,7 +42,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, input logic RvviAxiWready ); - localparam TotalFrameLengthBits = 2*48+32+16+187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12); + localparam TotalFrameLengthBits = 2*48+17+16+187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12); localparam TotalFrameLengthBytes = TotalFrameLengthBits / 8; logic [9:0] WordCount; @@ -121,7 +121,7 @@ module packetizer import cvw::*; #(parameter cvw_t P, end assign Length = {4'b0, BytesInFrame}; - assign TotalFrame = {16'b0, rvviDelay, EthType, DstMac, SrcMac}; + assign TotalFrame = {17'b0, rvviDelay, EthType, DstMac, SrcMac}; // *** fix me later assign DstMac = 48'h8F54_0000_1654; // made something up From f20b82b14e7c73a49e930c715601b637702c5cee Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 23 Jul 2024 13:03:21 -0500 Subject: [PATCH 79/95] Moved all rvvi files to rvvi directory. --- src/{wally => rvvi}/regchangedetect.sv | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{wally => rvvi}/regchangedetect.sv (100%) diff --git a/src/wally/regchangedetect.sv b/src/rvvi/regchangedetect.sv similarity index 100% rename from src/wally/regchangedetect.sv rename to src/rvvi/regchangedetect.sv From 7bc04702a76513ef3b73fc138345599d9c4ea826 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 23 Jul 2024 13:18:03 -0500 Subject: [PATCH 80/95] Down to 3 verilator warnings in rvvisynth and a 40 warnings in verilog-ethernet. --- src/{wally => rvvi}/priorityaomux.sv | 0 src/rvvi/rvvisynth.sv | 9 ++++++--- 2 files changed, 6 insertions(+), 3 deletions(-) rename src/{wally => rvvi}/priorityaomux.sv (100%) diff --git a/src/wally/priorityaomux.sv b/src/rvvi/priorityaomux.sv similarity index 100% rename from src/wally/priorityaomux.sv rename to src/rvvi/priorityaomux.sv diff --git a/src/rvvi/rvvisynth.sv b/src/rvvi/rvvisynth.sv index 5ee8b8c52..a98160d47 100644 --- a/src/rvvi/rvvisynth.sv +++ b/src/rvvi/rvvisynth.sv @@ -30,7 +30,8 @@ `define FPGA 0 module rvvisynth import cvw::*; #(parameter cvw_t P, - parameter integer MAX_CSRS, TOTAL_CSRS = 36)( + parameter integer MAX_CSRS = 3, + parameter integer TOTAL_CSRS = 36)( input logic clk, reset, input logic StallE, StallM, StallW, FlushE, FlushM, FlushW, // required @@ -64,6 +65,7 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, logic [TOTAL_CSRS-1:0] CSRWen [MAX_CSRS-1:0]; logic [11:0] CSRAddr [MAX_CSRS-1:0]; logic [MAX_CSRS-1:0] EnabledCSRs; + logic [MAX_CSRS-1:0] CSRCountShort; logic [11:0] CSRCount; logic [177+P.XLEN-1:0] Required; logic [10+2*P.XLEN-1:0] Registers; @@ -94,7 +96,7 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, // 3. Then use priorityaomux to collect CSR values and addresses for compating into the compressed rvvi format // step 2 - genvar index; + genvar index; for (index = 0; index < TOTAL_CSRS; index = index + 1) begin regchangedetect #(P.XLEN) changedetect(clk, reset, CSRArray[index], CSRArrayWen[index]); end @@ -109,7 +111,8 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, assign CSRs[(index+1) * (P.XLEN + 12)- 1: index * (P.XLEN + 12)] = {CSRValue[index], CSRAddr[index]}; assign EnabledCSRs[index] = |CSRWenShort; end - assign CSRCount = +EnabledCSRs; + assign CSRCountShort = +EnabledCSRs; + assign CSRCount = {{{12-MAX_CSRS}{1'b0}}, CSRCountShort}; assign rvvi = {CSRs, Registers, Required}; endmodule From da2511c63cd6da594ed879e18a9ff726ab73293b Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 23 Jul 2024 16:16:11 -0500 Subject: [PATCH 81/95] Fixed bugs in the rvvi synth logic which encoded csr instructions. --- src/rvvi/rvvisynth.sv | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/rvvi/rvvisynth.sv b/src/rvvi/rvvisynth.sv index a98160d47..d4847c9d4 100644 --- a/src/rvvi/rvvisynth.sv +++ b/src/rvvi/rvvisynth.sv @@ -102,14 +102,26 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, end // step 3a - for(index = 0; index < MAX_CSRS; index = index + 1) begin + logic [TOTAL_CSRS-1:0] CSRWenPriorityMatrix [MAX_CSRS-1:0]; + logic [TOTAL_CSRS-1:0] CSRWenFilterMatrix [MAX_CSRS-1:0]; + + priorityaomux #(TOTAL_CSRS, P.XLEN) firstpriorityaomux(CSRArrayWen, CSRArray, CSRValue[0], CSRWenPriorityMatrix[0]); + assign CSRWenFilterMatrix[0] = CSRArrayWen; + + for(index = 1; index < MAX_CSRS; index = index + 1) begin +/* -----\/----- EXCLUDED -----\/----- logic [MAX_CSRS-index-1:0] CSRWenShort; priorityaomux #(MAX_CSRS-index, P.XLEN) priorityaomux(CSRArrayWen[MAX_CSRS-1:index], CSRArray[MAX_CSRS-1:index], CSRValue[index], CSRWenShort); assign CSRWen[index] = {{{index}{1'b0}}, CSRWenShort}; + -----/\----- EXCLUDED -----/\----- */ + priorityaomux #(TOTAL_CSRS, P.XLEN) priorityaomux(CSRWenFilterMatrix[index], CSRArray, CSRValue[index], CSRWenPriorityMatrix[index]); + assign CSRWenFilterMatrix[index] = CSRWenFilterMatrix[index-1] & ~CSRWenPriorityMatrix[index-1]; + end + for(index = 0; index < MAX_CSRS; index = index + 1) begin // step 3b - csrindextoaddr #(TOTAL_CSRS) csrindextoaddr(CSRWen[index], CSRAddr[index]); + csrindextoaddr #(TOTAL_CSRS) csrindextoaddr(CSRWenPriorityMatrix[index], CSRAddr[index]); assign CSRs[(index+1) * (P.XLEN + 12)- 1: index * (P.XLEN + 12)] = {CSRValue[index], CSRAddr[index]}; - assign EnabledCSRs[index] = |CSRWenShort; + assign EnabledCSRs[index] = |CSRWenPriorityMatrix[index]; end assign CSRCountShort = +EnabledCSRs; assign CSRCount = {{{12-MAX_CSRS}{1'b0}}, CSRCountShort}; From fe9ac369288f0ec8f1f103442ded68a4c403aa89 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 23 Jul 2024 16:22:23 -0500 Subject: [PATCH 82/95] Fixed rvvi csr counting. --- src/rvvi/rvvisynth.sv | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/rvvi/rvvisynth.sv b/src/rvvi/rvvisynth.sv index d4847c9d4..7bdc05d10 100644 --- a/src/rvvi/rvvisynth.sv +++ b/src/rvvi/rvvisynth.sv @@ -123,7 +123,15 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, assign CSRs[(index+1) * (P.XLEN + 12)- 1: index * (P.XLEN + 12)] = {CSRValue[index], CSRAddr[index]}; assign EnabledCSRs[index] = |CSRWenPriorityMatrix[index]; end - assign CSRCountShort = +EnabledCSRs; + + integer index2; + always_comb begin + CSRCountShort = '0; + for(index2 = 0; index2 < MAX_CSRS; index2++) begin + CSRCountShort += EnabledCSRs[index2]; + end + end + assign CSRCount = {{{12-MAX_CSRS}{1'b0}}, CSRCountShort}; assign rvvi = {CSRs, Registers, Required}; From bfb3b63a24ce8249d532d24abb0507290ea492a3 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 23 Jul 2024 16:35:05 -0500 Subject: [PATCH 83/95] Code cleanup. --- src/rvvi/rvvisynth.sv | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/rvvi/rvvisynth.sv b/src/rvvi/rvvisynth.sv index 7bdc05d10..83c865529 100644 --- a/src/rvvi/rvvisynth.sv +++ b/src/rvvi/rvvisynth.sv @@ -27,8 +27,6 @@ // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// -`define FPGA 0 - module rvvisynth import cvw::*; #(parameter cvw_t P, parameter integer MAX_CSRS = 3, parameter integer TOTAL_CSRS = 36)( @@ -109,11 +107,6 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, assign CSRWenFilterMatrix[0] = CSRArrayWen; for(index = 1; index < MAX_CSRS; index = index + 1) begin -/* -----\/----- EXCLUDED -----\/----- - logic [MAX_CSRS-index-1:0] CSRWenShort; - priorityaomux #(MAX_CSRS-index, P.XLEN) priorityaomux(CSRArrayWen[MAX_CSRS-1:index], CSRArray[MAX_CSRS-1:index], CSRValue[index], CSRWenShort); - assign CSRWen[index] = {{{index}{1'b0}}, CSRWenShort}; - -----/\----- EXCLUDED -----/\----- */ priorityaomux #(TOTAL_CSRS, P.XLEN) priorityaomux(CSRWenFilterMatrix[index], CSRArray, CSRValue[index], CSRWenPriorityMatrix[index]); assign CSRWenFilterMatrix[index] = CSRWenFilterMatrix[index-1] & ~CSRWenPriorityMatrix[index-1]; end From 35efbd6a54cc0c4bf7884ce7ea0bb1353d67ffcb Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 23 Jul 2024 17:39:38 -0500 Subject: [PATCH 84/95] Changes are confirmed to work on the FPGA. --- src/rvvi/rvvisynth.sv | 2 +- testbench/testbench.sv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rvvi/rvvisynth.sv b/src/rvvi/rvvisynth.sv index 83c865529..f42e9c1a8 100644 --- a/src/rvvi/rvvisynth.sv +++ b/src/rvvi/rvvisynth.sv @@ -28,7 +28,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module rvvisynth import cvw::*; #(parameter cvw_t P, - parameter integer MAX_CSRS = 3, + parameter integer MAX_CSRS = 5, parameter integer TOTAL_CSRS = 36)( input logic clk, reset, input logic StallE, StallM, StallW, FlushE, FlushM, FlushW, diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 4885a6121..318d3d016 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -604,7 +604,7 @@ module testbench; end if(P.RVVI_SYNTH_SUPPORTED) begin : rvvi_synth - localparam MAX_CSRS = 3; + localparam MAX_CSRS = 5; logic valid; logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; From 7960f26e846c2a20194d0ffcd919967cbcad97d6 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Tue, 23 Jul 2024 17:44:37 -0500 Subject: [PATCH 85/95] Handled all remaining verilator warnings in the rvvi synth code. Now it's time to take on the verilog-ethernet warnings. --- src/rvvi/rvvisynth.sv | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/rvvi/rvvisynth.sv b/src/rvvi/rvvisynth.sv index f42e9c1a8..0c0214b3f 100644 --- a/src/rvvi/rvvisynth.sv +++ b/src/rvvi/rvvisynth.sv @@ -88,6 +88,9 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, {FPRWen, GPRWen} == 2'b10 ? {XLENZeros, 5'b0, FPRValue, FPRAddr} : '0; + /* verilator lint_off UNOPTFLAT */ + // For some reason verilator complains about CSRWenFilterMatrix being in a circular loop when it is not. + // the CSRs are complex // 1. we need to get the CSR values // 2. we check if the CSR value changes by registering the value then XORing with the old value. @@ -121,9 +124,12 @@ module rvvisynth import cvw::*; #(parameter cvw_t P, always_comb begin CSRCountShort = '0; for(index2 = 0; index2 < MAX_CSRS; index2++) begin + /* verilator lint_off WIDTHEXPAND */ CSRCountShort += EnabledCSRs[index2]; + /* verilator lint_on WIDTHEXPAND */ end end + /* verilator lint_on UNOPTFLAT */ assign CSRCount = {{{12-MAX_CSRS}{1'b0}}, CSRCountShort}; assign rvvi = {CSRs, Registers, Required}; From fb1869fcb9099da83a4af87f40a5619bb07a1e5b Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Wed, 24 Jul 2024 10:13:03 -0500 Subject: [PATCH 86/95] Updated verilog-ethernet to remove all verilator warnings or at least suppress them. --- addins/verilog-ethernet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addins/verilog-ethernet b/addins/verilog-ethernet index 471394b80..c180b22ed 160000 --- a/addins/verilog-ethernet +++ b/addins/verilog-ethernet @@ -1 +1 @@ -Subproject commit 471394b80c95a4859cd55a0f253d5ea502371e98 +Subproject commit c180b22ed5f4112d0ef35b2c5ac1acc45f9ebb5d From c11036358a86d0196edb81668bfca4a1cae7c8d7 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Wed, 24 Jul 2024 12:47:50 -0500 Subject: [PATCH 87/95] Converted fpga's rvvi from a config option to a testbench/fpga top level parameter and is envoked by passing --rvvi to wsim. --- bin/wsim | 4 ++++ config/derivlist.txt | 4 ---- config/rv32e/config.vh | 5 ----- config/rv32gc/config.vh | 5 ----- config/rv32i/config.vh | 5 ----- config/rv32imc/config.vh | 5 ----- config/rv64gc/config.vh | 5 ----- config/rv64i/config.vh | 5 ----- config/shared/parameter-defs.vh | 5 +---- fpga/generator/wally.tcl | 4 ++-- fpga/src/fpgaTopArtyA7.sv | 8 +++++--- src/cvw.sv | 4 ---- src/rvvi/packetizer.sv | 9 ++++++--- testbench/testbench.sv | 12 ++++++------ 14 files changed, 24 insertions(+), 56 deletions(-) diff --git a/bin/wsim b/bin/wsim index b70d0e26f..b2288deb4 100755 --- a/bin/wsim +++ b/bin/wsim @@ -33,6 +33,7 @@ parser.add_argument("--vcd", "-v", help="Generate testbench.vcd", action="store_ parser.add_argument("--lockstep", "-l", help="Run ImperasDV lock, step, and compare.", action="store_true") parser.add_argument("--locksteplog", "-b", help="Retired instruction number to be begin logging.", default=0) parser.add_argument("--covlog", "-d", help="Log coverage after n instructions.", default=0) +parser.add_argument("--rvvi", "-r", help="Simulate rvvi hardware interface and ethernet.", action="store_true") args = parser.parse_args() print("Config=" + args.config + " tests=" + args.testsuite + " sim=" + args.sim + " gui=" + str(args.gui) + " args='" + args.args + "'") ElfFile="" @@ -64,6 +65,9 @@ if (args.gui or args.ccov or args.fcov or args.lockstep): if (args.vcd): args.args += " -DMAKEVCD=1" +if (args.rvvi): + args.args += " -GRVVI_SYNTH_SUPPORTED=1" + # if lockstep is enabled, then we need to pass the Imperas lockstep arguments if(int(args.locksteplog) >= 1): EnableLog = 1 else: EnableLog = 0 diff --git a/config/derivlist.txt b/config/derivlist.txt index 048adcb21..1edd20b7b 100644 --- a/config/derivlist.txt +++ b/config/derivlist.txt @@ -57,10 +57,6 @@ EXT_MEM_RANGE 64'h0FFFFFFF SDC_SUPPORTED 1 PLIC_SDC_ID 32'd20 BPRED_SIZE 32'd12 -RVVI_SYNTH_SUPPORTED 1 -RVVI_INIT_TIME_OUT 32'd100000000 -RVVI_PACKET_DELAY 32'd400 - # The syn configurations are trimmed down for faster synthesis. deriv syn_rv32e rv32e diff --git a/config/rv32e/config.vh b/config/rv32e/config.vh index 1234bbcdf..4ec0123d1 100644 --- a/config/rv32e/config.vh +++ b/config/rv32e/config.vh @@ -225,9 +225,4 @@ localparam DIVCOPIES = 32'd4; // Memory synthesis configuration localparam logic USE_SRAM = 0; -// debug tools -localparam logic RVVI_SYNTH_SUPPORTED = 0; -localparam [31:0] RVVI_INIT_TIME_OUT = 32'd4; -localparam [31:0] RVVI_PACKET_DELAY = 32'd2; - `include "config-shared.vh" diff --git a/config/rv32gc/config.vh b/config/rv32gc/config.vh index 9f5809383..c861759d9 100644 --- a/config/rv32gc/config.vh +++ b/config/rv32gc/config.vh @@ -225,9 +225,4 @@ localparam DIVCOPIES = 32'd2; // Memory synthesis configuration localparam logic USE_SRAM = 0; -// debug tools -localparam logic RVVI_SYNTH_SUPPORTED = 0; -localparam [31:0] RVVI_INIT_TIME_OUT = 32'd4; -localparam [31:0] RVVI_PACKET_DELAY = 32'd2; - `include "config-shared.vh" diff --git a/config/rv32i/config.vh b/config/rv32i/config.vh index 6bfea805e..01818afc2 100644 --- a/config/rv32i/config.vh +++ b/config/rv32i/config.vh @@ -225,9 +225,4 @@ localparam DIVCOPIES = 32'd4; // Memory synthesis configuration localparam logic USE_SRAM = 0; -// debug tools -localparam logic RVVI_SYNTH_SUPPORTED = 0; -localparam [31:0] RVVI_INIT_TIME_OUT = 32'd4; -localparam [31:0] RVVI_PACKET_DELAY = 32'd2; - `include "config-shared.vh" diff --git a/config/rv32imc/config.vh b/config/rv32imc/config.vh index 3918c702c..05a8fd242 100644 --- a/config/rv32imc/config.vh +++ b/config/rv32imc/config.vh @@ -225,9 +225,4 @@ localparam DIVCOPIES = 32'd4; // Memory synthesis configuration localparam logic USE_SRAM = 0; -// debug tools -localparam logic RVVI_SYNTH_SUPPORTED = 0; -localparam [31:0] RVVI_INIT_TIME_OUT = 32'd4; -localparam [31:0] RVVI_PACKET_DELAY = 32'd2; - `include "config-shared.vh" diff --git a/config/rv64gc/config.vh b/config/rv64gc/config.vh index 86036aaa7..b8ed8dc47 100644 --- a/config/rv64gc/config.vh +++ b/config/rv64gc/config.vh @@ -225,9 +225,4 @@ localparam DIVCOPIES = 32'd4; // Memory synthesis configuration localparam logic USE_SRAM = 0; -// debug tools -localparam logic RVVI_SYNTH_SUPPORTED = 0; -localparam [31:0] RVVI_INIT_TIME_OUT = 32'd4; -localparam [31:0] RVVI_PACKET_DELAY = 32'd2; - `include "config-shared.vh" diff --git a/config/rv64i/config.vh b/config/rv64i/config.vh index 0e13f9ea1..94360877f 100644 --- a/config/rv64i/config.vh +++ b/config/rv64i/config.vh @@ -225,9 +225,4 @@ localparam DIVCOPIES = 32'd4; // Memory synthesis configuration localparam logic USE_SRAM = 0; -// debug tools -localparam logic RVVI_SYNTH_SUPPORTED = 0; -localparam [31:0] RVVI_INIT_TIME_OUT = 32'd4; -localparam [31:0] RVVI_PACKET_DELAY = 32'd2; - `include "config-shared.vh" diff --git a/config/shared/parameter-defs.vh b/config/shared/parameter-defs.vh index 14b5ee45c..c80b00232 100644 --- a/config/shared/parameter-defs.vh +++ b/config/shared/parameter-defs.vh @@ -200,9 +200,6 @@ localparam cvw_t P = '{ DURLEN : DURLEN, DIVb : DIVb, DIVBLEN : DIVBLEN, - INTDIVb : INTDIVb, - RVVI_SYNTH_SUPPORTED : RVVI_SYNTH_SUPPORTED, - RVVI_INIT_TIME_OUT : RVVI_INIT_TIME_OUT, - RVVI_PACKET_DELAY : RVVI_PACKET_DELAY + INTDIVb : INTDIVb }; diff --git a/fpga/generator/wally.tcl b/fpga/generator/wally.tcl index 9df775646..93c2788a2 100644 --- a/fpga/generator/wally.tcl +++ b/fpga/generator/wally.tcl @@ -89,8 +89,8 @@ report_clock_interaction -file re write_verilog -force -mode funcsim sim/syn-funcsim.v if {$board=="ArtyA7"} { - source ../constraints/small-debug.xdc - #source ../constraints/small-debug-rvvi.xdc + #source ../constraints/small-debug.xdc + source ../constraints/small-debug-rvvi.xdc } else { # source ../constraints/vcu-small-debug.xdc diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index 314b141a5..9413cedec 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -28,7 +28,7 @@ import cvw::*; -module fpgaTop +module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 0) (input default_100mhz_clk, (* mark_debug = "true" *) input resetn, input south_reset, @@ -1117,9 +1117,11 @@ module fpgaTop (* mark_debug = "true" *) logic IlaTrigger; - if(P.RVVI_SYNTH_SUPPORTED) begin : rvvi_synth + if(RVVI_SYNTH_SUPPORTED) begin : rvvi_synth localparam MAX_CSRS = 3; localparam TOTAL_CSRS = 36; + localparam [31:0] RVVI_INIT_TIME_OUT = 32'd100000000; + localparam [31:0] RVVI_PACKET_DELAY = 32'd400; // pipeline controlls logic StallE, StallM, StallW, FlushE, FlushM, FlushW; @@ -1218,7 +1220,7 @@ module fpgaTop logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; - packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(CPUCLK), .m_axi_aresetn(~bus_struct_reset), .RVVIStall, + packetizer #(P, MAX_CSRS, RVVI_INIT_TIME_OUT, RVVI_PACKET_DELAY) packetizer(.rvvi, .valid, .m_axi_aclk(CPUCLK), .m_axi_aresetn(~bus_struct_reset), .RVVIStall, .RvviAxiWdata, .RvviAxiWstrb, .RvviAxiWlast, .RvviAxiWvalid, .RvviAxiWready); eth_mac_mii_fifo #(.TARGET("XILINX"), .CLOCK_INPUT_STYLE("BUFG"), .AXIS_DATA_WIDTH(32), .TX_FIFO_DEPTH(1024)) ethernet(.rst(bus_struct_reset), .logic_clk(CPUCLK), .logic_rst(bus_struct_reset), diff --git a/src/cvw.sv b/src/cvw.sv index 7a64be7ba..ed0493484 100644 --- a/src/cvw.sv +++ b/src/cvw.sv @@ -296,10 +296,6 @@ typedef struct packed { int DIVBLEN ; // integer division/remainder constants int INTDIVb ; -// debug tools - logic RVVI_SYNTH_SUPPORTED; - logic [31:0] RVVI_INIT_TIME_OUT; - logic [31:0] RVVI_PACKET_DELAY; } cvw_t; endpackage diff --git a/src/rvvi/packetizer.sv b/src/rvvi/packetizer.sv index 54dc9a27f..cd3103fa4 100644 --- a/src/rvvi/packetizer.sv +++ b/src/rvvi/packetizer.sv @@ -28,7 +28,10 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module packetizer import cvw::*; #(parameter cvw_t P, - parameter integer MAX_CSRS)( + parameter integer MAX_CSRS, + parameter logic [31:0] RVVI_INIT_TIME_OUT = 32'd4, + parameter logic [31:0] RVVI_PACKET_DELAY = 32'd2 +)( input logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi, input logic valid, input logic m_axi_aclk, m_axi_aresetn, @@ -100,8 +103,8 @@ module packetizer import cvw::*; #(parameter cvw_t P, // have to count at least 250 ms after reset pulled to wait for the phy to actually be ready // at 20MHz 250 ms is 250e-3 / (1/20e6) = 5,000,000. counter #(32) rstcounter(m_axi_aclk, RstCountRst, RstCountEn, RstCount); - assign CountFlag = RstCount == P.RVVI_INIT_TIME_OUT; - assign DelayFlag = RstCount == P.RVVI_PACKET_DELAY; + assign CountFlag = RstCount == RVVI_INIT_TIME_OUT; + assign DelayFlag = RstCount == RVVI_PACKET_DELAY; counter #(32) framecounter(m_axi_aclk, ~m_axi_aresetn, (RvviAxiWready & RvviAxiWlast), FrameCount); diff --git a/testbench/testbench.sv b/testbench/testbench.sv index 318d3d016..a32a294d0 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -33,9 +33,6 @@ `include "idv/idv.svh" `endif -// *** bug replace with config? -`define RVVI_SYNTH_SUPPORTED 1 - import cvw::*; module testbench; @@ -46,6 +43,7 @@ module testbench; parameter BPRED_LOGGER=0; parameter I_CACHE_ADDR_LOGGER=0; parameter D_CACHE_ADDR_LOGGER=0; + parameter RVVI_SYNTH_SUPPORTED=0; `ifdef USE_IMPERAS_DV import idvPkg::*; @@ -603,9 +601,11 @@ module testbench; clk = 1'b1; # 5; clk = 1'b0; # 5; end - if(P.RVVI_SYNTH_SUPPORTED) begin : rvvi_synth + if(RVVI_SYNTH_SUPPORTED) begin : rvvi_synth localparam MAX_CSRS = 5; - logic valid; + localparam logic [31:0] RVVI_INIT_TIME_OUT = 32'd4; + localparam logic [31:0] RVVI_PACKET_DELAY = 32'd2; + logic valid; logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; localparam TOTAL_CSRS = 36; @@ -702,7 +702,7 @@ module testbench; logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; - packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, + packetizer #(P, MAX_CSRS, RVVI_INIT_TIME_OUT, RVVI_PACKET_DELAY) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, .RvviAxiWdata, .RvviAxiWstrb, .RvviAxiWlast, .RvviAxiWvalid, .RvviAxiWready); eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(reset), .logic_clk(clk), .logic_rst(reset), From 13db14db6b5a324b7d2d545c67b0ee05d9c29202 Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Wed, 24 Jul 2024 13:10:57 -0500 Subject: [PATCH 88/95] Factored out the rvvi testbench code into rvvitbwrapper. --- fpga/src/fpgaTopArtyA7.sv | 2 +- testbench/common/rvvitbwrapper.sv | 170 ++++++++++++++++++++++++++++++ testbench/testbench.sv | 126 +--------------------- 3 files changed, 174 insertions(+), 124 deletions(-) create mode 100644 testbench/common/rvvitbwrapper.sv diff --git a/fpga/src/fpgaTopArtyA7.sv b/fpga/src/fpgaTopArtyA7.sv index 9413cedec..827ca1438 100644 --- a/fpga/src/fpgaTopArtyA7.sv +++ b/fpga/src/fpgaTopArtyA7.sv @@ -28,7 +28,7 @@ import cvw::*; -module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 0) +module fpgaTop #(parameter logic RVVI_SYNTH_SUPPORTED = 1) (input default_100mhz_clk, (* mark_debug = "true" *) input resetn, input south_reset, diff --git a/testbench/common/rvvitbwrapper.sv b/testbench/common/rvvitbwrapper.sv new file mode 100644 index 000000000..708cd0e7b --- /dev/null +++ b/testbench/common/rvvitbwrapper.sv @@ -0,0 +1,170 @@ +/////////////////////////////////////////// +// loggers.sv +// +// Written: Rose Thompson ross1728@gmail.com +// Modified: 24 July 2024 +// +// Purpose: Wraps all the synthesizable rvvi hardware into a single module for the testbench. +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 +// +// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file +// except in compliance with the License, or, at your option, the Apache License version 2.0. You +// may obtain a copy of the License at +// +// https://solderpad.org/licenses/SHL-2.1/ +// +// Unless required by applicable law or agreed to in writing, any work distributed under the +// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +// either express or implied. See the License for the specific language governing permissions +// and limitations under the License. +//////////////////////////////////////////////////////////////////////////////////////////////// + +module rvvitbwrapper import cvw::*; #(parameter cvw_t P, + parameter MAX_CSRS = 5, + parameter logic [31:0] RVVI_INIT_TIME_OUT = 32'd4, + parameter logic [31:0] RVVI_PACKET_DELAY = 32'd2)( + input logic clk, + input logic reset, + output logic RVVIStall, + input logic mii_tx_clk, + output logic [3:0] mii_txd, + output logic mii_tx_en, mii_tx_er, + input logic mii_rx_clk, + input logic [3:0] mii_rxd, + input logic mii_rx_dv, + input logic mii_rx_er +); + + logic valid; + logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; + + localparam TOTAL_CSRS = 36; + + // pipeline controlls + logic StallE, StallM, StallW, FlushE, FlushM, FlushW; + // required + logic [P.XLEN-1:0] PCM; + logic InstrValidM; + logic [31:0] InstrRawD; + logic [63:0] Mcycle, Minstret; + logic TrapM; + logic [1:0] PrivilegeModeW; + // registers gpr and fpr + logic GPRWen, FPRWen; + logic [4:0] GPRAddr, FPRAddr; + logic [P.XLEN-1:0] GPRValue, FPRValue; + logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0]; + + // axi 4 write data channel + logic [31:0] RvviAxiWdata; + logic [3:0] RvviAxiWstrb; + logic RvviAxiWlast; + logic RvviAxiWvalid; + logic RvviAxiWready; + + logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; + logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; + + logic MiiTxEnDelay; + logic EthernetTXCounterEn; + logic [31:0] EthernetTXCount; + + assign StallE = dut.core.StallE; + assign StallM = dut.core.StallM; + assign StallW = dut.core.StallW; + assign FlushE = dut.core.FlushE; + assign FlushM = dut.core.FlushM; + assign FlushW = dut.core.FlushW; + assign InstrValidM = dut.core.ieu.InstrValidM; + assign InstrRawD = dut.core.ifu.InstrRawD; + assign PCM = dut.core.ifu.PCM; + assign Mcycle = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; + assign Minstret = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; + assign TrapM = dut.core.TrapM; + assign PrivilegeModeW = dut.core.priv.priv.privmode.PrivilegeModeW; + assign GPRAddr = dut.core.ieu.dp.regf.a3; + assign GPRWen = dut.core.ieu.dp.regf.we3; + assign GPRValue = dut.core.ieu.dp.regf.wd3; + assign FPRAddr = dut.core.fpu.fpu.fregfile.a4; + assign FPRWen = dut.core.fpu.fpu.fregfile.we4; + assign FPRValue = dut.core.fpu.fpu.fregfile.wd4; + + assign CSRArray[0] = dut.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 + assign CSRArray[1] = dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 + assign CSRArray[2] = dut.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 + assign CSRArray[3] = dut.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 + assign CSRArray[4] = dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 + assign CSRArray[5] = dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 + assign CSRArray[6] = dut.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 + assign CSRArray[7] = dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 + assign CSRArray[8] = dut.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 + assign CSRArray[9] = dut.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 + assign CSRArray[10] = dut.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 + assign CSRArray[11] = dut.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A + assign CSRArray[12] = dut.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 + assign CSRArray[13] = dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 + assign CSRArray[14] = dut.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 + assign CSRArray[15] = dut.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 + assign CSRArray[16] = 0; // 12'hF11 + assign CSRArray[17] = 0; // 12'hF12 + assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 + assign CSRArray[19] = 0; // 12'hF15 + assign CSRArray[20] = 0; // 12'h34A + // supervisor CSRs + assign CSRArray[21] = dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 + assign CSRArray[22] = dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 + assign CSRArray[23] = dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 + assign CSRArray[24] = dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 + assign CSRArray[25] = dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 + assign CSRArray[26] = dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A + assign CSRArray[27] = dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 + assign CSRArray[28] = dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 + assign CSRArray[29] = dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 + assign CSRArray[30] = dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 + assign CSRArray[31] = dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 + assign CSRArray[32] = dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D + // user CSRs + assign CSRArray[33] = dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 + assign CSRArray[34] = dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 + assign CSRArray[35] = {dut.core.priv.priv.csr.csru.csru.FRM_REGW, dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 + + rvvisynth #(P, MAX_CSRS, TOTAL_CSRS) rvvisynth(.clk, .reset, .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, + .PCM, .InstrValidM, .InstrRawD, .Mcycle, .Minstret, .TrapM, + .PrivilegeModeW, .GPRWen, .FPRWen, .GPRAddr, .FPRAddr, .GPRValue, .FPRValue, .CSRArray, + .valid, .rvvi); + + packetizer #(P, MAX_CSRS, RVVI_INIT_TIME_OUT, RVVI_PACKET_DELAY) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, + .RvviAxiWdata, .RvviAxiWstrb, .RvviAxiWlast, .RvviAxiWvalid, .RvviAxiWready); + + eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(reset), .logic_clk(clk), .logic_rst(reset), + .tx_axis_tdata(RvviAxiWdata), .tx_axis_tkeep(RvviAxiWstrb), .tx_axis_tvalid(RvviAxiWvalid), .tx_axis_tready(RvviAxiWready), + .tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), + .rx_axis_tlast(), .rx_axis_tuser(), + + .mii_rx_clk(clk), + .mii_rxd('0), + .mii_rx_dv('0), + .mii_rx_er('0), + .mii_tx_clk(clk), + .mii_txd, + .mii_tx_en, + .mii_tx_er, + + // status + .tx_error_underflow, .tx_fifo_overflow, .tx_fifo_bad_frame, .tx_fifo_good_frame, .rx_error_bad_frame, + .rx_error_bad_fcs, .rx_fifo_overflow, .rx_fifo_bad_frame, .rx_fifo_good_frame, + .cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1)); + + flopr #(1) txedgereg(clk, reset, mii_tx_en, MiiTxEnDelay); + assign EthernetTXCounterEn = ~mii_tx_en & MiiTxEnDelay; + counter #(32) ethernexttxcounter(clk, reset, EthernetTXCounterEn, EthernetTXCount); + +endmodule + + + diff --git a/testbench/testbench.sv b/testbench/testbench.sv index a32a294d0..55bb35843 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -605,133 +605,13 @@ module testbench; localparam MAX_CSRS = 5; localparam logic [31:0] RVVI_INIT_TIME_OUT = 32'd4; localparam logic [31:0] RVVI_PACKET_DELAY = 32'd2; - logic valid; - logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi; - - localparam TOTAL_CSRS = 36; - - // pipeline controlls - logic StallE, StallM, StallW, FlushE, FlushM, FlushW; - // required - logic [P.XLEN-1:0] PCM; - logic InstrValidM; - logic [31:0] InstrRawD; - logic [63:0] Mcycle, Minstret; - logic TrapM; - logic [1:0] PrivilegeModeW; - // registers gpr and fpr - logic GPRWen, FPRWen; - logic [4:0] GPRAddr, FPRAddr; - logic [P.XLEN-1:0] GPRValue, FPRValue; - logic [P.XLEN-1:0] CSRArray [TOTAL_CSRS-1:0]; - - assign StallE = dut.core.StallE; - assign StallM = dut.core.StallM; - assign StallW = dut.core.StallW; - assign FlushE = dut.core.FlushE; - assign FlushM = dut.core.FlushM; - assign FlushW = dut.core.FlushW; - assign InstrValidM = dut.core.ieu.InstrValidM; - assign InstrRawD = dut.core.ifu.InstrRawD; - assign PCM = dut.core.ifu.PCM; - assign Mcycle = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; - assign Minstret = dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; - assign TrapM = dut.core.TrapM; - assign PrivilegeModeW = dut.core.priv.priv.privmode.PrivilegeModeW; - assign GPRAddr = dut.core.ieu.dp.regf.a3; - assign GPRWen = dut.core.ieu.dp.regf.we3; - assign GPRValue = dut.core.ieu.dp.regf.wd3; - assign FPRAddr = dut.core.fpu.fpu.fregfile.a4; - assign FPRWen = dut.core.fpu.fpu.fregfile.we4; - assign FPRValue = dut.core.fpu.fpu.fregfile.wd4; - - assign CSRArray[0] = dut.core.priv.priv.csr.csrm.MSTATUS_REGW; // 12'h300 - assign CSRArray[1] = dut.core.priv.priv.csr.csrm.MSTATUSH_REGW; // 12'h310 - assign CSRArray[2] = dut.core.priv.priv.csr.csrm.MTVEC_REGW; // 12'h305 - assign CSRArray[3] = dut.core.priv.priv.csr.csrm.MEPC_REGW; // 12'h341 - assign CSRArray[4] = dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW; // 12'h306 - assign CSRArray[5] = dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW; // 12'h320 - assign CSRArray[6] = dut.core.priv.priv.csr.csrm.MEDELEG_REGW; // 12'h302 - assign CSRArray[7] = dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h303 - assign CSRArray[8] = dut.core.priv.priv.csr.csrm.MIP_REGW; // 12'h344 - assign CSRArray[9] = dut.core.priv.priv.csr.csrm.MIE_REGW; // 12'h304 - assign CSRArray[10] = dut.core.priv.priv.csr.csrm.MISA_REGW; // 12'h301 - assign CSRArray[11] = dut.core.priv.priv.csr.csrm.MENVCFG_REGW; // 12'h30A - assign CSRArray[12] = dut.core.priv.priv.csr.csrm.MHARTID_REGW; // 12'hF14 - assign CSRArray[13] = dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; // 12'h340 - assign CSRArray[14] = dut.core.priv.priv.csr.csrm.MCAUSE_REGW; // 12'h342 - assign CSRArray[15] = dut.core.priv.priv.csr.csrm.MTVAL_REGW; // 12'h343 - assign CSRArray[16] = 0; // 12'hF11 - assign CSRArray[17] = 0; // 12'hF12 - assign CSRArray[18] = {{P.XLEN-12{1'b0}}, 12'h100}; //P.XLEN'h100; // 12'hF13 - assign CSRArray[19] = 0; // 12'hF15 - assign CSRArray[20] = 0; // 12'h34A - // supervisor CSRs - assign CSRArray[21] = dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW; // 12'h100 - assign CSRArray[22] = dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222; // 12'h104 - assign CSRArray[23] = dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; // 12'h105 - assign CSRArray[24] = dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; // 12'h141 - assign CSRArray[25] = dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; // 12'h106 - assign CSRArray[26] = dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW; // 12'h10A - assign CSRArray[27] = dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; // 12'h180 - assign CSRArray[28] = dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; // 12'h140 - assign CSRArray[29] = dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; // 12'h143 - assign CSRArray[30] = dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW; // 12'h142 - assign CSRArray[31] = dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & dut.core.priv.priv.csr.csrm.MIDELEG_REGW; // 12'h144 - assign CSRArray[32] = dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW; // 12'h14D - // user CSRs - assign CSRArray[33] = dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW; // 12'h001 - assign CSRArray[34] = dut.core.priv.priv.csr.csru.csru.FRM_REGW; // 12'h002 - assign CSRArray[35] = {dut.core.priv.priv.csr.csru.csru.FRM_REGW, dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW}; // 12'h003 - - rvvisynth #(P, MAX_CSRS, TOTAL_CSRS) rvvisynth(.clk, .reset, .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, - .PCM, .InstrValidM, .InstrRawD, .Mcycle, .Minstret, .TrapM, - .PrivilegeModeW, .GPRWen, .FPRWen, .GPRAddr, .FPRAddr, .GPRValue, .FPRValue, .CSRArray, - .valid, .rvvi); - - // axi 4 write data channel - logic [31:0] RvviAxiWdata; - logic [3:0] RvviAxiWstrb; - logic RvviAxiWlast; - logic RvviAxiWvalid; - logic RvviAxiWready; logic [3:0] mii_txd; logic mii_tx_en, mii_tx_er; - - logic tx_error_underflow, tx_fifo_overflow, tx_fifo_bad_frame, tx_fifo_good_frame, rx_error_bad_frame; - logic rx_error_bad_fcs, rx_fifo_overflow, rx_fifo_bad_frame, rx_fifo_good_frame; - - packetizer #(P, MAX_CSRS, RVVI_INIT_TIME_OUT, RVVI_PACKET_DELAY) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall, - .RvviAxiWdata, .RvviAxiWstrb, .RvviAxiWlast, .RvviAxiWvalid, .RvviAxiWready); - - eth_mac_mii_fifo #("GENERIC", "BUFG", 32) ethernet(.rst(reset), .logic_clk(clk), .logic_rst(reset), - .tx_axis_tdata(RvviAxiWdata), .tx_axis_tkeep(RvviAxiWstrb), .tx_axis_tvalid(RvviAxiWvalid), .tx_axis_tready(RvviAxiWready), - .tx_axis_tlast(RvviAxiWlast), .tx_axis_tuser('0), .rx_axis_tdata(), .rx_axis_tkeep(), .rx_axis_tvalid(), .rx_axis_tready(1'b1), - .rx_axis_tlast(), .rx_axis_tuser(), - - .mii_rx_clk(clk), - .mii_rxd('0), - .mii_rx_dv('0), - .mii_rx_er('0), - .mii_tx_clk(clk), - .mii_txd, - .mii_tx_en, - .mii_tx_er, - - // status - .tx_error_underflow, .tx_fifo_overflow, .tx_fifo_bad_frame, .tx_fifo_good_frame, .rx_error_bad_frame, - .rx_error_bad_fcs, .rx_fifo_overflow, .rx_fifo_bad_frame, .rx_fifo_good_frame, - .cfg_ifg(8'd12), .cfg_tx_enable(1'b1), .cfg_rx_enable(1'b1) - ); - - logic MiiTxEnDelay; - logic EthernetTXCounterEn; - logic [31:0] EthernetTXCount; - flopr #(1) txedgereg(clk, reset, mii_tx_en, MiiTxEnDelay); - assign EthernetTXCounterEn = ~mii_tx_en & MiiTxEnDelay; - counter #(32) ethernexttxcounter(clk, reset, EthernetTXCounterEn, EthernetTXCount); + rvvitbwrapper #(P, MAX_CSRS, RVVI_INIT_TIME_OUT, RVVI_PACKET_DELAY) + rvvitbwrapper(.clk, .reset, .RVVIStall, .mii_tx_clk(clk), .mii_txd, .mii_tx_en, .mii_tx_er, + .mii_rx_clk(clk), .mii_rxd('0), .mii_rx_dv('0), .mii_rx_er('0)); end else begin assign RVVIStall = '0; end From 994386f12c643ae7d26043df0a09ad071aad3e8e Mon Sep 17 00:00:00 2001 From: Rose Thompson Date: Wed, 24 Jul 2024 13:30:25 -0500 Subject: [PATCH 89/95] Removed unused file. --- fpga/rvvidaemon/send-copy.c | 133 ------------------------------------ 1 file changed, 133 deletions(-) delete mode 100644 fpga/rvvidaemon/send-copy.c diff --git a/fpga/rvvidaemon/send-copy.c b/fpga/rvvidaemon/send-copy.c deleted file mode 100644 index 5d7f85ee8..000000000 --- a/fpga/rvvidaemon/send-copy.c +++ /dev/null @@ -1,133 +0,0 @@ - -/* - * This program is free software: 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEST_MAC0 0x43 -#define DEST_MAC1 0x68 -#define DEST_MAC2 0x11 -#define DEST_MAC3 0x11 -#define DEST_MAC4 0x02 -#define DEST_MAC5 0x45 - -#define SRC_MAC0 0x54 -#define SRC_MAC1 0x16 -#define SRC_MAC2 0x00 -#define SRC_MAC3 0x00 -#define SRC_MAC4 0x54 -#define SRC_MAC5 0x8F - -#define DEFAULT_IF "eth0" -#define BUF_SIZ 1024 -#define ETHER_TYPE 0x5c00 // The type defined in packetizer.sv - -int main(int argc, char *argv[]) -{ - int sockfd; - struct ifreq if_idx; - struct ifreq if_mac; - int tx_len = 0; - char sendbuf[BUF_SIZ]; - struct ether_header *eh = (struct ether_header *) sendbuf; - struct iphdr *iph = (struct iphdr *) (sendbuf + sizeof(struct ether_header)); - struct sockaddr_ll socket_address; - char ifName[IFNAMSIZ]; - - /* Get interface name */ - if (argc > 1) - strcpy(ifName, argv[1]); - else - strcpy(ifName, DEFAULT_IF); - - /* Open RAW socket to send on */ - //if ((sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW)) == -1) { - if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) { - perror("socket"); - } - - /* Get the index of the interface to send on */ - memset(&if_idx, 0, sizeof(struct ifreq)); - strncpy(if_idx.ifr_name, ifName, IFNAMSIZ-1); - if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) - perror("SIOCGIFINDEX"); - /* Get the MAC address of the interface to send on */ - memset(&if_mac, 0, sizeof(struct ifreq)); - strncpy(if_mac.ifr_name, ifName, IFNAMSIZ-1); - if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0) - perror("SIOCGIFHWADDR"); - - /* Construct the Ethernet header */ - memset(sendbuf, 0, BUF_SIZ); - /* Ethernet header */ - /* eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0]; */ - /* eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1]; */ - /* eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2]; */ - /* eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3]; */ - /* eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4]; */ - /* eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5]; */ - eh->ether_shost[0] = SRC_MAC0; - eh->ether_shost[1] = SRC_MAC1; - eh->ether_shost[2] = SRC_MAC2; - eh->ether_shost[3] = SRC_MAC3; - eh->ether_shost[4] = SRC_MAC4; - eh->ether_shost[5] = SRC_MAC5; - eh->ether_dhost[0] = DEST_MAC0; - eh->ether_dhost[1] = DEST_MAC1; - eh->ether_dhost[2] = DEST_MAC2; - eh->ether_dhost[3] = DEST_MAC3; - eh->ether_dhost[4] = DEST_MAC4; - eh->ether_dhost[5] = DEST_MAC5; - /* Ethertype field */ - //eh->ether_type = htons(ETH_P_IP); - eh->ether_type = htons(ETHER_TYPE); - tx_len += sizeof(struct ether_header); - - /* Packet data */ - sendbuf[tx_len++] = 0xde; - sendbuf[tx_len++] = 0xad; - sendbuf[tx_len++] = 0xbe; - sendbuf[tx_len++] = 0xef; - - /* Index of the network device */ - socket_address.sll_ifindex = if_idx.ifr_ifindex; - /* Address length*/ - socket_address.sll_halen = ETH_ALEN; - /* Destination MAC */ - socket_address.sll_addr[0] = DEST_MAC0; - socket_address.sll_addr[1] = DEST_MAC1; - socket_address.sll_addr[2] = DEST_MAC2; - socket_address.sll_addr[3] = DEST_MAC3; - socket_address.sll_addr[4] = DEST_MAC4; - socket_address.sll_addr[5] = DEST_MAC5; - - int i; - printf("buffer: "); - for(i=0;i Date: Wed, 24 Jul 2024 13:32:46 -0500 Subject: [PATCH 90/95] Fixed the reset bug in wallyTracer. --- testbench/common/wallyTracer.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testbench/common/wallyTracer.sv b/testbench/common/wallyTracer.sv index 8c72a6816..80f7af651 100644 --- a/testbench/common/wallyTracer.sv +++ b/testbench/common/wallyTracer.sv @@ -274,7 +274,7 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi); // Initially connecting the writeback stage signals, but may need to use M stage // and gate on ~FlushW. - assign valid = InstrValidW & ~StallW; + assign valid = InstrValidW & ~StallW & ~reset; assign rvvi.clk = clk; assign rvvi.valid[0][0] = valid; assign rvvi.order[0][0] = CSRArray[12'hB02]; // TODO: IMPERAS Should be event order From 337e40ac1b24da65e28607a3c9b0cf1109d796ce Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 25 Jul 2024 06:59:58 -0700 Subject: [PATCH 91/95] Issue #894: trap on floating-point ops with reserved rounding modes --- src/fpu/fctrl.sv | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index 8595fd29e..eed90ddcf 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -81,6 +81,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( logic [1:0] Fmt, Fmt2; // format - before possible reduction logic SupportedFmt; // is the format supported logic SupportedFmt2; // is the source format supported for fp -> fp + logic SupportedRM; // is the rounding mode supported logic FCvtIntD, FCvtIntM; // convert to integer operation logic ZfaD; // Zfa variants of instructions logic ZfaFRoundNXD; // Zfa froundnx instruction @@ -93,14 +94,16 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( (Fmt == 2'b10 & P.ZFH_SUPPORTED) | (Fmt == 2'b11 & P.Q_SUPPORTED)); assign SupportedFmt2 = (Fmt2 == 2'b00 | (Fmt2 == 2'b01 & P.D_SUPPORTED) | (Fmt2 == 2'b10 & P.ZFH_SUPPORTED) | (Fmt2 == 2'b11 & P.Q_SUPPORTED)); + // rounding modes 5 and 6 are reserved. Rounding mode 7 is dynamic, and is reserved if FRM is 5, 6, or 7 + assign SupportedRM = ~(Funct3D == 3'b101 | Funct3D == 3'b110 | (Funct3D == 3'b111 & (FRM_REGW == 3'b101 | FRM_REGW == 3'b110 | FRM_REGW == 3'b111))); // decode the instruction // FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt_Zfa_FroundNX always_comb if (STATUS_FS == 2'b00) // FPU instructions are illegal when FPU is disabled ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0_0_0; - else if (OpD != 7'b0000111 & OpD != 7'b0100111 & ~SupportedFmt) - ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0_0_0; // for anything other than loads and stores, check for supported format + else if (OpD != 7'b0000111 & OpD != 7'b0100111 & (~SupportedFmt | ~SupportedRM)) + ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0_0_0; // for anything other than loads and stores, check for supported format and rounding mode else begin ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0_0_0; // default: non-implemented instruction /* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed From 7234abebef08a5d28887d700f7a4998cd3926143 Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 25 Jul 2024 09:09:13 -0700 Subject: [PATCH 92/95] Issue #894: trap on floating-point ops with reserved rounding modes: detect Zfa flt --- src/fpu/fctrl.sv | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index eed90ddcf..ab9cad093 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -95,8 +95,11 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( assign SupportedFmt2 = (Fmt2 == 2'b00 | (Fmt2 == 2'b01 & P.D_SUPPORTED) | (Fmt2 == 2'b10 & P.ZFH_SUPPORTED) | (Fmt2 == 2'b11 & P.Q_SUPPORTED)); // rounding modes 5 and 6 are reserved. Rounding mode 7 is dynamic, and is reserved if FRM is 5, 6, or 7 - assign SupportedRM = ~(Funct3D == 3'b101 | Funct3D == 3'b110 | (Funct3D == 3'b111 & (FRM_REGW == 3'b101 | FRM_REGW == 3'b110 | FRM_REGW == 3'b111))); - + assign SupportedRM = ~(Funct3D == 3'b101 | Funct3D == 3'b110 | (Funct3D == 3'b111 & (FRM_REGW == 3'b101 | FRM_REGW == 3'b110 | FRM_REGW == 3'b111))) | + (OpD == 7'b1010011 & Funct3D == 3'b101 & Funct7D[6:2] == 5'b10100 & P.ZFA_SUPPORTED); // Zfa fltq has a funny rounding mode + /*assign SupportedRM = ~(Funct3D == 3'b101 | Funct3D == 3'b110 | (Funct3D == 3'b111 & (FRM_REGW == 3'b101 | FRM_REGW == 3'b110 | FRM_REGW == 3'b111))) | + (OpD == 7'b1010011 & P.ZFA_SUPPORTED); +*/ // decode the instruction // FRegWrite_FWriteInt_FResSel_PostProcSel_FOpCtrl_FDivStart_IllegalFPUInstr_FCvtInt_Zfa_FroundNX always_comb From c637e40058c9e48331fc1c366b51348410eb158f Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 25 Jul 2024 09:19:23 -0700 Subject: [PATCH 93/95] CHeck legal rnum field when decoding aes64ks1i --- src/ieu/bmu/bmuctrl.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index d482616ef..d4a8afe23 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -238,7 +238,7 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) ( if ((P.ZKND_SUPPORTED | P.ZKNE_SUPPORTED) & P.XLEN == 64) begin // ZKND and ZKNE shared instructions casez({OpD, Funct7D, Funct3D}) - 17'b0010011_0011000_001: if (Rs2D[4] == 1'b1) + 17'b0010011_0011000_001: if (Rs2D[4] == 1'b1 & $unsigned(Rs2D[3:0]) <= 10) BMUControlsD = `BMUCTRLW'b000_0111_0010_1_0_0_0_1_0_0_0_0_0; // aes64ks1i - key schedule istr1 17'b0110011_0111111_000: BMUControlsD = `BMUCTRLW'b000_0111_0011_1_0_0_0_1_0_0_0_0_0; // aes64ks2 - key schedule istr2 endcase From 7360be1234ff6b1db7c50b1df8273381f67ac04c Mon Sep 17 00:00:00 2001 From: David Harris Date: Thu, 25 Jul 2024 09:43:54 -0700 Subject: [PATCH 94/95] Legalized PMPconfig WARL --- src/privileged/csrm.sv | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/privileged/csrm.sv b/src/privileged/csrm.sv index f86b3f6d6..24132ab93 100644 --- a/src/privileged/csrm.sv +++ b/src/privileged/csrm.sv @@ -106,7 +106,10 @@ module csrm import cvw::*; #(parameter cvw_t P) ( genvar i; if (P.PMP_ENTRIES > 0) begin:pmp logic [P.PMP_ENTRIES-1:0] WritePMPCFGM; - logic [P.PMP_ENTRIES-1:0] WritePMPADDRM ; + logic [P.PMP_ENTRIES-1:0] WritePMPADDRM; + logic [7:0] CSRPMPWriteValM[P.PMP_ENTRIES-1:0]; + logic [7:0] CSRPMPLegalizedWriteValM[P.PMP_ENTRIES-1:0]; + logic [1:0] CSRPMPWRLegalizedWriteValM[P.PMP_ENTRIES-1:0]; logic [P.PMP_ENTRIES-1:0] ADDRLocked, CFGLocked; for(i=0; i Date: Thu, 25 Jul 2024 10:08:34 -0700 Subject: [PATCH 95/95] Updated ImperasTG derived config to turn off peripherals --- config/derivlist.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/config/derivlist.txt b/config/derivlist.txt index 1edd20b7b..c689d2cb9 100644 --- a/config/derivlist.txt +++ b/config/derivlist.txt @@ -1657,7 +1657,7 @@ IDIV_ON_FPU 1 # imperas used for a smart memory # VCS doesn't like removing the bootrom, but make it tiny in a random unused location -derive imperas rv64gc +derive ImperasTG rv64gc ICACHE_SUPPORTED 0 DCACHE_SUPPORTED 0 VIRTMEM_SUPPORTED 0 @@ -1668,6 +1668,13 @@ ZICBOM_SUPPORTED 0 ZICBOZ_SUPPORTED 0 SVPBMT_SUPPORTED 0 SVNAPOT_SUPPORTED 0 -BOOTROM_BASE 64'h700012340010 +BOOTROM_BASE 64'h700012340080 BOOTROM_RANGE 64'h10 +CLINT_SUPPORTED 0 +GPIO_SUPPORTED 0 +UART_SUPPORTED 0 +PLIC_SUPPORTED 0 +SPI_SUPPORTED 0 + +