Removed copy of FPGA source files.
Original-commit: fd3e84941de463fa1a7ebab0a69515b4bf2614cd
This commit is contained in:
@@ -1 +0,0 @@
|
||||
/build
|
||||
File diff suppressed because one or more lines are too long
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: LvFpga_Chinch_Interface.vhd
|
||||
-- Author: Ashish Chaudhari
|
||||
-- Original Project: EttusUsrpB250Top
|
||||
-- Date: 1 Oct 2013
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- (c) 2013 Copyright National Instruments Corporation
|
||||
-- All Rights Reserved
|
||||
-- National Instruments Internal Information
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
`include "LvFpga_Chinch_Interface.vh"
|
||||
|
||||
module LvFpga_Chinch_Interface
|
||||
(
|
||||
input aIoResetIn_n,
|
||||
output bBusReset,
|
||||
|
||||
input BusClk,
|
||||
input Rio40Clk,
|
||||
input IDelayRefClk,
|
||||
input aRioClkPllLocked,
|
||||
output aRioClkPllReset,
|
||||
|
||||
output aIoReadyOut,
|
||||
input aIoReadyIn,
|
||||
output aIoPort2Restart,
|
||||
|
||||
input IoRxClock,
|
||||
input IoRxClock_n,
|
||||
input [`LVFPGA_IFACE_LINK_WIDTH-1:0] irIoRxData,
|
||||
input [`LVFPGA_IFACE_LINK_WIDTH-1:0] irIoRxData_n,
|
||||
input irIoRxHeader,
|
||||
input irIoRxHeader_n,
|
||||
|
||||
output IoTxClock,
|
||||
output IoTxClock_n,
|
||||
output [`LVFPGA_IFACE_LINK_WIDTH-1:0] itIoTxData,
|
||||
output [`LVFPGA_IFACE_LINK_WIDTH-1:0] itIoTxData_n,
|
||||
output itIoTxHeader,
|
||||
output itIoTxHeader_n,
|
||||
|
||||
input [(`LVFPGA_IFACE_NUM_RX_DMA_CNT*`LVFPGA_IFACE_DMA_CHAN_WIDTH)-1:0] bDmaRxData,
|
||||
input [`LVFPGA_IFACE_NUM_RX_DMA_CNT-1:0] bDmaRxValid,
|
||||
output [`LVFPGA_IFACE_NUM_RX_DMA_CNT-1:0] bDmaRxReady,
|
||||
output [`LVFPGA_IFACE_NUM_RX_DMA_CNT-1:0] bDmaRxEnabled,
|
||||
output [(`LVFPGA_IFACE_NUM_RX_DMA_CNT*`LVFPGA_IFACE_DMA_SIZE_WIDTH)-1:0] bDmaRxFifoFreeCnt,
|
||||
|
||||
output [(`LVFPGA_IFACE_NUM_TX_DMA_CNT*`LVFPGA_IFACE_DMA_CHAN_WIDTH)-1:0] bDmaTxData,
|
||||
output [`LVFPGA_IFACE_NUM_TX_DMA_CNT-1:0] bDmaTxValid,
|
||||
input [`LVFPGA_IFACE_NUM_TX_DMA_CNT-1:0] bDmaTxReady,
|
||||
output [`LVFPGA_IFACE_NUM_TX_DMA_CNT-1:0] bDmaTxEnabled,
|
||||
output [(`LVFPGA_IFACE_NUM_TX_DMA_CNT*`LVFPGA_IFACE_DMA_SIZE_WIDTH)-1:0] bDmaTxFifoFullCnt,
|
||||
|
||||
output bUserRegPortInWt,
|
||||
output bUserRegPortInRd,
|
||||
output [`LVFPGA_IFACE_UREG_ADDR_WIDTH-1:0] bUserRegPortInAddr,
|
||||
output [`LVFPGA_IFACE_UREG_DATA_WIDTH-1:0] bUserRegPortInData,
|
||||
output [`LVFPGA_IFACE_UREG_SIZE_WIDTH-1:0] bUserRegPortInSize,
|
||||
input [`LVFPGA_IFACE_UREG_DATA_WIDTH-1:0] bUserRegPortOutData,
|
||||
input bUserRegPortOutDataValid,
|
||||
input bUserRegPortOutReady,
|
||||
|
||||
input bChinchRegPortOutWt,
|
||||
input bChinchRegPortOutRd,
|
||||
input [`LVFPGA_IFACE_CREG_ADDR_WIDTH-1:0] bChinchRegPortOutAddr,
|
||||
input [`LVFPGA_IFACE_CREG_DATA_WIDTH-1:0] bChinchRegPortOutData,
|
||||
input [`LVFPGA_IFACE_CREG_SIZE_WIDTH-1:0] bChinchRegPortOutSize,
|
||||
output [`LVFPGA_IFACE_CREG_DATA_WIDTH-1:0] bChinchRegPortInData,
|
||||
output bChinchRegPortInDataValid,
|
||||
output bChinchRegPortInReady,
|
||||
|
||||
output aIrq
|
||||
) /* synthesis syn_black_box syn_noprune=1 */;
|
||||
// This module serves as an API wrapper for LvFpga_Chinch_Interface.ngc and we don't want
|
||||
// the tool to accidentally prune out it contents. Hence the syn_black_box syn_noprune=1 directives.
|
||||
endmodule
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: LvFpga_Chinch_Interface.vh
|
||||
-- Author: Ashish Chaudhari
|
||||
-- Original Project: EttusUsrpB250Top
|
||||
-- Date: 1 Oct 2013
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- (c) 2013 Copyright National Instruments Corporation
|
||||
-- All Rights Reserved
|
||||
-- National Instruments Internal Information
|
||||
-------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
//Physical link width for the IoPort2 interface to the STC3
|
||||
`define LVFPGA_IFACE_LINK_WIDTH 16
|
||||
|
||||
//DMA Related Constants
|
||||
`define LVFPGA_IFACE_DMA_CHAN_WIDTH 64 //DMA data bus width
|
||||
`define LVFPGA_IFACE_DMA_SIZE_WIDTH 11 //DMA FIFO fullness count width
|
||||
`define LVFPGA_IFACE_NUM_RX_DMA_CNT 6 //Number of RX DMA channels
|
||||
`define LVFPGA_IFACE_NUM_TX_DMA_CNT 6 //Number of TX DMA channels
|
||||
`define LVFPGA_IFACE_RX_DMA_INDEX 0 //Index for the first RX DMA channel
|
||||
`define LVFPGA_IFACE_TX_DMA_INDEX 6 //Index for the first TX DMA channel
|
||||
|
||||
//User register port constants
|
||||
`define LVFPGA_IFACE_UREG_ADDR_WIDTH 20 //Address width
|
||||
`define LVFPGA_IFACE_UREG_DATA_WIDTH 32 //Payload width
|
||||
`define LVFPGA_IFACE_UREG_SIZE_WIDTH 2 //Transaction size width
|
||||
|
||||
//Chinch register port constants
|
||||
`define LVFPGA_IFACE_CREG_ADDR_WIDTH 32 //Address width
|
||||
`define LVFPGA_IFACE_CREG_DATA_WIDTH 64 //Payload width
|
||||
`define LVFPGA_IFACE_CREG_SIZE_WIDTH 2 //Transaction size width
|
||||
@@ -1,20 +0,0 @@
|
||||
#
|
||||
# Copyright 2012-2013 Ettus Research LLC
|
||||
#
|
||||
|
||||
##################################################
|
||||
# io_port2
|
||||
##################################################
|
||||
IOPORT2_SRCS = $(abspath $(addprefix $(BASE_DIR)/../lib/io_port2/, \
|
||||
./LvFpga_Chinch_Interface.v \
|
||||
./LvFpga_Chinch_Interface.ngc \
|
||||
./ioport2_msg_codec.v \
|
||||
./pcie_pkt_route_specifier.v \
|
||||
./pcie_axi_wb_conv.v \
|
||||
./pcie_wb_reg_core.v \
|
||||
./pcie_iop2_msg_arbiter.v \
|
||||
./pcie_basic_regs.v \
|
||||
./pcie_dma_ctrl.v \
|
||||
./data_swapper_64.v \
|
||||
./pcie_lossy_samp_gate.v \
|
||||
))
|
||||
@@ -1,76 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from xml.etree import ElementTree
|
||||
from collections import namedtuple
|
||||
import optparse
|
||||
import base64
|
||||
import md5
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Parse options
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option("--device", type="string", dest="device_type", help="Device Type. (Has to match the LVFPGA target plugin)", default=None)
|
||||
parser.add_option("--input-bin", type="string", dest="input_bin", help="Path to bin file that needs to be merged with the LVBITX before exporting", default=None)
|
||||
parser.add_option("--output-bin", type="string", dest="output_bin", help="Create a binary configuration bitstream", default=None)
|
||||
parser.add_option("--output-lvbitx", type="string", dest="output_lvbitx_path", help="Output path for autogenerated LVBITX file", default=None)
|
||||
parser.add_option("--output-src-path", type="string", dest="output_src_path", help="Output path for autogenerated src file", default=None)
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
# Args
|
||||
if (len(args) < 1):
|
||||
print 'ERROR: Please specify the input LVBITX file name'
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
lvbitx_filename = args[0]
|
||||
input_filename = os.path.abspath(lvbitx_filename)
|
||||
|
||||
if (not os.path.isfile(input_filename)):
|
||||
print 'ERROR: LVBITX File ' + input_filename + ' could not be accessed or is not a file.'
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
if (options.input_bin is not None and not os.path.isfile(os.path.abspath(options.input_bin))):
|
||||
print 'ERROR: FPGA Bin File ' + options.input_bin + ' could not be accessed or is not a file.'
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
if (options.output_lvbitx_path is not None and input_filename == options.output_lvbitx_path):
|
||||
print 'ERROR: Input and output LVBITX files were the same. Choose a difference input or output file.'
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
# Get XML Tree Node
|
||||
tree = ElementTree.parse(input_filename)
|
||||
root = tree.getroot()
|
||||
|
||||
# Update device type
|
||||
if (options.device_type is not None):
|
||||
root.find('Project').find('TargetClass').text += '; ' + options.device_type
|
||||
|
||||
# Merge bitstream into LVBITX
|
||||
if (options.input_bin is not None):
|
||||
with open(os.path.abspath(options.input_bin), 'rb') as bin_file:
|
||||
bitstream = bin_file.read()
|
||||
bitstream_md5 = md5.new(bitstream).hexdigest()
|
||||
bitstream_b64 = base64.b64encode(bitstream)
|
||||
bitstream_b64_lb = ''
|
||||
for i in range(0, len(bitstream_b64), 76):
|
||||
bitstream_b64_lb += bitstream_b64[i:i+76] + '\n'
|
||||
|
||||
root.find('Bitstream').text = bitstream_b64_lb
|
||||
root.find('BitstreamMD5').text = bitstream_md5
|
||||
|
||||
# Write BIN file
|
||||
bitstream = base64.b64decode(root.find('Bitstream').text)
|
||||
if (options.output_lvbitx_path is not None and md5.new(bitstream).hexdigest() != root.find('BitstreamMD5').text):
|
||||
print 'ERROR: The MD5 sum for the output LVBITX was incorrect. Make sure that the bitstream in the input LVBITX or BIN file is valid.'
|
||||
sys.exit(1)
|
||||
if (options.output_bin is not None):
|
||||
fpga_bin_file = open(options.output_bin, 'w')
|
||||
fpga_bin_file.write(bitstream)
|
||||
fpga_bin_file.close()
|
||||
|
||||
# Save LVBITX
|
||||
if (options.output_lvbitx_path is not None):
|
||||
tree.write(options.output_lvbitx_path, encoding="utf-8", xml_declaration=True, default_namespace=None, method="xml")
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Ettus Research LLC
|
||||
//
|
||||
|
||||
module data_swapper_64 (
|
||||
input [2:0] swap_lanes,
|
||||
|
||||
input [63:0] i_tdata,
|
||||
output [63:0] o_tdata
|
||||
);
|
||||
localparam SWAP_32B = 3'b100;
|
||||
localparam SWAP_16B = 3'b010;
|
||||
localparam SWAP_8B = 3'b001;
|
||||
|
||||
wire [63:0] data_p1, data_p2;
|
||||
|
||||
assign data_p1 = (|(swap_lanes & SWAP_32B)) ? { i_tdata[31:0], i_tdata[63:32] } : i_tdata;
|
||||
assign data_p2 = (|(swap_lanes & SWAP_16B)) ? { data_p1[47:32], data_p1[63:48], data_p1[15:0], data_p1[31:16] } : data_p1;
|
||||
assign o_tdata = (|(swap_lanes & SWAP_8B)) ? { data_p2[55:48], data_p2[63:56], data_p2[39:32], data_p2[47:40],
|
||||
data_p2[23:16], data_p2[31:24], data_p2[7:0], data_p2[15:8] } : data_p2;
|
||||
|
||||
endmodule // data_swapper_64
|
||||
@@ -1,49 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Ettus Research LLC
|
||||
//
|
||||
|
||||
|
||||
//Message format:
|
||||
// msg[63]: Completion {1 -> Read Completion, 0 -> Transaction Request}
|
||||
// msg[62]: Write request*
|
||||
// msg[61]: Read request*
|
||||
// msg[60]: Half word {1 -> 16-bit transaction, 0 -> 32-bit transaction}*
|
||||
// msg[59:52]: Reserved
|
||||
// msg[51:32]: Address*
|
||||
// msg[31:0]: Data
|
||||
//
|
||||
// * Field only valid when the word is a transaction request.
|
||||
|
||||
module ioport2_msg_decode(
|
||||
input [63:0] message,
|
||||
output rd_response,
|
||||
output wr_request,
|
||||
output rd_request,
|
||||
output half_word,
|
||||
output [19:0] address,
|
||||
output [31:0] data,
|
||||
output [31:0] control
|
||||
);
|
||||
assign rd_response = message[63];
|
||||
assign wr_request = message[62];
|
||||
assign rd_request = message[61];
|
||||
assign half_word = message[60];
|
||||
assign address = message[51:32];
|
||||
assign data = message[31:0];
|
||||
assign control = message[63:32];
|
||||
endmodule
|
||||
|
||||
|
||||
module ioport2_msg_encode(
|
||||
input rd_response,
|
||||
input wr_request,
|
||||
input rd_request,
|
||||
input half_word,
|
||||
input [19:0] address,
|
||||
input [31:0] data,
|
||||
output [31:0] control,
|
||||
output [63:0] message
|
||||
);
|
||||
assign control = rd_response ? {rd_response, 31'h0} : {rd_response, wr_request, rd_request, half_word, 8'h00, address};
|
||||
assign message = {control, data};
|
||||
endmodule
|
||||
@@ -1,196 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Ettus Research LLC
|
||||
//
|
||||
|
||||
|
||||
module pcie_axi_wb_conv #(
|
||||
parameter WB_ADDRW = 16,
|
||||
parameter WB_DATAW = 32
|
||||
)(
|
||||
input clk,
|
||||
input rst,
|
||||
|
||||
input wb_stb_i,
|
||||
input wb_we_i,
|
||||
input [WB_ADDRW-1:0] wb_adr_i,
|
||||
input [WB_DATAW-1:0] wb_dat_i,
|
||||
output wb_ack_o,
|
||||
output [WB_DATAW-1:0] wb_dat_o,
|
||||
|
||||
input [63:0] msgi_tdata,
|
||||
input msgi_tvalid,
|
||||
output msgi_tready,
|
||||
|
||||
output [63:0] msgo_tdata,
|
||||
output msgo_tvalid,
|
||||
input msgo_tready,
|
||||
|
||||
output wb_monitor_active,
|
||||
output reg wb_req_pending,
|
||||
output reg wb_resp_pending,
|
||||
output reg pcie_resp_pending
|
||||
);
|
||||
|
||||
localparam SB_ADDRW = 4;
|
||||
localparam SB_DATAW = 32;
|
||||
localparam MONITOR_TIMEOUTW = 20; //20bits@175MHz ~ 6ms
|
||||
|
||||
localparam SR_PCIE_DATA_REG = 4'd0;
|
||||
localparam SR_PCIE_CTRL_REG = 4'd1;
|
||||
localparam RB_PCIE_DATA_REG = 4'd0;
|
||||
localparam RB_PCIE_CTRL_REG = 4'd1;
|
||||
localparam RB_PCIE_RESP_DATA_REG = 4'd2;
|
||||
localparam RB_PCIE_STATUS_REG = 4'd3;
|
||||
|
||||
//------------------------------------------
|
||||
// Settings and readback bus
|
||||
//
|
||||
wire [SB_DATAW-1:0] set_data, rb_data;
|
||||
wire [SB_ADDRW-1:0] set_addr, rb_addr;
|
||||
wire set_stb, rb_stb;
|
||||
|
||||
settings_bus #(.AWIDTH(WB_ADDRW), .DWIDTH(WB_DATAW)) settings_bus (
|
||||
.wb_clk(clk), .wb_rst(rst),
|
||||
.wb_adr_i(wb_adr_i), .wb_dat_i(wb_dat_i),
|
||||
.wb_stb_i(wb_stb_i), .wb_we_i(wb_we_i), .wb_ack_o(wb_ack_o),
|
||||
.strobe(set_stb), .addr(set_addr), .data(set_data)
|
||||
);
|
||||
|
||||
settings_readback #(.AWIDTH(WB_ADDRW), .DWIDTH(WB_DATAW), .RB_ADDRW(SB_ADDRW)) settings_readback (
|
||||
.wb_clk(clk), .wb_rst(rst),
|
||||
.wb_adr_i(wb_adr_i), .wb_stb_i(wb_stb_i), .wb_we_i(wb_we_i),
|
||||
.rb_data(rb_data), .rb_addr(rb_addr), .rb_rd_stb(rb_stb),
|
||||
.wb_dat_o(wb_dat_o)
|
||||
);
|
||||
//------------------------------------------
|
||||
|
||||
//------------------------------------------
|
||||
// Settings/Readback Registers
|
||||
//
|
||||
wire [31:0] axi_out_data, axi_out_ctrl;
|
||||
wire axi_out_stb;
|
||||
|
||||
setting_reg #(.my_addr(SR_PCIE_DATA_REG), .awidth(SB_ADDRW), .width(SB_DATAW)) set_pcie_out_data_reg (
|
||||
.clk(clk), .rst(rst),
|
||||
.strobe(set_stb), .addr(set_addr), .in(set_data),
|
||||
.out(axi_out_data)
|
||||
);
|
||||
|
||||
setting_reg #(.my_addr(SR_PCIE_CTRL_REG), .awidth(SB_ADDRW), .width(SB_DATAW)) set_pcie_out_ctrl_reg (
|
||||
.clk(clk), .rst(rst),
|
||||
.strobe(set_stb), .addr(set_addr), .in(set_data),
|
||||
.out(axi_out_ctrl), .changed(axi_out_stb)
|
||||
);
|
||||
|
||||
reg [31:0] axi_in_data_reg, axi_in_ctrl_reg, axi_in_resp_reg;
|
||||
wire msgo_fifo_tready;
|
||||
|
||||
// Readback MUX
|
||||
assign rb_data = (
|
||||
(rb_addr == RB_PCIE_STATUS_REG) ? {27'h0, ~msgo_fifo_tready, 1'b0, wb_resp_pending, wb_req_pending, pcie_resp_pending} : (
|
||||
(rb_addr == RB_PCIE_RESP_DATA_REG) ? axi_in_resp_reg : (
|
||||
(rb_addr == RB_PCIE_DATA_REG) ? axi_in_data_reg : (
|
||||
(rb_addr == RB_PCIE_CTRL_REG) ? axi_in_ctrl_reg : 32'h0))));
|
||||
//------------------------------------------
|
||||
|
||||
//------------------------------------------
|
||||
// Output message handler
|
||||
//
|
||||
wire [63:0] msgo_fifo_tdata;
|
||||
wire axi_out_rd, axi_out_wr, axi_out_rr;
|
||||
|
||||
assign msgo_fifo_tdata = {axi_out_ctrl, axi_out_data};
|
||||
|
||||
axi_fifo_short #(.WIDTH(64)) wb_out_msg_fifo (
|
||||
.clk(clk), .reset(rst), .clear(1'b0),
|
||||
.i_tdata(msgo_fifo_tdata), .i_tvalid(axi_out_stb), .i_tready(msgo_fifo_tready),
|
||||
.o_tdata(msgo_tdata), .o_tvalid(msgo_tvalid), .o_tready(msgo_tready),
|
||||
.space(), .occupied());
|
||||
|
||||
ioport2_msg_decode axi_out_decoder (
|
||||
.message(msgo_fifo_tdata),
|
||||
.rd_response(axi_out_rr), .wr_request(axi_out_wr), .rd_request(axi_out_rd)
|
||||
);
|
||||
//------------------------------------------
|
||||
|
||||
//------------------------------------------
|
||||
// Input message handler
|
||||
//
|
||||
wire [63:0] msgi_fifo_tdata;
|
||||
wire axi_in_valid, axi_in_stb;
|
||||
|
||||
wire [31:0] axi_in_data, axi_in_ctrl;
|
||||
wire axi_in_rd, axi_in_wr, axi_in_rr;
|
||||
|
||||
axi_fifo_short #(.WIDTH(64)) wb_in_msg_fifo (
|
||||
.clk(clk), .reset(rst), .clear(1'b0),
|
||||
.i_tdata(msgi_tdata), .i_tvalid(msgi_tvalid), .i_tready(msgi_tready),
|
||||
.o_tdata(msgi_fifo_tdata), .o_tvalid(axi_in_valid), .o_tready(axi_in_stb),
|
||||
.space(), .occupied());
|
||||
|
||||
ioport2_msg_decode axi_in_decoder (
|
||||
.message(msgi_fifo_tdata),
|
||||
.rd_response(axi_in_rr), .wr_request(axi_in_wr), .rd_request(axi_in_rd),
|
||||
.data(axi_in_data), .control(axi_in_ctrl)
|
||||
);
|
||||
|
||||
assign axi_in_stb = axi_in_valid & (axi_in_rr | ((axi_in_wr | axi_in_rd) & ~(wb_req_pending | wb_resp_pending)));
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
axi_in_data_reg <= 32'h0;
|
||||
axi_in_ctrl_reg <= 32'h0;
|
||||
axi_in_resp_reg <= 32'h0;
|
||||
end else begin
|
||||
if (axi_in_stb & axi_in_rr) begin
|
||||
axi_in_resp_reg <= axi_in_data;
|
||||
end else if (axi_in_stb & (axi_in_wr | axi_in_rd)) begin
|
||||
axi_in_data_reg <= axi_in_data;
|
||||
axi_in_ctrl_reg <= axi_in_ctrl;
|
||||
end
|
||||
end
|
||||
end
|
||||
//------------------------------------------
|
||||
|
||||
//------------------------------------------
|
||||
// State handler
|
||||
//
|
||||
//wb_monitor_active
|
||||
reg [MONITOR_TIMEOUTW-1:0] wb_monitor_timeout;
|
||||
assign wb_monitor_active = (wb_monitor_timeout != {(MONITOR_TIMEOUTW){1'b0}});
|
||||
always @(posedge clk) begin
|
||||
if (rst)
|
||||
wb_monitor_timeout <= {(MONITOR_TIMEOUTW){1'b0}}; //Monitor disabled on rst
|
||||
else if (rb_stb && (rb_addr == RB_PCIE_STATUS_REG))
|
||||
wb_monitor_timeout <= {(MONITOR_TIMEOUTW){1'b1}}; //Reset counter when the ZPU queries the status reg
|
||||
else if (wb_monitor_active)
|
||||
wb_monitor_timeout <= wb_monitor_timeout - 1; //Decrement counter when idle
|
||||
end
|
||||
|
||||
//wb_req_pending
|
||||
always @(posedge clk) begin
|
||||
if (rst || (rb_stb && (rb_addr == RB_PCIE_CTRL_REG)))
|
||||
wb_req_pending <= 1'b0;
|
||||
else if (axi_in_stb & (axi_in_rd | axi_in_wr))
|
||||
wb_req_pending <= 1'b1;
|
||||
end
|
||||
|
||||
//wb_resp_pending
|
||||
always @(posedge clk) begin
|
||||
if (rst | (axi_out_stb & msgo_fifo_tready & axi_out_rr))
|
||||
wb_resp_pending <= 1'b0;
|
||||
else if (axi_in_stb & axi_in_rd)
|
||||
wb_resp_pending <= 1'b1;
|
||||
end
|
||||
|
||||
//pcie_resp_pending
|
||||
always @(posedge clk) begin
|
||||
if (rst | (axi_in_stb & axi_in_rr))
|
||||
pcie_resp_pending <= 1'b0;
|
||||
else if (axi_out_stb & msgo_fifo_tready & axi_out_rd)
|
||||
pcie_resp_pending <= 1'b1;
|
||||
end
|
||||
//------------------------------------------
|
||||
|
||||
|
||||
endmodule
|
||||
@@ -1,106 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Ettus Research LLC
|
||||
//
|
||||
|
||||
|
||||
module pcie_basic_regs #(
|
||||
parameter SIGNATURE = 32'h0,
|
||||
parameter CLK_FREQ = 32'h0
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input [63:0] regi_tdata,
|
||||
input regi_tvalid,
|
||||
output regi_tready,
|
||||
output [63:0] rego_tdata,
|
||||
output rego_tvalid,
|
||||
input rego_tready,
|
||||
|
||||
input [31:0] misc_status
|
||||
);
|
||||
localparam PCIE_FPGA_SIG_VAL = SIGNATURE;
|
||||
localparam PCIE_FPGA_COUNTER_FREQ = CLK_FREQ;
|
||||
|
||||
localparam PCIE_REG_ADDR_MASK = 20'h001FF;
|
||||
|
||||
localparam PCIE_FPGA_SIG_REG_ADDR = 20'h00000; //32-bit
|
||||
localparam PCIE_FPGA_COUNTER_LO_REG_ADDR = 20'h00004; //32-bit
|
||||
localparam PCIE_FPGA_COUNTER_HI_REG_ADDR = 20'h00008; //32-bit
|
||||
localparam PCIE_FPGA_COUNTER_FREQ_ADDR = 20'h0000C; //32-bit
|
||||
localparam PCIE_FPGA_SCRATCH0_ADDR = 20'h00010; //32-bit
|
||||
localparam PCIE_FPGA_SCRATCH1_ADDR = 20'h00014; //32-bit
|
||||
localparam PCIE_FPGA_MISC_STATUS_ADDR = 20'h00020; //32-bit
|
||||
localparam PCIE_FPGA_USR_SIG_REG_ADDR = 20'h00030; //128-bit
|
||||
|
||||
wire regi_wr, regi_rd;
|
||||
wire [19:0] regi_addr, regi_addr_local;
|
||||
wire [31:0] regi_payload;
|
||||
reg [31:0] rego_payload;
|
||||
|
||||
ioport2_msg_decode regi_decoder (
|
||||
.message(regi_tdata), .wr_request(regi_wr), .rd_request(regi_rd),
|
||||
.address(regi_addr), .data(regi_payload)
|
||||
);
|
||||
|
||||
ioport2_msg_encode rego_encoder (
|
||||
.rd_response(1'b1), .data(rego_payload), .message(rego_tdata)
|
||||
);
|
||||
|
||||
assign regi_tready = (regi_tvalid & regi_wr) | rego_tready;
|
||||
assign rego_tvalid = regi_tvalid & regi_rd;
|
||||
assign regi_addr_local = regi_addr & PCIE_REG_ADDR_MASK;
|
||||
|
||||
//Counter counting bus_clk cycles
|
||||
reg [63:0] bus_counter;
|
||||
always @(posedge clk) begin
|
||||
if (reset) bus_counter <= 64'h0;
|
||||
else bus_counter <= bus_counter + 1;
|
||||
end
|
||||
|
||||
//Scratch registers
|
||||
reg [63:0] scratch;
|
||||
always @(posedge clk) begin
|
||||
if (reset)
|
||||
scratch <= 64'h0;
|
||||
else if (regi_tvalid & regi_tready & regi_wr)
|
||||
if (regi_addr_local == PCIE_FPGA_SCRATCH0_ADDR)
|
||||
scratch[31:0] <= regi_payload;
|
||||
else if (regi_addr_local == PCIE_FPGA_SCRATCH1_ADDR)
|
||||
scratch[63:32] <= regi_payload;
|
||||
end
|
||||
|
||||
//User signature register
|
||||
reg [127:0] usr_signature;
|
||||
always @(posedge clk) begin
|
||||
if (reset)
|
||||
usr_signature <= 128'h0;
|
||||
else if (regi_tvalid & regi_tready & regi_wr)
|
||||
if (regi_addr_local == (PCIE_FPGA_USR_SIG_REG_ADDR + 20'h00000))
|
||||
usr_signature[31:0] <= regi_payload;
|
||||
else if (regi_addr_local == (PCIE_FPGA_USR_SIG_REG_ADDR + 20'h00004))
|
||||
usr_signature[63:32] <= regi_payload;
|
||||
else if (regi_addr_local == (PCIE_FPGA_USR_SIG_REG_ADDR + 20'h00008))
|
||||
usr_signature[95:64] <= regi_payload;
|
||||
else if (regi_addr_local == (PCIE_FPGA_USR_SIG_REG_ADDR + 20'h0000C))
|
||||
usr_signature[127:96] <= regi_payload;
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case (regi_addr_local)
|
||||
PCIE_FPGA_SIG_REG_ADDR: rego_payload = PCIE_FPGA_SIG_VAL;
|
||||
PCIE_FPGA_COUNTER_LO_REG_ADDR: rego_payload = bus_counter[31:0];
|
||||
PCIE_FPGA_COUNTER_HI_REG_ADDR: rego_payload = bus_counter[63:32];
|
||||
PCIE_FPGA_COUNTER_FREQ_ADDR: rego_payload = PCIE_FPGA_COUNTER_FREQ;
|
||||
PCIE_FPGA_SCRATCH0_ADDR: rego_payload = scratch[31:0];
|
||||
PCIE_FPGA_SCRATCH1_ADDR: rego_payload = scratch[63:32];
|
||||
PCIE_FPGA_MISC_STATUS_ADDR: rego_payload = misc_status;
|
||||
PCIE_FPGA_USR_SIG_REG_ADDR + 20'h00000: rego_payload = usr_signature[31:0];
|
||||
PCIE_FPGA_USR_SIG_REG_ADDR + 20'h00004: rego_payload = usr_signature[63:32];
|
||||
PCIE_FPGA_USR_SIG_REG_ADDR + 20'h00008: rego_payload = usr_signature[95:64];
|
||||
PCIE_FPGA_USR_SIG_REG_ADDR + 20'h0000C: rego_payload = usr_signature[127:96];
|
||||
default: rego_payload = 32'hFFFFFFFF;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -1,159 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Ettus Research LLC
|
||||
//
|
||||
|
||||
|
||||
`define BIT_WIDTH(N) (\
|
||||
N <= 2 ? 1 : \
|
||||
N <= 4 ? 2 : \
|
||||
N <= 8 ? 3 : \
|
||||
N <= 16 ? 4 : \
|
||||
N <= 32 ? 5 : \
|
||||
N <= 64 ? 6 : \
|
||||
N <= 128 ? 7 : \
|
||||
N <= 256 ? 8 : \
|
||||
N <= 512 ? 9 : \
|
||||
10)
|
||||
`define GET_REG_OFFSET(reg_addr, chan_idx) (((chan_idx * (1<<DMA_REG_GRP_W)) + reg_addr) + REG_BASE_ADDR)
|
||||
`define EXTRACT_CHAN_NUM(reg_addr) regi_addr[`BIT_WIDTH(NUM_STREAMS)+DMA_REG_GRP_W-1:DMA_REG_GRP_W]
|
||||
|
||||
module pcie_dma_ctrl #(
|
||||
parameter NUM_STREAMS = 4,
|
||||
parameter FRAME_SIZE_W = 16,
|
||||
parameter REG_BASE_ADDR = 20'h00000,
|
||||
parameter ENABLE_ROUTER = 0,
|
||||
parameter ROUTER_SID_W = 8,
|
||||
parameter ROUTER_DST_W = 2
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input [63:0] regi_tdata,
|
||||
input regi_tvalid,
|
||||
output regi_tready,
|
||||
output [63:0] rego_tdata,
|
||||
output rego_tvalid,
|
||||
input rego_tready,
|
||||
|
||||
output reg [NUM_STREAMS-1:0] set_enabled,
|
||||
output reg [NUM_STREAMS-1:0] set_clear,
|
||||
output [(NUM_STREAMS*FRAME_SIZE_W)-1:0] set_frame_size,
|
||||
output [(NUM_STREAMS*3)-1:0] swap_lanes,
|
||||
|
||||
input [NUM_STREAMS-1:0] packet_stb,
|
||||
input [NUM_STREAMS-1:0] sample_stb,
|
||||
input [NUM_STREAMS-1:0] stream_busy,
|
||||
input [NUM_STREAMS-1:0] stream_err,
|
||||
|
||||
input [ROUTER_SID_W-1:0] rtr_sid,
|
||||
output [ROUTER_DST_W-1:0] rtr_dst
|
||||
);
|
||||
|
||||
localparam DMA_REG_GRP_W = 4;
|
||||
localparam DMA_CTRL_STATUS_REG = 4'h0; //[RW] R: Stream Status, W: Stream Control
|
||||
localparam DMA_FSIZE_REG = 4'h4; //[RW] R: Frame Size, W: Frame Size
|
||||
localparam DMA_SAMP_CNT_REG = 4'h8; //[RW] R: Sample Count, W: Reset Count to 0
|
||||
localparam DMA_PKT_CNT_REG = 4'hC; //[RW] R: Packet Count, W: Reset Count to 0
|
||||
|
||||
localparam DEFAULT_FSIZE = 32;
|
||||
|
||||
//NOTE: Although this module supports these, the 8 and 16 bit modes will be disabled for efficiency
|
||||
localparam DMA_CTRL_BUF_SIZE_8 = 2'b00; // 8-bit wide SW buffer
|
||||
localparam DMA_CTRL_BUF_SIZE_16 = 2'b01; //16-bit wide SW buffer
|
||||
localparam DMA_CTRL_BUF_SIZE_32 = 2'b10; //32-bit wide SW buffer
|
||||
localparam DMA_CTRL_BUF_SIZE_64 = 2'b11; //64-bit wide SW buffer
|
||||
|
||||
wire regi_wr, regi_rd;
|
||||
wire [19:0] regi_addr;
|
||||
wire [31:0] regi_payload;
|
||||
wire [31:0] rego_payload;
|
||||
|
||||
ioport2_msg_decode regi_decoder (
|
||||
.message(regi_tdata), .wr_request(regi_wr), .rd_request(regi_rd),
|
||||
.address(regi_addr), .data(regi_payload)
|
||||
);
|
||||
|
||||
ioport2_msg_encode rego_encoder (
|
||||
.rd_response(1'b1), .data(rego_payload), .message(rego_tdata)
|
||||
);
|
||||
|
||||
reg [31:0] pkt_count_mem[0:NUM_STREAMS-1];
|
||||
reg [31:0] samp_count_mem[0:NUM_STREAMS-1];
|
||||
reg [FRAME_SIZE_W-1:0] frame_size_mem[0:NUM_STREAMS-1];
|
||||
reg [NUM_STREAMS-1:0] sw_buf_width_mem;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i<NUM_STREAMS; i=i+1) begin: dma_ctrl_logic_generator
|
||||
//Memory -> output translations
|
||||
assign set_frame_size[(FRAME_SIZE_W*(i+1))-1:(FRAME_SIZE_W*i)] = frame_size_mem[i];
|
||||
assign swap_lanes[(3*(i+1))-1:(3*i)] = { ~(sw_buf_width_mem[i]), 2'b00 }; //Optimized for only 2 modes
|
||||
|
||||
//Setting registers
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
frame_size_mem[i] <= DEFAULT_FSIZE;
|
||||
set_clear[i] <= 0;
|
||||
set_enabled[i] <= 0;
|
||||
sw_buf_width_mem[i] <= 1;
|
||||
end else if (regi_tready & regi_tvalid & regi_wr) begin
|
||||
if (regi_addr == `GET_REG_OFFSET(DMA_CTRL_STATUS_REG, i)) begin
|
||||
set_clear[i] <= regi_payload[0]; //DMA_CTRL_STATUS_REG[0] == Clear DMA queues
|
||||
set_enabled[i] <= regi_payload[1]; //DMA_CTRL_STATUS_REG[1] == Enable DMA channel
|
||||
sw_buf_width_mem[i] <= regi_payload[4]; //DMA_CTRL_STATUS_REG[5:4] == SW Buffer Size (See note above)
|
||||
end else if (regi_addr == `GET_REG_OFFSET(DMA_FSIZE_REG, i)) begin
|
||||
frame_size_mem[i] <= regi_payload[FRAME_SIZE_W-1:0]; //DMA_FSIZE_REG[14:0] == DMA Frame size
|
||||
end
|
||||
end else begin
|
||||
set_clear[i] <= 0; //set_clear should be "self-clearing"
|
||||
end
|
||||
end
|
||||
|
||||
//Packet counter
|
||||
always @(posedge clk) begin
|
||||
if (reset | (regi_tvalid && regi_wr && (regi_addr == `GET_REG_OFFSET(DMA_PKT_CNT_REG, i)))) begin
|
||||
pkt_count_mem[i] <= 0;
|
||||
end else if (packet_stb[i]) begin
|
||||
pkt_count_mem[i] <= pkt_count_mem[i] + 1;
|
||||
end
|
||||
end
|
||||
|
||||
//Sample counter
|
||||
always @(posedge clk) begin
|
||||
if (reset | (regi_tvalid && regi_wr && (regi_addr == `GET_REG_OFFSET(DMA_SAMP_CNT_REG, i)))) begin
|
||||
samp_count_mem[i] <= 0;
|
||||
end else if (sample_stb[i]) begin
|
||||
samp_count_mem[i] <= samp_count_mem[i] + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
//Readback
|
||||
assign rego_payload =
|
||||
(regi_addr[DMA_REG_GRP_W-1:0] == DMA_PKT_CNT_REG) ? pkt_count_mem[`EXTRACT_CHAN_NUM(regi_addr)] : (
|
||||
(regi_addr[DMA_REG_GRP_W-1:0] == DMA_SAMP_CNT_REG) ? samp_count_mem[`EXTRACT_CHAN_NUM(regi_addr)] : (
|
||||
(regi_addr[DMA_REG_GRP_W-1:0] == DMA_FSIZE_REG) ? frame_size_mem[`EXTRACT_CHAN_NUM(regi_addr)] : (
|
||||
(regi_addr[DMA_REG_GRP_W-1:0] == DMA_CTRL_STATUS_REG) ? {30'h0, stream_busy[`EXTRACT_CHAN_NUM(regi_addr)], stream_err[`EXTRACT_CHAN_NUM(regi_addr)]} : (
|
||||
32'hFFFFFFFF))));
|
||||
|
||||
assign rego_tvalid = regi_tvalid && regi_rd;
|
||||
assign regi_tready = rego_tready || (regi_tvalid && regi_wr);
|
||||
|
||||
//Optional router
|
||||
generate if (ENABLE_ROUTER == 1) begin
|
||||
pcie_pkt_route_specifier #(
|
||||
.BASE_ADDR((1<<ROUTER_SID_W) + REG_BASE_ADDR), .ADDR_MASK(20'hFFFFF^((1<<ROUTER_SID_W)-1)),
|
||||
.SID_WIDTH(ROUTER_SID_W), .DST_WIDTH(ROUTER_DST_W)
|
||||
) route_specifier (
|
||||
.clk(clk), .reset(reset),
|
||||
.regi_tdata(regi_tdata), .regi_tvalid(regi_tvalid), .regi_tready(),
|
||||
.local_sid(rtr_sid), .fifo_dst(rtr_dst)
|
||||
);
|
||||
end endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
`undef EXTRACT_CHAN_NUM
|
||||
`undef GET_REG_OFFSET
|
||||
`undef BIT_WIDTH
|
||||
@@ -1,89 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Ettus Research LLC
|
||||
//
|
||||
|
||||
|
||||
`timescale 500ps/1ps
|
||||
|
||||
module pcie_dma_ctrl_tb();
|
||||
reg clk = 0;
|
||||
reg reset = 1;
|
||||
|
||||
always #10 clk = ~clk;
|
||||
|
||||
initial begin
|
||||
#100 reset = 0;
|
||||
#200000;
|
||||
$finish;
|
||||
end
|
||||
|
||||
function [63:0] iop2_msg_write;
|
||||
input [19:0] address;
|
||||
input [31:0] data;
|
||||
input half_wd;
|
||||
begin
|
||||
// {rd_response, wr_request, rd_request, half_word, 8'h00, address, data};
|
||||
iop2_msg_write = {1'b0, 1'b1, 1'b0, half_wd, 8'h00, address, data};
|
||||
end
|
||||
endfunction // iop2_msg_write
|
||||
|
||||
function [63:0] iop2_msg_read;
|
||||
input [19:0] address;
|
||||
input half_wd;
|
||||
begin
|
||||
// {rd_response, wr_request, rd_request, half_word, 8'h00, address, data};
|
||||
iop2_msg_read = {1'b0, 1'b0, 1'b1, half_wd, 8'h00, address, 32'h0};
|
||||
end
|
||||
endfunction // iop2_msg_read
|
||||
|
||||
wire [3:0] clear;
|
||||
wire [63:0] frame_size;
|
||||
reg [3:0] pkt_stb = 0;
|
||||
reg [3:0] samp_stb = 0;
|
||||
reg [3:0] error = 0;
|
||||
reg [7:0] rtr_sid = 4;
|
||||
wire [3:0] rtr_dst;
|
||||
|
||||
reg [63:0] regi_tdata;
|
||||
reg regi_tvalid;
|
||||
wire regi_tready;
|
||||
wire [63:0] rego_tdata;
|
||||
wire rego_tvalid;
|
||||
reg rego_tready;
|
||||
reg [31:0] rego_payload;
|
||||
|
||||
always @(posedge clk)
|
||||
if (rego_tdata[63] & rego_tvalid & rego_tready)
|
||||
rego_payload <= rego_tdata[31:0];
|
||||
|
||||
initial begin
|
||||
regi_tvalid <= 0;
|
||||
rego_tready <= 0;
|
||||
while (reset) @(posedge clk);
|
||||
|
||||
rego_tready <= 1;
|
||||
@(posedge clk);
|
||||
|
||||
regi_tdata <= iop2_msg_write(20'h304, 32'hA, 0);
|
||||
regi_tvalid <= 1;
|
||||
@(posedge clk);
|
||||
while (~regi_tready) @(posedge clk);
|
||||
regi_tvalid <= 0;
|
||||
@(posedge clk);
|
||||
|
||||
end // initial begin
|
||||
|
||||
pcie_dma_ctrl #(
|
||||
.NUM_STREAMS(4), .FRAME_SIZE_W(16),
|
||||
.REG_BASE_ADDR(20'h00200), .ENABLE_ROUTER(1),
|
||||
.ROUTER_SID_W(8), .ROUTER_DST_W(4)
|
||||
) dut (
|
||||
.clk(clk), .reset(reset),
|
||||
.regi_tdata(regi_tdata), .regi_tvalid(regi_tvalid), .regi_tready(regi_tready),
|
||||
.rego_tdata(rego_tdata), .rego_tvalid(rego_tvalid), .rego_tready(rego_tready),
|
||||
.set_clear(clear), .set_frame_size(frame_size), .sample_stb(samp_stb), .packet_stb(pkt_stb),
|
||||
.stream_err(error), .rtr_sid(rtr_sid), .rtr_dst(rtr_dst)
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
@@ -1,131 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Ettus Research LLC
|
||||
//
|
||||
|
||||
|
||||
module pcie_iop2_msg_arbiter #(
|
||||
parameter E0_ADDR = 20'h0,
|
||||
parameter E0_MASK = 20'h0,
|
||||
parameter E1_ADDR = 20'h0,
|
||||
parameter E1_MASK = 20'h0,
|
||||
parameter E2_ADDR = 20'h0,
|
||||
parameter E2_MASK = 20'h0,
|
||||
parameter E3_ADDR = 20'h0,
|
||||
parameter E3_MASK = 20'h0
|
||||
) (
|
||||
//Clocks and resets
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input [63:0] regi_tdata,
|
||||
input regi_tvalid,
|
||||
output regi_tready,
|
||||
output [63:0] rego_tdata,
|
||||
output rego_tvalid,
|
||||
input rego_tready,
|
||||
|
||||
output [63:0] e0_regi_tdata,
|
||||
output e0_regi_tvalid,
|
||||
input e0_regi_tready,
|
||||
input [63:0] e0_rego_tdata,
|
||||
input e0_rego_tvalid,
|
||||
output e0_rego_tready,
|
||||
|
||||
output [63:0] e1_regi_tdata,
|
||||
output e1_regi_tvalid,
|
||||
input e1_regi_tready,
|
||||
input [63:0] e1_rego_tdata,
|
||||
input e1_rego_tvalid,
|
||||
output e1_rego_tready,
|
||||
|
||||
output [63:0] e2_regi_tdata,
|
||||
output e2_regi_tvalid,
|
||||
input e2_regi_tready,
|
||||
input [63:0] e2_rego_tdata,
|
||||
input e2_rego_tvalid,
|
||||
output e2_rego_tready,
|
||||
|
||||
output [63:0] e3_regi_tdata,
|
||||
output e3_regi_tvalid,
|
||||
input e3_regi_tready,
|
||||
input [63:0] e3_rego_tdata,
|
||||
input e3_rego_tvalid,
|
||||
output e3_rego_tready
|
||||
);
|
||||
|
||||
//*******************************************************************************
|
||||
// PCIe output message arbiter
|
||||
//
|
||||
axi_mux4 #(.PRIO(0), .WIDTH(64), .BUFFER(0)) rego_arbiter_mux (
|
||||
.clk(clk), .reset(reset), .clear(1'b0),
|
||||
.i0_tdata(e0_rego_tdata), .i0_tlast(e0_rego_tvalid), .i0_tvalid(e0_rego_tvalid), .i0_tready(e0_rego_tready),
|
||||
.i1_tdata(e1_rego_tdata), .i1_tlast(e1_rego_tvalid), .i1_tvalid(e1_rego_tvalid), .i1_tready(e1_rego_tready),
|
||||
.i2_tdata(e2_rego_tdata), .i2_tlast(e2_rego_tvalid), .i2_tvalid(e2_rego_tvalid), .i2_tready(e2_rego_tready),
|
||||
.i3_tdata(e3_rego_tdata), .i3_tlast(e3_rego_tvalid), .i3_tvalid(e3_rego_tvalid), .i3_tready(e3_rego_tready),
|
||||
.o_tdata(rego_tdata), .o_tlast(), .o_tvalid(rego_tvalid), .o_tready(rego_tready)
|
||||
);
|
||||
//
|
||||
//*******************************************************************************
|
||||
|
||||
//*******************************************************************************
|
||||
// PCIe input message arbiter
|
||||
//
|
||||
wire [63:0] regi_msg;
|
||||
wire regi_rc;
|
||||
wire [19:0] regi_addr;
|
||||
wire e0_rego_rd, e1_rego_rd, e2_rego_rd, e3_rego_rd;
|
||||
|
||||
ioport2_msg_decode e0_rego_decoder (.message(e0_rego_tdata), .rd_request(e0_rego_rd));
|
||||
ioport2_msg_decode e1_rego_decoder (.message(e1_rego_tdata), .rd_request(e1_rego_rd));
|
||||
ioport2_msg_decode e2_rego_decoder (.message(e2_rego_tdata), .rd_request(e2_rego_rd));
|
||||
ioport2_msg_decode e3_rego_decoder (.message(e3_rego_tdata), .rd_request(e3_rego_rd));
|
||||
|
||||
localparam DEST_E0 = 2'd0;
|
||||
localparam DEST_E1 = 2'd1;
|
||||
localparam DEST_E2 = 2'd2;
|
||||
localparam DEST_E3 = 2'd3;
|
||||
|
||||
reg [1:0] regi_resp_dest;
|
||||
wire [1:0] regi_req_dest, regi_dest;
|
||||
|
||||
assign regi_req_dest =
|
||||
((regi_addr & E0_MASK) == E0_ADDR) ? DEST_E0 : (
|
||||
((regi_addr & E1_MASK) == E1_ADDR) ? DEST_E1 : (
|
||||
((regi_addr & E2_MASK) == E2_ADDR) ? DEST_E2 : (
|
||||
((regi_addr & E3_MASK) == E3_ADDR) ? DEST_E3 : (
|
||||
DEST_E0))));
|
||||
|
||||
//A response must be routed to the port with the last read request
|
||||
always @(posedge clk) begin
|
||||
if (reset)
|
||||
regi_resp_dest <= DEST_E0; //Default 0
|
||||
else if (e0_rego_tvalid & e0_rego_tready & e0_rego_rd)
|
||||
regi_resp_dest <= DEST_E0;
|
||||
else if (e1_rego_tvalid & e1_rego_tready & e1_rego_rd)
|
||||
regi_resp_dest <= DEST_E1;
|
||||
else if (e2_rego_tvalid & e2_rego_tready & e2_rego_rd)
|
||||
regi_resp_dest <= DEST_E2;
|
||||
else if (e3_rego_tvalid & e3_rego_tready & e3_rego_rd)
|
||||
regi_resp_dest <= DEST_E3;
|
||||
end
|
||||
|
||||
ioport2_msg_decode regi_decoder (
|
||||
.message(regi_msg), .rd_response(regi_rc), .address(regi_addr));
|
||||
|
||||
//If request, get destination from msg.
|
||||
//If response, get destination from last read location.
|
||||
assign regi_dest = regi_rc ? regi_resp_dest : regi_req_dest;
|
||||
|
||||
axi_demux4 #(.ACTIVE_CHAN(4'b1111), .WIDTH(64), .BUFFER(0)) regi_arbiter_demux (
|
||||
.clk(clk), .reset(reset), .clear(1'b0),
|
||||
.header(regi_msg), .dest(regi_dest),
|
||||
.i_tdata(regi_tdata), .i_tlast(regi_tvalid), .i_tvalid(regi_tvalid), .i_tready(regi_tready),
|
||||
.o0_tdata(e0_regi_tdata), .o0_tlast(), .o0_tvalid(e0_regi_tvalid), .o0_tready(e0_regi_tready),
|
||||
.o1_tdata(e1_regi_tdata), .o1_tlast(), .o1_tvalid(e1_regi_tvalid), .o1_tready(e1_regi_tready),
|
||||
.o2_tdata(e2_regi_tdata), .o2_tlast(), .o2_tvalid(e2_regi_tvalid), .o2_tready(e2_regi_tready),
|
||||
.o3_tdata(e3_regi_tdata), .o3_tlast(), .o3_tvalid(e3_regi_tvalid), .o3_tready(e3_regi_tready)
|
||||
);
|
||||
//
|
||||
//*******************************************************************************
|
||||
|
||||
endmodule
|
||||
@@ -1,107 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Ettus Research LLC
|
||||
//
|
||||
|
||||
|
||||
`timescale 500ps/1ps
|
||||
|
||||
module pcie_iop2_msg_arbiter_tb();
|
||||
reg clk = 0;
|
||||
reg reset = 1;
|
||||
|
||||
always #10 clk = ~clk;
|
||||
|
||||
initial begin
|
||||
#100 reset = 0;
|
||||
#200000;
|
||||
$finish;
|
||||
end
|
||||
|
||||
function [63:0] iop2_msg_write;
|
||||
input [19:0] address;
|
||||
input [31:0] data;
|
||||
input half_wd;
|
||||
begin
|
||||
// {rd_response, wr_request, rd_request, half_word, 8'h00, address, data};
|
||||
iop2_msg_write = {1'b0, 1'b1, 1'b0, half_wd, 8'h00, address, data};
|
||||
end
|
||||
endfunction // iop2_msg_write
|
||||
|
||||
function [63:0] iop2_msg_read;
|
||||
input [19:0] address;
|
||||
input half_wd;
|
||||
begin
|
||||
// {rd_response, wr_request, rd_request, half_word, 8'h00, address, data};
|
||||
iop2_msg_read = {1'b0, 1'b0, 1'b1, half_wd, 8'h00, address, 32'h0};
|
||||
end
|
||||
endfunction // iop2_msg_read
|
||||
|
||||
reg [63:0] msgi_tdata;
|
||||
wire [63:0] msgo_tdata;
|
||||
wire msgo_tvalid, msgi_tready;
|
||||
reg msgo_tready, msgi_tvalid;
|
||||
|
||||
wire [63:0] basic_regi_tdata, zpu_regi_tdata;
|
||||
wire basic_regi_tvalid, zpu_regi_tvalid;
|
||||
reg basic_regi_tready, zpu_regi_tready;
|
||||
reg [63:0] basic_rego_tdata, zpu_rego_tdata;
|
||||
reg basic_rego_tvalid, zpu_rego_tvalid;
|
||||
wire basic_rego_tready, zpu_rego_tready;
|
||||
|
||||
initial begin
|
||||
//@TODO: Make this a self-checking TB
|
||||
while (reset) @(posedge clk);
|
||||
|
||||
msgo_tready <= 1;
|
||||
basic_regi_tready <= 1;
|
||||
@(posedge clk);
|
||||
|
||||
|
||||
msgi_tdata <= iop2_msg_write(20'h0, 32'hDEAD, 0);
|
||||
msgi_tvalid <= 1;
|
||||
while (~msgi_tready) @(posedge clk);
|
||||
msgi_tvalid <= 0;
|
||||
@(posedge clk);
|
||||
|
||||
|
||||
msgi_tdata <= iop2_msg_read(20'h00000, 0);
|
||||
msgi_tvalid <= 1;
|
||||
while (~msgi_tready) @(posedge clk);
|
||||
msgi_tvalid <= 0;
|
||||
@(posedge clk);
|
||||
|
||||
zpu_rego_tdata <= {1, 31'h0, 32'h12345678};
|
||||
zpu_rego_tvalid <= 1;
|
||||
while (~zpu_rego_tready) @(posedge clk);
|
||||
zpu_rego_tvalid <= 0;
|
||||
|
||||
|
||||
|
||||
end // initial begin
|
||||
|
||||
pcie_iop2_msg_arbiter #(
|
||||
.E0_ADDR(20'h00000), .E0_MASK(20'hFFF00), //0x00000 - 0x000FF: Basic PCIe registers
|
||||
.E1_ADDR(20'h00100), .E1_MASK(20'hFFF00), //0x00100 - 0x001FF: PCIe router registers
|
||||
.E2_ADDR(20'h00200), .E2_MASK(20'hFFE00), //0x00200 - 0x003FF: DMA stream registers
|
||||
.E3_ADDR(20'h40000), .E3_MASK(20'hC0000) //0x40000 - 0x7FFFF: Client address space
|
||||
) iop2_msg_arbiter (
|
||||
.clk(clk), .reset(reset),
|
||||
//Master
|
||||
.regi_tdata(msgi_tdata), .regi_tvalid(msgi_tvalid), .regi_tready(msgi_tready),
|
||||
.rego_tdata(msgo_tdata), .rego_tvalid(msgo_tvalid), .rego_tready(msgo_tready),
|
||||
//Endpoint 0
|
||||
.e0_regi_tdata(basic_regi_tdata), .e0_regi_tvalid(basic_regi_tvalid), .e0_regi_tready(basic_regi_tready),
|
||||
.e0_rego_tdata(basic_rego_tdata), .e0_rego_tvalid(basic_rego_tvalid), .e0_rego_tready(basic_rego_tready),
|
||||
//Endpoint 1
|
||||
.e1_regi_tdata(), .e1_regi_tvalid(), .e1_regi_tready(1'b1),
|
||||
.e1_rego_tdata(64'h0), .e1_rego_tvalid(1'b0), .e1_rego_tready(),
|
||||
//Endpoint 2
|
||||
.e2_regi_tdata(), .e2_regi_tvalid(), .e2_regi_tready(1'b1),
|
||||
.e2_rego_tdata(64'h0), .e2_rego_tvalid(1'b0), .e2_rego_tready(),
|
||||
//Endpoint 3
|
||||
.e3_regi_tdata(zpu_regi_tdata), .e3_regi_tvalid(zpu_regi_tvalid), .e3_regi_tready(zpu_regi_tready),
|
||||
.e3_rego_tdata(zpu_rego_tdata), .e3_rego_tvalid(zpu_rego_tvalid), .e3_rego_tready(zpu_rego_tready)
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
@@ -1,26 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Ettus Research LLC
|
||||
//
|
||||
|
||||
|
||||
module pcie_lossy_samp_gate
|
||||
(
|
||||
input [63:0] i_tdata,
|
||||
input i_tvalid,
|
||||
output i_tready,
|
||||
|
||||
output [63:0] o_tdata,
|
||||
output o_tvalid,
|
||||
input o_tready,
|
||||
|
||||
input drop,
|
||||
output dropping
|
||||
);
|
||||
|
||||
assign o_tdata = i_tdata;
|
||||
assign o_tvalid = i_tvalid & ~drop;
|
||||
assign i_tready = o_tready | drop;
|
||||
|
||||
assign dropping = drop & i_tvalid;
|
||||
|
||||
endmodule // pcie_lossy_samp_gate
|
||||
@@ -1,43 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Ettus Research LLC
|
||||
//
|
||||
|
||||
|
||||
module pcie_pkt_route_specifier #(
|
||||
parameter BASE_ADDR = 20'h0,
|
||||
parameter ADDR_MASK = 20'hFFF00,
|
||||
parameter SID_WIDTH = 8,
|
||||
parameter DST_WIDTH = 4
|
||||
) (
|
||||
input clk,
|
||||
input reset,
|
||||
|
||||
input [63:0] regi_tdata,
|
||||
input regi_tvalid,
|
||||
output regi_tready,
|
||||
|
||||
input [SID_WIDTH-1:0] local_sid,
|
||||
output [DST_WIDTH-1:0] fifo_dst
|
||||
);
|
||||
// Routing table
|
||||
reg [DST_WIDTH-1:0] routing_table[0:(1<<SID_WIDTH)-1];
|
||||
assign fifo_dst = routing_table[local_sid];
|
||||
|
||||
wire reg_wr;
|
||||
wire [19:0] reg_addr;
|
||||
wire [31:0] reg_data;
|
||||
|
||||
// Routing table configuration
|
||||
ioport2_msg_decode config_message_decoder (
|
||||
.message(regi_tdata), .wr_request(reg_wr), .rd_request(reg_rd), .address(reg_addr), .data(reg_data)
|
||||
);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (regi_tvalid && regi_tready && reg_wr && ((reg_addr & ADDR_MASK) == BASE_ADDR)) begin
|
||||
routing_table[reg_data[SID_WIDTH+15:16]] <= reg_data[DST_WIDTH-1:0];
|
||||
end
|
||||
end
|
||||
|
||||
assign regi_tready = 1;
|
||||
|
||||
endmodule
|
||||
@@ -1,126 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Ettus Research LLC
|
||||
//
|
||||
|
||||
|
||||
module pcie_wb_reg_core #(
|
||||
parameter WB_ADDRW = 16,
|
||||
parameter WB_DATAW = 32
|
||||
)(
|
||||
input clk,
|
||||
input rst,
|
||||
|
||||
input wb_stb_i,
|
||||
input wb_we_i,
|
||||
input [WB_ADDRW-1:0] wb_adr_i,
|
||||
input [WB_DATAW-1:0] wb_dat_i,
|
||||
output wb_ack_o,
|
||||
output [WB_DATAW-1:0] wb_dat_o,
|
||||
|
||||
input [63:0] msgi_tdata,
|
||||
input msgi_tvalid,
|
||||
output msgi_tready,
|
||||
|
||||
output [63:0] msgo_tdata,
|
||||
output msgo_tvalid,
|
||||
input msgo_tready,
|
||||
|
||||
output [31:0] debug
|
||||
);
|
||||
// Parameters
|
||||
localparam PCIE_REGPORT_ADDR_MASK = 20'h0FFFF;
|
||||
localparam PCIE_REGPORT_DATA_ADDR = 20'h70000;
|
||||
localparam PCIE_REGPORT_READ_ADDR = 20'h60000;
|
||||
localparam PCIE_REGPORT_STATUS_ADDR = 20'h60000;
|
||||
|
||||
//------------------------------------------
|
||||
// WB AXI interface
|
||||
//
|
||||
wire [63:0] wb_msgi_tdata, wb_msgo_tdata;
|
||||
wire wb_msgi_tvalid, wb_msgi_tready, wb_msgo_tvalid, wb_msgo_tready;
|
||||
wire wb_monitor_active, wb_req_pending, wb_resp_pending;
|
||||
|
||||
pcie_axi_wb_conv #( .WB_ADDRW(WB_ADDRW), .WB_DATAW(WB_DATAW) ) axi_wb_translator (
|
||||
.clk(clk), .rst(rst),
|
||||
.wb_stb_i(wb_stb_i), .wb_we_i(wb_we_i), .wb_adr_i(wb_adr_i),
|
||||
.wb_dat_i(wb_dat_i), .wb_ack_o(wb_ack_o), .wb_dat_o(wb_dat_o),
|
||||
.msgi_tdata(wb_msgo_tdata), .msgi_tvalid(wb_msgo_tvalid), .msgi_tready(wb_msgo_tready),
|
||||
.msgo_tdata(wb_msgi_tdata), .msgo_tvalid(wb_msgi_tvalid), .msgo_tready(wb_msgi_tready),
|
||||
.wb_monitor_active(wb_monitor_active), .wb_req_pending(wb_req_pending), .wb_resp_pending(wb_resp_pending)
|
||||
);
|
||||
//------------------------------------------
|
||||
|
||||
//------------------------------------------
|
||||
// PCIe In -> WB Out
|
||||
//
|
||||
wire pcie_in_wr, pcie_in_rd, wb_out_wr, wb_out_rd;
|
||||
wire pcie2wb_rr, pcie2wb_hword;
|
||||
wire pcie_in_status_read, pcie_in_data_read;
|
||||
wire [19:0] pcie_in_addr;
|
||||
wire [31:0] pcie2wb_payload;
|
||||
|
||||
ioport2_msg_decode pcie_in_decoder (
|
||||
.message(msgi_tdata),
|
||||
.rd_response(pcie2wb_rr), .wr_request(pcie_in_wr), .rd_request(pcie_in_rd),
|
||||
.half_word(pcie2wb_hword), .address(pcie_in_addr), .data(pcie2wb_payload)
|
||||
);
|
||||
|
||||
ioport2_msg_encode wb_out_decoder (
|
||||
.rd_response(pcie2wb_rr), .wr_request(wb_out_wr), .rd_request(wb_out_rd),
|
||||
.half_word(pcie2wb_hword), .address(pcie_in_addr & PCIE_REGPORT_ADDR_MASK), .data(pcie2wb_payload),
|
||||
.message(wb_msgo_tdata)
|
||||
);
|
||||
|
||||
assign wb_out_wr = pcie_in_wr && ((pcie_in_addr & ~PCIE_REGPORT_ADDR_MASK) == PCIE_REGPORT_DATA_ADDR);
|
||||
assign wb_out_rd = pcie_in_wr && ((pcie_in_addr & ~PCIE_REGPORT_ADDR_MASK) == PCIE_REGPORT_READ_ADDR);
|
||||
assign wb_msgo_tvalid = msgi_tvalid & (wb_out_wr | wb_out_rd | pcie2wb_rr);
|
||||
assign msgi_tready = pcie_out_auto_resp_valid ? pcie_out_auto_resp_ready : wb_msgo_tready;
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
//------------------------------------------
|
||||
// WB In -> PCIe Out
|
||||
//
|
||||
assign pcie_in_status_read = pcie_in_rd && ((pcie_in_addr & ~PCIE_REGPORT_ADDR_MASK) == PCIE_REGPORT_STATUS_ADDR);
|
||||
assign pcie_in_data_read = pcie_in_rd && ((pcie_in_addr & ~PCIE_REGPORT_ADDR_MASK) == PCIE_REGPORT_DATA_ADDR);
|
||||
|
||||
reg [31:0] wb_in_resp_payload_reg;
|
||||
|
||||
wire wb_in_rr, wb_msgi_tready_int;
|
||||
wire [63:0] pcie_out_auto_resp_data;
|
||||
wire pcie_out_auto_resp_valid, pcie_out_auto_resp_ready;
|
||||
wire [31:0] wb_in_resp_payload;
|
||||
|
||||
ioport2_msg_decode wb_in_decoder (
|
||||
.message(wb_msgi_tdata), .rd_response(wb_in_rr), .data(wb_in_resp_payload)
|
||||
);
|
||||
|
||||
assign pcie_out_auto_resp_valid = (msgi_tvalid & (pcie_in_status_read | pcie_in_data_read));
|
||||
|
||||
ioport2_msg_encode auto_response_encoder (
|
||||
.rd_response(1'b1),
|
||||
.data(pcie_in_data_read ? wb_in_resp_payload_reg : {~wb_monitor_active, 30'h0, (wb_req_pending | wb_resp_pending)}),
|
||||
.message(pcie_out_auto_resp_data)
|
||||
);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst)
|
||||
wb_in_resp_payload_reg <= 32'h0;
|
||||
else if (wb_msgi_tvalid & wb_msgi_tready & wb_in_rr)
|
||||
wb_in_resp_payload_reg <= wb_in_resp_payload;
|
||||
end
|
||||
|
||||
axi_mux4 #(.PRIO(0), .WIDTH(64), .BUFFER(1)) msgo_arbiter_mux (
|
||||
.clk(clk), .reset(rst), .clear(1'b0),
|
||||
.i0_tdata(wb_msgi_tdata), .i0_tlast(1'b1), .i0_tvalid(wb_msgi_tvalid & ~wb_in_rr), .i0_tready(wb_msgi_tready_int),
|
||||
.i1_tdata(pcie_out_auto_resp_data), .i1_tlast(1'b1), .i1_tvalid(pcie_out_auto_resp_valid), .i1_tready(pcie_out_auto_resp_ready),
|
||||
.i2_tdata(0), .i2_tlast(1'b0), .i2_tvalid(1'b0), .i2_tready(),
|
||||
.i3_tdata(0), .i3_tlast(1'b0), .i3_tvalid(1'b0), .i3_tready(),
|
||||
.o_tdata(msgo_tdata), .o_tlast(), .o_tvalid(msgo_tvalid), .o_tready(msgo_tready)
|
||||
);
|
||||
|
||||
assign wb_msgi_tready = wb_msgi_tready_int | (wb_msgi_tvalid & wb_in_rr);
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
endmodule
|
||||
@@ -1,240 +0,0 @@
|
||||
//
|
||||
// Copyright 2013 Ettus Research LLC
|
||||
//
|
||||
|
||||
|
||||
`timescale 500ps/1ps
|
||||
`define CHECK_VALUE(val, expected, report) \
|
||||
if (val == expected) \
|
||||
$display("%s...Passed",report); \
|
||||
else \
|
||||
$display("%s...FAILED!!! (Val=0x%x, Exp=0x%x)",report,val,expected); \
|
||||
|
||||
module pcie_wb_reg_core_tb();
|
||||
reg clk = 0, reset = 1;
|
||||
reg wb_stb_i = 0;
|
||||
reg wb_we_i = 0;
|
||||
reg [15:0] wb_adr_i = 0;
|
||||
reg [31:0] wb_dat_i = 0;
|
||||
wire wb_ack_o;
|
||||
wire [31:0] wb_dat_o;
|
||||
|
||||
wire [63:0] msgo_data;
|
||||
wire msgo_valid;
|
||||
reg msgo_ready = 0;
|
||||
reg [63:0] msgi_data = 0;
|
||||
reg msgi_valid = 0;
|
||||
wire msgi_ready;
|
||||
|
||||
reg [31:0] msgo_payload = 32'h0;
|
||||
reg [31:0] msgo_ctrl = 32'h0;
|
||||
|
||||
reg [31:0] it;
|
||||
|
||||
always #10 clk = ~clk;
|
||||
|
||||
initial begin
|
||||
#100 reset = 0;
|
||||
#200000;
|
||||
$finish;
|
||||
end
|
||||
|
||||
localparam READ = 3'b001;
|
||||
localparam WRITE = 3'b010;
|
||||
localparam RESPONSE = 3'b100;
|
||||
|
||||
task pcie_send;
|
||||
input [2:0] op;
|
||||
input [19:0] address;
|
||||
input [31:0] data;
|
||||
begin
|
||||
//{rd_resp, wr_request, rd_request, half_word, 8'h00, address, data};
|
||||
msgi_data <= {op, 1'b0, 8'h00, address, data};
|
||||
msgi_valid <= 1'b1;
|
||||
|
||||
@(posedge clk);
|
||||
while (~msgi_ready) @(posedge clk);
|
||||
|
||||
msgi_valid <= 1'b0;
|
||||
@(posedge clk);
|
||||
end
|
||||
endtask // pcie_send
|
||||
|
||||
task pcie_recv;
|
||||
input [2:0] op;
|
||||
input [19:0] address;
|
||||
input [31:0] data;
|
||||
begin
|
||||
while (~msgo_valid) @(posedge clk);
|
||||
|
||||
msgo_ready <= 1'b1;
|
||||
@(posedge clk);
|
||||
|
||||
if (msgo_data[63] == op[2] || (msgo_data[62:61] == op[1:0] && msgo_data[51:32] == address))
|
||||
msgo_payload <= msgo_data[31:0];
|
||||
msgo_ctrl <= msgo_data[63:32];
|
||||
|
||||
msgo_ready <= 1'b0;
|
||||
@(posedge clk);
|
||||
end
|
||||
endtask // pcie_recv
|
||||
|
||||
task wb_send;
|
||||
input [2:0] op;
|
||||
input [15:0] address;
|
||||
input [31:0] data;
|
||||
begin
|
||||
wb_adr_i <= address;
|
||||
wb_dat_i <= data;
|
||||
wb_we_i <= op[1];
|
||||
wb_stb_i <= 1'b1;
|
||||
|
||||
@(posedge clk);
|
||||
while (~wb_ack_o) @(posedge clk);
|
||||
|
||||
wb_stb_i <= 1'b0;
|
||||
end
|
||||
endtask // pcie_send
|
||||
|
||||
|
||||
initial begin
|
||||
msgo_ready <= 1'b0;
|
||||
msgi_valid <= 1'b0;
|
||||
while (reset) @(posedge clk);
|
||||
@(posedge clk);
|
||||
|
||||
$display("\n[TEST] ZPU Read from PCIe");
|
||||
pcie_send(WRITE, 20'h6a000, 32'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe readback before initiating read request");
|
||||
pcie_send(READ, 20'h6a000, 32'h0);
|
||||
pcie_recv(RESPONSE, 20'h0, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status after initiating read");
|
||||
pcie_send(READ, 20'h6a000, 32'h0);
|
||||
pcie_recv(RESPONSE, 20'h0, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status after initiating second read");
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h6, "Verify WB status after PCIe read request");
|
||||
wb_send(READ, 16'h4, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h2000a000, "Verify WB control value after PCIe read request");
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h4, "Verify WB status value after consuming PCIe read request");
|
||||
pcie_send(READ, 20'h6a000, 32'h0);
|
||||
pcie_recv(RESPONSE, 20'h0, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status after WB consumes request only");
|
||||
wb_send(WRITE, 16'h0, 32'hDEADBEEF);
|
||||
wb_send(WRITE, 16'h4, 32'h80000000);
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after responding to PCIe read request");
|
||||
pcie_send(READ, 20'h6a000, 32'h0);
|
||||
pcie_recv(RESPONSE, 20'h0, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status after WB responds to read request");
|
||||
pcie_send(READ, 20'h7a000, 32'h0);
|
||||
pcie_recv(RESPONSE, 20'h0, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'hdeadbeef, "Verify PCIe read data");
|
||||
|
||||
$display("\n[TEST] ZPU Write from PCIe");
|
||||
pcie_send(WRITE, 20'h7b000, 32'h12345678);
|
||||
pcie_send(READ, 20'h7a000, 32'h0);
|
||||
pcie_recv(RESPONSE, 20'h0, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'hdeadbeef, "Verify that PCIe read data is still intact after write");
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h2, "Verify WB status value after PCIe write request");
|
||||
wb_send(READ, 16'h0, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h12345678, "Verify WB data value after PCIe read request");
|
||||
wb_send(READ, 16'h4, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h4000b000, "Verify WB control value after PCIe read request");
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after consuming PCIe write request");
|
||||
pcie_send(READ, 20'h6a000, 32'h0);
|
||||
pcie_recv(RESPONSE, 20'h0, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status after WB consumes request");
|
||||
|
||||
$display("\n[TEST] Chinch Write from ZPU");
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value before initiating write request");
|
||||
wb_send(WRITE, 16'h0, 32'h00beef00);
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after writing just the data reg");
|
||||
wb_send(WRITE, 16'h4, 32'h40000200);
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after initiating write");
|
||||
pcie_recv(WRITE, 20'h200, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'h00beef00, "Verify received PCIe data");
|
||||
`CHECK_VALUE(msgo_ctrl, 32'h40000200, "Verify received PCIe control");
|
||||
wb_send(WRITE, 16'h0, 32'h00feeb00);
|
||||
wb_send(WRITE, 16'h4, 32'h400002fc);
|
||||
pcie_recv(WRITE, 20'h200, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'h00feeb00, "Verify second received PCIe data");
|
||||
`CHECK_VALUE(msgo_ctrl, 32'h400002fc, "Verify second received PCIe control");
|
||||
|
||||
$display("\n[TEST] Chinch Read from ZPU");
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value before initiating read request");
|
||||
wb_send(WRITE, 16'h0, 32'hffffffff);
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after writing just the data reg");
|
||||
wb_send(WRITE, 16'h4, 32'h20000400);
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h1, "Verify WB status value after initiating read request");
|
||||
pcie_recv(READ, 20'h400, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'hffffffff, "Verify received PCIe data");
|
||||
`CHECK_VALUE(msgo_ctrl, 32'h20000400, "Verify received PCIe control");
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h1, "Verify WB status value before PCIe responds");
|
||||
pcie_send(RESPONSE, 20'h000, 32'hace06666);
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after PCIe responds");
|
||||
wb_send(READ, 16'h8, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'hace06666, "Verify WB read value after PCIe responds");
|
||||
|
||||
$display("\n[TEST] WB Outbound flood");
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status before request flood");
|
||||
for (it = 0; it < 64; it = it + 1) begin
|
||||
wb_send(WRITE, 16'h4, 32'h20000400);
|
||||
end
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h11, "Verify WB status after request flood");
|
||||
for (it = 0; it < 64; it = it + 1) begin
|
||||
pcie_recv(READ, 20'h400, 20'h0);
|
||||
end
|
||||
wb_send(READ, 16'hC, 32'h0);
|
||||
`CHECK_VALUE(wb_dat_o, 32'h1, "Verify WB status after consuming requests");
|
||||
|
||||
$display("\n[TEST] PCIe Transaction Status");
|
||||
pcie_send(READ, 20'h6a000, 32'h0);
|
||||
pcie_recv(RESPONSE, 20'h0, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status before multiple reads");
|
||||
pcie_send(WRITE, 20'h6a000, 32'h0);
|
||||
pcie_send(WRITE, 20'h6a000, 32'h0);
|
||||
pcie_send(WRITE, 20'h6a000, 32'h0);
|
||||
pcie_send(READ, 20'h6a000, 32'h0);
|
||||
pcie_recv(RESPONSE, 20'h0, 20'h0);
|
||||
pcie_send(READ, 20'h6a000, 32'h0);
|
||||
pcie_recv(RESPONSE, 20'h0, 20'h0);
|
||||
pcie_send(READ, 20'h6a000, 32'h0);
|
||||
pcie_recv(RESPONSE, 20'h0, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status before multiple read requests and status queries");
|
||||
wb_send(READ, 16'h4, 32'h0);
|
||||
wb_send(WRITE, 16'h0, 32'hDEADBEEF);
|
||||
wb_send(WRITE, 16'h4, 32'h80000000);
|
||||
pcie_send(READ, 20'h6a000, 32'h0);
|
||||
pcie_recv(RESPONSE, 20'h0, 20'h0);
|
||||
`CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status after response");
|
||||
|
||||
$display("\n[DONE]");
|
||||
|
||||
|
||||
end // initial begin
|
||||
|
||||
pcie_wb_reg_core #(.WB_ADDRW(16), .WB_DATAW(32)) dut (
|
||||
.clk(clk), .rst(reset),
|
||||
.wb_stb_i(wb_stb_i), .wb_we_i(wb_we_i), .wb_adr_i(wb_adr_i),
|
||||
.wb_dat_i(wb_dat_i), .wb_ack_o(wb_ack_o), .wb_dat_o(wb_dat_o),
|
||||
.msgi_tdata(msgi_data), .msgi_tvalid(msgi_valid), .msgi_tready(msgi_ready),
|
||||
.msgo_tdata(msgo_data), .msgo_tvalid(msgo_valid), .msgo_tready(msgo_ready),
|
||||
.debug());
|
||||
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user