Removed copy of FPGA source files.

Original-commit: fd3e84941de463fa1a7ebab0a69515b4bf2614cd
This commit is contained in:
Martin Braun
2014-10-07 11:25:20 +02:00
parent 56e84828fe
commit 74893643ca
2415 changed files with 0 additions and 1492030 deletions
-28
View File
@@ -1,28 +0,0 @@
#
# Copyright 2013 Ettus Research LLC
#
##################################################
# Control Lib Sources
##################################################
CONTROL_LIB_SRCS = $(abspath $(addprefix $(BASE_DIR)/../lib/control/, \
reset_sync.v \
por_gen.v \
gpio_atr.v \
simple_spi_core.v \
simple_i2c_core.v \
setting_reg.v \
settings_bus_crossclock.v \
radio_ctrl_proc.v \
ram_2port.v \
axi_crossbar.v \
axi_slave_mux.v \
axi_fifo_header.v \
arb_qualify_master.v \
axi_forwarding_cam.v \
axi_test_vfifo.v \
dram_2port.v \
cvita_uart.v \
serial_to_settings.v \
filter_bad_sid.v \
))
View File
-88
View File
@@ -1,88 +0,0 @@
//
// Copyright 2012 Ettus Research LLC
//
//
// This module forms the qualification engine for a single master as
// part of a larger arbitration engine for a slave. It would typically
// be instantiated from arb_select_master.v to form a complete arbitor solution.
//
module arb_qualify_master
#(
parameter WIDTH=16 // Bit width of destination field.
)
(
input clk,
input reset,
input clear,
// Header signals
input [WIDTH-1:0] header,
input header_valid,
// Slave Confg Signals
input [WIDTH-1:0] slave_addr,
input [WIDTH-1:0] slave_mask,
input slave_valid,
// Arbitration flags
output reg master_valid,
input master_ack
);
localparam WAIT_HEADER_VALID = 0;
localparam MATCH = 1;
localparam WAIT_HEADER_NOT_VALID = 2;
reg [1:0] state, next_state;
// Does masked slave address match header field for dest from master?
assign header_match = ((header & slave_mask) == (slave_addr & slave_mask)) && slave_valid;
always @(posedge clk)
if (reset | clear) begin
state <= WAIT_HEADER_VALID;
master_valid <= 0;
end else
begin
case(state)
//
// Wait here until Masters FIFO presents a valid header word.
//
WAIT_HEADER_VALID: begin
if (header_valid)
if (header_match) begin
state <= MATCH;
master_valid <= 1;
end else
next_state <= WAIT_HEADER_NOT_VALID;
end
//
// There should only ever be one match across various arbitors
// if they are configured correctly and since the backing FIFO in the
// master should not start to drain until the arbitration is won
// by that master, master_ack should always preceed de-assertion of
// header_valid so we don't check for the other order of deassertion.
//
MATCH: begin
if (master_ack) begin
master_valid <= 0;
state <= WAIT_HEADER_NOT_VALID;
end
end
//
// Wait here until this master starts to drain this packet from his FIFO.
//
WAIT_HEADER_NOT_VALID: begin
if (!header_valid) begin
state <= WAIT_HEADER_VALID;
end
end
endcase // case(state)
end // else: !if(reset | clear)
endmodule // arb_qualify_master
-167
View File
@@ -1,167 +0,0 @@
//
// Copyright 2012 Ettus Research LLC
//
`define LOG2(N) (\
N < 2 ? 0 : \
N < 4 ? 1 : \
N < 8 ? 2 : \
N < 16 ? 3 : \
N < 32 ? 4 : \
N < 64 ? 5 : \
N < 128 ? 6 : \
N < 256 ? 7 : \
N < 512 ? 8 : \
N < 1024 ? 9 : \
10)
module axi_crossbar
#(
parameter FIFO_WIDTH = 64, // AXI4-STREAM data bus width
parameter DST_WIDTH = 16, // Width of DST field we are routing on.
parameter NUM_INPUTS = 2, // number of input AXI4-STREAM buses
parameter NUM_OUTPUTS = 2 // number of output AXI4-STREAM buses
)
(
input clk,
input reset,
input clear,
input [7:0] local_addr,
// Inputs
input [(FIFO_WIDTH*NUM_INPUTS)-1:0] i_tdata,
input [NUM_INPUTS-1:0] i_tvalid,
input [NUM_INPUTS-1:0] i_tlast,
output [NUM_INPUTS-1:0] i_tready,
input [NUM_INPUTS-1:0] pkt_present,
// Setting Bus
input set_stb,
input [15:0] set_addr,
input [31:0] set_data,
// Output
output [(FIFO_WIDTH*NUM_OUTPUTS)-1:0] o_tdata,
output [NUM_OUTPUTS-1:0] o_tvalid,
output [NUM_OUTPUTS-1:0] o_tlast,
input [NUM_OUTPUTS-1:0] o_tready,
// readback bus
input rb_rd_stb,
input [`LOG2(NUM_OUTPUTS)+`LOG2(NUM_INPUTS)-1:0] rb_addr,
output [31:0] rb_data
);
genvar m,n;
wire [(NUM_INPUTS*NUM_OUTPUTS)-1:0] forward_valid_in;
wire [(NUM_INPUTS*NUM_OUTPUTS)-1:0] forward_ack_in;
wire [(NUM_INPUTS*NUM_OUTPUTS)-1:0] forward_valid_out;
wire [(NUM_INPUTS*NUM_OUTPUTS)-1:0] forward_ack_out;
wire [NUM_INPUTS-1:0] i_tready_slave [0:NUM_OUTPUTS-1];
//
// Instantiate an axi_slave_mux for every slave/output of the Crossbar switch.
// Each axi_slave_mux contains logic to maux and resolve arbitration
// for this particular slave/output.
//
generate
for (m = 0; m < NUM_OUTPUTS; m = m + 1) begin: instantiate_slave_mux
wire [NUM_INPUTS-1:0] i_tready_tmp;
axi_slave_mux
#(
.FIFO_WIDTH(FIFO_WIDTH), // AXI4-STREAM data bus width
.DST_WIDTH(DST_WIDTH), // Width of DST field we are routing on.
.NUM_INPUTS(NUM_INPUTS) // number of input AXI buses
) axi_slave_mux_i
(
.clk(clk),
.reset(reset),
.clear(clear),
// Inputs
.i_tdata(i_tdata),
.i_tvalid(i_tvalid),
.i_tlast(i_tlast),
.i_tready(i_tready_tmp),
// Forwarding flags (One from each Input/Master)
.forward_valid(forward_valid_in[(m+1)*NUM_INPUTS-1:m*NUM_INPUTS]),
.forward_ack(forward_ack_out[(m+1)*NUM_INPUTS-1:m*NUM_INPUTS]),
// Output
.o_tdata(o_tdata[(m*FIFO_WIDTH)+FIFO_WIDTH-1:m*FIFO_WIDTH]),
.o_tvalid(o_tvalid[m]),
.o_tlast(o_tlast[m]),
.o_tready(o_tready[m])
);
if (m==0)
assign i_tready_slave[0] = i_tready_tmp;
else
assign i_tready_slave[m] = i_tready_tmp | i_tready_slave[m-1] ;
end // block: instantiate_slave_mux
endgenerate
assign i_tready = i_tready_slave[NUM_OUTPUTS-1];
//
// Permute the forwarding flag buses
//
generate
for (m = 0; m < NUM_OUTPUTS; m = m + 1) begin: permute_outer
for (n = 0; n < NUM_INPUTS; n = n + 1) begin: permute_inner
assign forward_valid_in[n*NUM_OUTPUTS+m] = forward_valid_out[n+m*NUM_INPUTS];
assign forward_ack_in[n+m*NUM_INPUTS] = forward_ack_out[n*NUM_OUTPUTS+m];
end
end
endgenerate
//
// Instantiate an axi_forwarding_cam for every Input/Master of the Crossbar switch.
// Each contains a TCAM like lookup that allocates an egress port.
//
wire [31:0] rb_data_mux[0:NUM_INPUTS-1];
generate
for (m = 0; m < NUM_INPUTS; m = m + 1) begin: instantiate_cam
axi_forwarding_cam
#(
.BASE(0),
.WIDTH(FIFO_WIDTH), // Bit width of FIFO word.
.NUM_OUTPUTS(NUM_OUTPUTS)
) axi_forwarding_cam_i
(
.clk(clk),
.reset(reset),
.clear(clear),
// Monitored FIFO signals
.o_tdata(i_tdata[(m*FIFO_WIDTH)+FIFO_WIDTH-1:m*FIFO_WIDTH]),
.o_tvalid(i_tvalid[m]),
.o_tready(i_tready[m]),
.o_tlast(i_tlast[m]),
.pkt_present(pkt_present[m]),
// Configuration
.local_addr(local_addr),
// Setting Bus
.set_stb(set_stb),
.set_addr(set_addr),
.set_data(set_data),
// Header signals
.forward_valid(forward_valid_out[(m+1)*NUM_OUTPUTS-1:m*NUM_OUTPUTS]),
.forward_ack(forward_ack_in[(m+1)*NUM_OUTPUTS-1:m*NUM_OUTPUTS]),
// Readback bus
.rb_rd_stb(rb_rd_strobe && (rb_addr[`LOG2(NUM_OUTPUTS)+`LOG2(NUM_INPUTS)-1:`LOG2(NUM_OUTPUTS)] == m)),
.rb_addr(rb_addr[`LOG2(NUM_OUTPUTS)-1:0]),
.rb_data(rb_data_mux[m])
);
end // block: instantiate_fifo_header
endgenerate
assign rb_data = rb_data_mux[rb_addr[`LOG2(NUM_OUTPUTS)+`LOG2(NUM_INPUTS)-1:`LOG2(NUM_OUTPUTS)]];
endmodule // axi_crossbar
-214
View File
@@ -1,214 +0,0 @@
//
// Copyright 2012 Ettus Research LLC
//
`timescale 1 ps / 1 ps
module axi_crossbar_tb;
localparam STREAM_WIDTH = 64;
// Currently support simulations upto 8x8 configurations
localparam MAX_NUM_INPUTS = 8;
localparam MAX_NUM_OUTPUTS = 8;
wire [(MAX_NUM_INPUTS*STREAM_WIDTH)-1:0] i_tdata;
wire [STREAM_WIDTH-1:0] i_tdata_array [0:MAX_NUM_INPUTS-1];
wire [MAX_NUM_INPUTS-1:0] i_tvalid;
wire [MAX_NUM_INPUTS-1:0] i_tready;
wire [MAX_NUM_INPUTS-1:0] i_tlast;
wire [MAX_NUM_INPUTS-1:0] pkt_present;
reg [STREAM_WIDTH-1:0] data_in [0:MAX_NUM_INPUTS-1];
reg [MAX_NUM_INPUTS-1:0] valid_in;
wire [MAX_NUM_INPUTS-1:0] ready_in;
reg [MAX_NUM_INPUTS-1:0] last_in;
wire [(MAX_NUM_OUTPUTS*STREAM_WIDTH)-1:0] o_tdata;
wire [STREAM_WIDTH-1:0] o_tdata_array [0:MAX_NUM_OUTPUTS-1];
wire [MAX_NUM_OUTPUTS-1:0] o_tvalid;
wire [MAX_NUM_OUTPUTS-1:0] o_tready;
wire [MAX_NUM_OUTPUTS-1:0] o_tlast;
wire [STREAM_WIDTH-1:0] data_out [0:MAX_NUM_OUTPUTS-1];
wire [MAX_NUM_OUTPUTS-1:0] valid_out;
reg [MAX_NUM_OUTPUTS-1:0] ready_out;
wire [MAX_NUM_OUTPUTS-1:0] last_out;
genvar m;
reg clk;
reg reset;
reg clear;
reg set_stb;
reg [15:0] set_addr;
reg [31:0] set_data;
// reg reset;
//
// Simulation specific testbench is included here
//
`include "task_library.v"
`include "simulation_script.v"
//
// Define Clocks
//
initial begin
clk = 1'b1;
end
// 125MHz clock
always #4000 clk = ~clk;
//
// Good starting state
//
initial begin
reset <= 0;
clear <= 0;
set_stb <= 0;
set_addr <= 0;
set_data <= 0;
/* -----\/----- EXCLUDED -----\/-----
data_in[0] <= 0;
valid_in[0] <= 0;
last_in[0] <= 0;
data_in[1] <= 0;
valid_in[1] <= 0;
last_in[1] <= 0;
-----/\----- EXCLUDED -----/\----- */
end
//
// AXI Crossbar instance
//
localparam SR_AWIDTH = 16;
localparam SR_XB_LOCAL = 512;
wire [7:0] local_addr;
setting_reg #(.my_addr(SR_XB_LOCAL), .awidth(SR_AWIDTH), .width(8)) sr_local_addr
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr),
.in(set_data),.out(local_addr),.changed());
axi_crossbar
#(
.FIFO_WIDTH(STREAM_WIDTH), // AXI4-STREAM data bus width
.DST_WIDTH(16), // Width of DST field we are routing on.
.NUM_INPUTS(NUM_INPUTS), // number of input AXI4-STREAM buses
.NUM_OUTPUTS(NUM_OUTPUTS) // number of output AXI4-STREAM buses
) axi_crossbar_i
(
.clk(clk),
.reset(reset),
.clear(clear),
.local_addr(local_addr),
// Inputs
.i_tdata(i_tdata[(NUM_INPUTS*STREAM_WIDTH)-1:0]),
.i_tvalid(i_tvalid[NUM_INPUTS-1:0]),
.i_tlast(i_tlast[NUM_INPUTS-1:0]),
.i_tready(i_tready[NUM_INPUTS-1:0]),
.pkt_present(pkt_present[NUM_INPUTS-1:0]),
// Settings bus
.set_stb(set_stb),
.set_addr(set_addr),
.set_data(set_data),
// Output
.o_tdata(o_tdata[(NUM_OUTPUTS*STREAM_WIDTH)-1:0]),
.o_tvalid(o_tvalid[NUM_OUTPUTS-1:0]),
.o_tlast(o_tlast[NUM_OUTPUTS-1:0]),
.o_tready(o_tready[NUM_OUTPUTS-1:0]),
// Readback Bus
.rb_rd_stb(1'b0),
.rb_addr(0),
.rb_data()
);
//
// Input FIFOs
//
generate
for (m=0;m<NUM_INPUTS;m=m+1)
begin: input_fifos
assign i_tdata[(STREAM_WIDTH*m)+STREAM_WIDTH-1:STREAM_WIDTH*m] = i_tdata_array[m];
axi_fifo_short
#(.WIDTH(STREAM_WIDTH+1)) axi_fifo_short_in
(
.clk(clk),
.reset(reset),
.clear(clear),
.o_tdata({i_tlast[m],i_tdata_array[m]}),
.o_tvalid(i_tvalid[m]),
.o_tready(i_tready[m]),
.i_tdata({last_in[m],data_in[m]}),
.i_tvalid(valid_in[m]),
.i_tready(ready_in[m]),
.space(),
.occupied()
);
monitor_axi_fifo
#(
.COUNT_BITS(8)
) monitor_axi_fifo_in
(
.clk(clk),
.reset(reset),
.clear(clear),
// Monitored FIFO signals
.i_tvalid(valid_in[m]),
.i_tready(ready_in[m]),
.i_tlast(last_in[m]),
.o_tvalid(i_tvalid[m]),
.o_tready(i_tready[m]),
.o_tlast(i_tlast[m]),
// FIFO status output
.pkt_present(pkt_present[m]), // Flags any whole packets present
.pkt_count()
);
end
endgenerate
//
// Output FIFO's
//
generate
for (m=0;m<NUM_OUTPUTS;m=m+1)
begin: output_fifos
assign o_tdata_array[m] = o_tdata[(STREAM_WIDTH*m)+STREAM_WIDTH-1:STREAM_WIDTH*m];
axi_fifo_short
#(.WIDTH(STREAM_WIDTH+1)) axi_fifo_short_out
(
.clk(clk),
.reset(reset),
.clear(clear),
.i_tdata({o_tlast[m],o_tdata_array[m]}),
.i_tvalid(o_tvalid[m]),
.i_tready(o_tready[m]),
.o_tdata({last_out[m],data_out[m]}),
.o_tvalid(valid_out[m]),
.o_tready(ready_out[m]),
.space(),
.occupied()
);
end
endgenerate // block: output_fifos
endmodule // axi_crossbar_tb
-84
View File
@@ -1,84 +0,0 @@
//
// Copyright 2012 Ettus Research LLC
//
//
// This module is connected to the output port of an AXI4-STREAM FIFO that is used to move packetized data.
// It extracts and indicates the header (first word) of a packet in the FIFO. The header and flag are pipelined
// for timing closure.
//
module axi_fifo_header
#(
parameter WIDTH=64 // Bit width of FIFO word.
)
(
input clk,
input reset,
input clear,
// Monitored FIFO signals
input [WIDTH-1:0] o_tdata,
input o_tvalid,
input o_tready,
input o_tlast,
input pkt_present,
// Header signals
output reg [WIDTH-1:0] header,
output reg header_valid
);
localparam WAIT_SOF = 0;
localparam WAIT_EOF = 1;
reg out_state;
//
// Monitor packets leaving FIFO
//
always @(posedge clk)
if (reset | clear) begin
out_state <= WAIT_SOF;
end else
case(out_state)
//
// After RESET or the EOF of previous packet, the first cycle with
// output valid asserted is the SOF and presents the Header word.
// The cycle following the concurrent presentation of asserted output
// valid and output ready presents the word following the header.
//
WAIT_SOF:
if (o_tvalid && o_tready) begin
out_state <= WAIT_EOF;
end else begin
out_state <= WAIT_SOF;
end
//
// EOF is signalled by o_tlast asserted whilst output valid and ready asserted.
//
WAIT_EOF:
if (o_tlast && o_tvalid && o_tready) begin
out_state <= WAIT_SOF;
end else begin
out_state <= WAIT_EOF;
end
endcase // case(in_state)
//
// Pipeline Header signals
//
always @(posedge clk)
if (reset | clear) begin
header <= 0;
header_valid <= 0;
end else if (o_tvalid && (out_state == WAIT_SOF) && pkt_present) begin
// Header will remian valid until o_tready is asserted as this will cause a state transition.
header <= o_tdata;
header_valid <= 1;
end else begin
header_valid <= 0;
end
endmodule // axi_fifo_header
-232
View File
@@ -1,232 +0,0 @@
//
// Copyright 2013 Ettus Research LLC
//
//
// This module implements a highly customized TCAM that enbales forwarding
// decisions to be made on a 16bit field from a VITA SID field.
// The 16bits are allocated by convention as 8 bits of Network address
// (Addresses USRP's etc) and 8 bits of Host address (adresses endpoints in
// a USRP). By definition if the DEST field in the SID addresses a different
// USRP than this one then we don't care about the Host field, only the Network Field.
// We only look at the Host Field when the Network field addresses us.
// Thus Need TCAM of 256+256 entries with Log2(N) bits, where N is the number of
// slave(output) ports on the crossbar switch.
//
//
//
// SID format:
//
// |--------|---------|--------|---------|
// | SOURCE | DEST | DEST |
// | ADDRESS | NETWORK| HOST |
// |--------|---------|--------|---------|
// 8 8 8 8
//
`define LOG2(N) (\
N < 2 ? 0 : \
N < 4 ? 1 : \
N < 8 ? 2 : \
N < 16 ? 3 : \
N < 32 ? 4 : \
N < 64 ? 5 : \
N < 128 ? 6 : \
N < 256 ? 7 : \
N < 512 ? 8 : \
N < 1024 ? 9 : \
10)
module axi_forwarding_cam
#(
parameter BASE = 0, // BASE address for setting registers in this block. (512 addrs used)
parameter WIDTH=64, // Bit width of FIFO word.
parameter NUM_OUTPUTS=2 // Number of outputs (destinations) in crossbar.
)
(
input clk,
input reset,
input clear,
// Monitored FIFO signals
input [WIDTH-1:0] o_tdata,
input o_tvalid,
input o_tready,
input o_tlast,
input pkt_present,
// Configuration
input [7:0] local_addr,
// Setting Bus
input set_stb,
input [15:0] set_addr,
input [31:0] set_data,
// Forwarding Flags
output reg [NUM_OUTPUTS-1:0] forward_valid,
input [NUM_OUTPUTS-1:0] forward_ack,
// readback bus
input rb_rd_stb,
input [`LOG2(NUM_OUTPUTS)-1:0] rb_addr,
output [31:0] rb_data
);
localparam WAIT_SOF = 0;
localparam WAIT_EOF = 1;
reg state;
localparam IDLE = 0;
localparam FORWARD = 1;
localparam WAIT = 2;
reg [1:0] demux_state;
reg [15:0] dst;
reg dst_valid, dst_valid_reg;
wire local_dst;
wire [8:0] read_addr;
//
// Monitor packets leaving FIFO
//
always @(posedge clk)
if (reset | clear) begin
state <= WAIT_SOF;
end else
case(state)
//
// After RESET or the EOF of previous packet, the first cycle with
// output valid asserted is the SOF and presents the Header word.
// The cycle following the concurrent presentation of asserted output
// valid and output ready presents the word following the header.
//
WAIT_SOF:
if (o_tvalid && o_tready) begin
state <= WAIT_EOF;
end else begin
state <= WAIT_SOF;
end
//
// EOF is signalled by o_tlast asserted whilst output valid and ready asserted.
//
WAIT_EOF:
if (o_tlast && o_tvalid && o_tready) begin
state <= WAIT_SOF;
end else begin
state <= WAIT_EOF;
end
endcase // case(in_state)
//
// Extract Destination fields(s) from SID
//
always @(posedge clk)
if (reset | clear) begin
dst <= 0;
dst_valid <= 0;
dst_valid_reg <= 0;
end else if (o_tvalid && (state == WAIT_SOF) && pkt_present) begin
// SID will remain valid until o_tready is asserted as this will cause a state transition.
dst <= o_tdata[15:0];
dst_valid <= 1;
dst_valid_reg <= dst_valid;
end else begin
dst_valid <= 0;
dst_valid_reg <= dst_valid;
end
//
// Is Network field in DST our local address?
//
assign local_dst = (dst[15:8] == local_addr) && dst_valid;
//
// Mux address to RAM so that it searches CAM for Network field or Host field.
// Network addresses are stored in the lower 256 locations, host addresses the upper 256.
//
assign read_addr = {local_dst,(local_dst ? dst[7:0] : dst[15:8])};
//
// Imply a block RAM here, 512xCeil(Log2(NUM_OUTPUTS))
//
//synthesis attribute ram_style of mem is block
reg [(`LOG2(NUM_OUTPUTS))-1 : 0] mem [0:511];
reg [8:0] read_addr_reg;
wire write;
wire [`LOG2(NUM_OUTPUTS)-1:0] read_data;
assign write = (set_addr[15:9] == (BASE >>9)) && set_stb; // Addr decode.
always @(posedge clk)
begin
read_addr_reg <= read_addr;
if (write) begin
mem[set_addr[8:0]] <= set_data[`LOG2(NUM_OUTPUTS)-1:0];
end
end
assign read_data = mem[read_addr_reg];
//
// State machine to manage forwarding flags.
//
always @(posedge clk)
if (reset | clear) begin
demux_state <= IDLE;
end else
case(demux_state)
// Wait for Valid DST which indicates a new packet lookup in the CAM.
IDLE: begin
if (dst_valid_reg == 1) begin
forward_valid <= 1 << read_data;
demux_state <= FORWARD;
end
end
// When Slave/Output thats forwarding ACK's the forward flag, clear request and wait for packet to be transfered
FORWARD: begin
if ((forward_ack & forward_valid) != 0) begin
forward_valid <= 0;
demux_state <= WAIT;
end
end
// When packet transfered go back to idle.
WAIT: begin
if (forward_ack == 0)
demux_state <= IDLE;
end
endcase // case (demux_state)
//
// Compile forwarding statistics
// (This uses a lot of registers!)
//
genvar m;
reg [31:0] statistics [0:NUM_OUTPUTS-1];
generate
for (m = 0; m < NUM_OUTPUTS; m = m + 1) begin: generate_stats
always @(posedge clk)
if (reset | clear)
statistics[m] <= 0;
else if ((rb_addr == m) && rb_rd_stb)
statistics[m] <= 0;
else if (forward_ack[m] & forward_valid[m])
statistics[m] <= statistics[m] + 1;
end
endgenerate
assign rb_data = statistics[rb_addr];
endmodule
-122
View File
@@ -1,122 +0,0 @@
//
// Copyright 2012 Ettus Research LLC
//
`define LOG2(N) (\
N < 2 ? 0 : \
N < 4 ? 1 : \
N < 8 ? 2 : \
N < 16 ? 3 : \
N < 32 ? 4 : \
N < 64 ? 5 : \
N < 128 ? 6 : \
N < 256 ? 7 : \
N < 512 ? 8 : \
N < 1024 ? 9 : \
10)
module axi_slave_mux
#(
parameter FIFO_WIDTH = 64, // AXI4-STREAM data bus width
parameter DST_WIDTH = 16, // Width of DST field we are routing on.
parameter NUM_INPUTS = 2 // number of input AXI buses
)
(
input clk,
input reset,
input clear,
// Inputs
input [(FIFO_WIDTH*NUM_INPUTS)-1:0] i_tdata,
input [NUM_INPUTS-1:0] i_tvalid,
input [NUM_INPUTS-1:0] i_tlast,
output [NUM_INPUTS-1:0] i_tready,
// Forwarding Flags
input [NUM_INPUTS-1:0] forward_valid,
output reg [NUM_INPUTS-1:0] forward_ack,
// Output
output [FIFO_WIDTH-1:0] o_tdata,
output o_tvalid,
output o_tlast,
input o_tready
);
wire [FIFO_WIDTH-1:0] i_tdata_array [0:NUM_INPUTS-1];
reg [`LOG2(NUM_INPUTS):0] select;
reg enable;
reg state;
localparam CHECK_THIS_INPUT = 0;
localparam WAIT_LAST = 1;
always @(posedge clk)
if (reset | clear) begin
state <= CHECK_THIS_INPUT;
select <= 0;
enable <= 0;
forward_ack <= 0;
end else begin
case(state)
// Is the currently selected input addressing this slave with a ready packet?
CHECK_THIS_INPUT: begin
if (forward_valid[select]) begin
enable <= 1;
forward_ack[select] <= 1;
state <= WAIT_LAST;
end else if (select == NUM_INPUTS - 1 ) begin
select <= 0;
end else begin
select <= select + 1;
end
end
// Assert ACK immediately to forwarding logic and then wait for end of packet.
WAIT_LAST: begin
if (i_tlast[select] && i_tvalid[select] && o_tready) begin
if (select == NUM_INPUTS - 1 ) begin
select <= 0;
end else begin
select <= select + 1;
end
state <= CHECK_THIS_INPUT;
forward_ack <= 0;
enable <= 0;
end else begin
forward_ack[select] <= 1;
enable <= 1;
end
end
endcase // case(state)
end
//
// Combinatorial mux
//
genvar m;
generate
for (m = 0; m < NUM_INPUTS; m = m + 1) begin: form_buses
assign i_tdata_array[m] = i_tdata[(m*FIFO_WIDTH)+FIFO_WIDTH-1:m*FIFO_WIDTH];
end
endgenerate
assign o_tdata = i_tdata_array[select];
assign o_tvalid = enable && i_tvalid[select];
assign o_tlast = enable && i_tlast[select];
// assign i_tready = {NUM_INPUTS{o_tready}} & (enable << select);
generate
for (m = 0; m < NUM_INPUTS; m = m + 1) begin: form_ready
assign i_tready[m] = o_tready && enable && (select == m);
end
endgenerate
endmodule // axi_slave_mux
-139
View File
@@ -1,139 +0,0 @@
//
// Test Virtual FIFO's by streaming modulo 2^32 counter (replicated in upper
// and lower 32bits). Test result by tracking count on receive and using
// sticky flag for error indication.
// Also provide signal from MSB of 32bit count to blink LED.
//
module axi_test_vfifo
#(parameter PACKET_SIZE = 128)
(
input aclk,
input aresetn,
input enable,
// AXI Stream Out
output reg out_axis_tvalid,
input out_axis_tready,
output [63 : 0] out_axis_tdata,
output reg [7 : 0] out_axis_tstrb,
output reg [7 : 0] out_axis_tkeep,
output reg out_axis_tlast,
output reg [0 : 0] out_axis_tid,
output reg [0 : 0] out_axis_tdest,
input vfifo_full,
// AXI Stream In
input in_axis_tvalid,
output reg in_axis_tready,
input [63 : 0] in_axis_tdata,
input [7 : 0] in_axis_tstrb,
input [7 : 0] in_axis_tkeep,
input in_axis_tlast,
input [0 : 0] in_axis_tid,
input [0 : 0] in_axis_tdest,
// Flags
output reg flag_error,
output heartbeat_in,
output heartbeat_out,
output [31:0] expected_count
);
reg [31:0] out_count;
reg [31:0] in_count;
reg [63:0] in_axis_tdata_reg;
reg in_data_valid;
//
// Output
//
always @(posedge aclk)
if (!aresetn) begin
out_count <= 0;
out_axis_tvalid <= 0;
out_axis_tid <= 0; // Don't care.
out_axis_tdest <= 0; // Only use port 0 of VFIFO.
out_axis_tstrb <= 0; // Unused in VFIFO
out_axis_tkeep <= 8'hFF; // Always use every byte of data
out_axis_tlast <= 1'b0;
end else if (enable) begin
if (~vfifo_full) begin
// Always ready to output new count value.
out_axis_tvalid <= 1;
if (out_axis_tready)
out_count <= out_count + 1;
// Assert TLAST every PACKET_SIZE beats.
if (out_count[15:0] == PACKET_SIZE)
out_axis_tlast <= 1'b1;
else
out_axis_tlast <= 1'b0;
end else begin
out_axis_tvalid <= 0;
end
end else begin
out_axis_tlast <= 1'b0;
out_axis_tvalid <= 0;
end
assign out_axis_tdata = {out_count,out_count};
assign heartbeat_out = out_count[28];
//
// Input (Ignore TLAST signal)
//
always @(posedge aclk)
if (!aresetn) begin
in_axis_tready <= 0;
in_axis_tdata_reg <= 0;
in_data_valid <= 0;
end else if (enable) begin
in_axis_tready <= 1;
in_axis_tdata_reg <= in_axis_tdata;
if (in_axis_tvalid)
in_data_valid <= 1;
else
in_data_valid <= 0;
end else begin
in_data_valid <= 0;
in_axis_tready <= 0;
end // else: !if(enable)
assign heartbeat_in = in_count[28];
//
// Input Checker
//
always @(posedge aclk)
if (!aresetn) begin
in_count <= 0;
flag_error <= 0;
end else if (enable) begin
if (in_data_valid) begin
if ((in_axis_tdata_reg[63:32] != in_count) || (in_axis_tdata_reg[31:0] != in_count))
begin
flag_error <= 1;
in_count <= in_axis_tdata_reg[63:32] + 1;
end
else
begin
flag_error <= 0;
in_count <= in_count + 1;
end
end
end
assign expected_count = in_count;
endmodule // axi_test_vfifo
-42
View File
@@ -1,42 +0,0 @@
`define LOG2(N) (\
N < 2 ? 0 : \
N < 4 ? 1 : \
N < 8 ? 2 : \
N < 16 ? 3 : \
N < 32 ? 4 : \
N < 64 ? 5 : \
N < 128 ? 6 : \
N < 256 ? 7 : \
N < 512 ? 8 : \
N < 1024 ? 9 : \
10)
module binary_encoder
#(
parameter SIZE = 16
)
(
input [SIZE-1:0] in,
output [`LOG2(SIZE)-1:0] out
);
genvar m,n;
generate
// Loop enough times to represent the total number of input bits as an encoded value
for (m = 0; m <= `log2(SIZE-1); m = m + 1) begin: expand_or_tree
wire [SIZE-1:0] encoding;
// Build enable mask by iterating through every input bit.
for (n = 0; n < SIZE ; n = n + 1) begin: encode_this_bit
assign encoding[n] = n[m];
end
// OR tree for this output bit with appropraite bits enabled.
assign out[m] = |(encoding & in);
end
endgenerate
endmodule // binary_encoder
-164
View File
@@ -1,164 +0,0 @@
//
// Copyright 2013 Ettus Research LLC
//
//create a compressed vita based uart data interface
module cvita_uart
#(
parameter SIZE = 0
)
(
//clocking interface
input clk, input rst,
//uart interface
input rxd, output txd,
//chdr fifo input
input [63:0] i_tdata,
input i_tlast,
input i_tvalid,
output i_tready,
//chdr fifo output
output [63:0] o_tdata,
output o_tlast,
output o_tvalid,
input o_tready
);
reg [31:0] sid;
//baud clock divider
reg [15:0] clkdiv;
//hold rx in disable until a tx event
reg rxd_enable;
//==================================================================
//== RXD capture and packet generation interface
//==================================================================
wire [7:0] rx_char;
wire fifo_empty;
wire fifo_read;
reg [11:0] seqnum;
wire pgen_trigger;
wire pgen_done;
//rx uart capture
simple_uart_rx #(.SIZE(SIZE)) simple_uart_rx
(
.clk(clk), .rst(rst),
.fifo_out(rx_char), .fifo_read(fifo_read), .fifo_level(), .fifo_empty(fifo_empty),
.clkdiv(clkdiv), .rx(rxd)
);
//packet generation - holds rx character
context_packet_gen context_packet_gen
(
.clk(clk), .reset(rst), .clear(1'b0),
.trigger(pgen_trigger),
.seqnum(seqnum),
.sid({sid[15:0], sid[31:16]}),
.body({56'b0, rx_char}),
.vita_time(64'b0),
.done(pgen_done),
.o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready)
);
//state machine to manage pgen and rx uart
reg [1:0] rxd_state;
localparam RXD_STATE_RECV_CHAR = 0;
localparam RXD_STATE_PGEN_TRIG = 1;
localparam RXD_STATE_WAIT_DONE = 2;
localparam RXD_STATE_READ_FIFO = 3;
always @(posedge clk) begin
if (rst) begin
seqnum <= 12'b0;
rxd_state <= RXD_STATE_RECV_CHAR;
end
else case (rxd_state)
RXD_STATE_RECV_CHAR: begin
if (!fifo_empty && rxd_enable) rxd_state <= RXD_STATE_PGEN_TRIG;
end
RXD_STATE_PGEN_TRIG: begin
rxd_state <= RXD_STATE_WAIT_DONE;
end
RXD_STATE_WAIT_DONE: begin
if (pgen_done) rxd_state <= RXD_STATE_READ_FIFO;
end
RXD_STATE_READ_FIFO: begin
rxd_state <= RXD_STATE_RECV_CHAR;
seqnum <= seqnum + 1'b1;
end
endcase //rxd_state
end
assign fifo_read = (rxd_state == RXD_STATE_READ_FIFO) || (!rxd_enable);
assign pgen_trigger = (rxd_state == RXD_STATE_PGEN_TRIG);
//==================================================================
//== TXD generation and packet control interface
//==================================================================
wire [7:0] tx_char;
wire fifo_write;
wire fifo_full;
simple_uart_tx #(.SIZE(SIZE)) simple_uart_tx
(
.clk(clk), .rst(rst),
.fifo_in(tx_char), .fifo_write(fifo_write), .fifo_level(), .fifo_full(fifo_full),
.clkdiv(clkdiv), .baudclk(), .tx(txd)
);
//state machine to manage control and tx uart
reg [1:0] txd_state;
localparam TXD_STATE_RECV_CHDR = 0;
localparam TXD_STATE_RECV_TIME = 1;
localparam TXD_STATE_RECV_BODY = 2;
localparam TXD_STATE_DROP_FIFO = 3;
always @(posedge clk) begin
if (rst) begin;
txd_state <= TXD_STATE_RECV_CHDR;
rxd_enable <= 1'b0;
end
if (i_tvalid && i_tready) case (txd_state)
TXD_STATE_RECV_CHDR: begin
txd_state <= (i_tdata[61])? TXD_STATE_RECV_TIME : TXD_STATE_RECV_BODY;
sid <= i_tdata[31:0];
end
TXD_STATE_RECV_TIME: begin
txd_state <= TXD_STATE_RECV_BODY;
end
TXD_STATE_RECV_BODY: begin
txd_state <= (i_tlast)? TXD_STATE_RECV_CHDR : TXD_STATE_DROP_FIFO;
clkdiv <= i_tdata[47:32];
rxd_enable <= 1'b1;
end
TXD_STATE_DROP_FIFO: begin
if (i_tlast) txd_state <= TXD_STATE_RECV_CHDR;
end
endcase //txd_state
end
assign tx_char = i_tdata[7:0];
assign fifo_write = (txd_state == TXD_STATE_RECV_BODY) && i_tvalid && i_tready;
assign i_tready = !fifo_full;
endmodule // cvita_uart
-27
View File
@@ -1,27 +0,0 @@
////////////////////////////////////////////////////////////////////////
// Copyright Ettus Research LLC
////////////////////////////////////////////////////////////////////////
module dram_2port
#(parameter DWIDTH=32,
parameter AWIDTH=9)
(input clk,
input write,
input [AWIDTH-1:0] raddr,
input [AWIDTH-1:0] waddr,
input [DWIDTH-1:0] wdata,
output [DWIDTH-1:0] rdata);
reg [DWIDTH-1:0] ram [(1<<AWIDTH)-1:0];
integer i;
initial
for(i=0;i<(1<<AWIDTH);i=i+1)
ram[i] <= {DWIDTH{1'b0}};
assign rdata = ram[raddr];
always @(posedge clk) begin
if (write) ram[waddr] <= wdata;
end
endmodule //dram_2port
-72
View File
@@ -1,72 +0,0 @@
// Discard silently packets which don't match this SID
module filter_bad_sid
(
input clk,
input reset,
input clear,
//
input [64:0] i_tdata,
input i_tvalid,
output i_tready,
//
output [64:0] o_tdata,
output o_tvalid,
input o_tready,
//
output reg [15:0] count
);
reg [1:0] state;
wire good_sid;
wire qualify_i_tvalid;
localparam IDLE = 0;
localparam ACCEPT = 1;
localparam DISCARD = 2;
always @(posedge clk)
if (reset | clear) begin
state <= IDLE;
count <= 0;
end else
case(state)
//
IDLE: begin
if (i_tvalid && i_tready)
if (good_sid)
state <= ACCEPT;
else begin
count <= count + 1;
state <= DISCARD;
end
end
//
ACCEPT: begin
if (i_tvalid && i_tready && i_tdata[64])
state <= IDLE;
end
//
DISCARD: begin
if (i_tvalid && i_tready && i_tdata[64])
state <= IDLE;
end
endcase // case(state)
assign good_sid = ((i_tdata[15:0] == 16'h00A0) || (i_tdata[15:0] == 16'h00B0));
assign qualify_i_tvalid = (state == IDLE) ? good_sid : ((state == DISCARD) ? 1'b0 : 1'b1);
//
// Buffer output, break combinatorial timing paths
//
axi_fifo_short #(.WIDTH(65)) fifo_short
(
.clk(clk), .reset(reset), .clear(clear),
.i_tdata(i_tdata), .i_tvalid(i_tvalid && qualify_i_tvalid), .i_tready(i_tready),
.o_tdata(o_tdata), .o_tvalid(o_tvalid), .o_tready(o_tready),
.space(), .occupied()
);
endmodule // axi_fast_fifo
-66
View File
@@ -1,66 +0,0 @@
//
// Copyright 2011 Ettus Research LLC
//
module gpio_atr
#(parameter BASE = 0,
parameter WIDTH = 32,
parameter default_ddr = 0,
parameter default_idle = 0)
(input clk, input reset,
input set_stb, input [7:0] set_addr, input [31:0] set_data,
input rx, input tx,
inout [WIDTH-1:0] gpio,
output reg [31:0] gpio_readback
);
wire [WIDTH-1:0] ddr, in_idle, in_tx, in_rx, in_fdx;
reg [WIDTH-1:0] rgpio, igpio;
reg [WIDTH-1:0] gpio_pipe;
setting_reg #(.my_addr(BASE+0), .width(WIDTH), .at_reset(default_idle)) reg_idle
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),
.out(in_idle),.changed());
setting_reg #(.my_addr(BASE+1), .width(WIDTH)) reg_rx
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),
.out(in_rx),.changed());
setting_reg #(.my_addr(BASE+2), .width(WIDTH)) reg_tx
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),
.out(in_tx),.changed());
setting_reg #(.my_addr(BASE+3), .width(WIDTH)) reg_fdx
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),
.out(in_fdx),.changed());
setting_reg #(.my_addr(BASE+4), .width(WIDTH), .at_reset(default_ddr)) reg_ddr
(.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),
.out(ddr),.changed());
always @(posedge clk)
case({tx,rx})
2'b00: rgpio <= in_idle;
2'b01: rgpio <= in_rx;
2'b10: rgpio <= in_tx;
2'b11: rgpio <= in_fdx;
endcase // case ({tx,rx})
integer n;
always @*
for(n=0;n<WIDTH;n=n+1)
igpio[n] <= ddr[n] ? rgpio[n] : 1'bz;
assign gpio = igpio;
// Double pipeline stage for timing, first flop is in IOB, second in core logic.
always @(posedge clk) begin
gpio_pipe <= gpio;
gpio_readback <= gpio_pipe;
end
endmodule // gpio_atr
-25
View File
@@ -1,25 +0,0 @@
//
// Copyright 2013 Ettus Research LLC
//
module por_gen
(input clk,
output reset_out);
reg por_rst;
reg [7:0] por_counter = 8'h0;
always @(posedge clk)
if (por_counter != 8'h55)
begin
por_counter <= por_counter + 8'h1;
por_rst <= 1'b1;
end
else
por_rst <= 1'b0;
assign reset_out = por_rst;
endmodule // por_gen
-143
View File
@@ -1,143 +0,0 @@
// Radio Control Processor
// Accepts compressed vita extension context packets of the following form:
// { VITA Compressed Header, Stream ID }
// { Optional 64 bit time }
// { 16'h0, setting bus address [15:0], setting [31:0] }
//
// If there is a timestamp, packet is held until that time comes.
// Goes immediately if there is no timestamp or if time has passed.
// Sends out setting to setting bus, and then generates a response packet
// with the same sequence number, the src/dest swapped streamid, and the actual time
// the setting was sent.
//
// Note -- if t0 is the requested time, the actual send time on the setting bus is t0 + 1 cycle.
// Note 2 -- if t1 is the actual time the setting bus, t1+2 is the reported time.
module radio_ctrl_proc
(input clk, input reset, input clear,
input [63:0] ctrl_tdata, input ctrl_tlast, input ctrl_tvalid, output reg ctrl_tready,
output reg [63:0] resp_tdata, output reg resp_tlast, output resp_tvalid, input resp_tready,
input [63:0] vita_time,
output set_stb, output [7:0] set_addr, output [31:0] set_data,
input ready,
input [63:0] readback,
output [31:0] debug);
localparam RC_HEAD = 4'd0;
localparam RC_TIME = 4'd1;
localparam RC_DATA = 4'd2;
localparam RC_DUMP = 4'd3;
localparam RC_RESP_HEAD = 4'd4;
localparam RC_RESP_TIME = 4'd5;
localparam RC_RESP_DATA = 4'd6;
wire IS_EC = ctrl_tdata[63];
wire HAS_TIME = ctrl_tdata[61];
reg HAS_TIME_reg;
reg [3:0] rc_state;
reg [63:0] cmd_time;
wire now, late, go;
reg [11:0] seqnum;
reg [31:0] sid;
always @(posedge clk)
if(reset)
begin
rc_state <= RC_HEAD;
HAS_TIME_reg <= 1'b0;
sid <= 32'd0;
seqnum <= 12'd0;
end
else
case(rc_state)
RC_HEAD :
if(ctrl_tvalid)
begin
sid <= ctrl_tdata[31:0];
seqnum <= ctrl_tdata[59:48];
HAS_TIME_reg <= HAS_TIME;
if(IS_EC)
if(HAS_TIME)
rc_state <= RC_TIME;
else
rc_state <= RC_DATA;
else
if(~ctrl_tlast)
rc_state <= RC_DUMP;
end
RC_TIME :
if(ctrl_tvalid)
if(ctrl_tlast)
rc_state <= RC_RESP_HEAD;
else if(go)
rc_state <= RC_DATA;
RC_DATA :
if(ctrl_tvalid)
if(ready)
if(ctrl_tlast)
rc_state <= RC_RESP_HEAD;
else
rc_state <= RC_DUMP;
RC_DUMP :
if(ctrl_tvalid)
if(ctrl_tlast)
rc_state <= RC_RESP_HEAD;
RC_RESP_HEAD :
if(resp_tready)
rc_state <= RC_RESP_TIME;
RC_RESP_TIME :
if(resp_tready)
rc_state <= RC_RESP_DATA;
RC_RESP_DATA:
if(resp_tready)
rc_state <= RC_HEAD;
default :
rc_state <= RC_HEAD;
endcase // case (rc_state)
always @*
case (rc_state)
RC_HEAD : ctrl_tready <= 1'b1;
RC_TIME : ctrl_tready <= ctrl_tlast | go;
RC_DATA : ctrl_tready <= ready;
RC_DUMP : ctrl_tready <= 1'b1;
default : ctrl_tready <= 1'b0;
endcase // case (rc_state)
time_compare time_compare
(.clk(clk), .reset(reset), .time_now(vita_time), .trigger_time(ctrl_tdata), .now(now), .early(), .late(late), .too_early());
assign go = now | late;
assign set_stb = (rc_state == RC_DATA) & ready & ctrl_tvalid;
assign set_addr = ctrl_tdata[39:32];
assign set_data = ctrl_tdata[31:0];
always @*
case (rc_state)
RC_RESP_HEAD : { resp_tlast, resp_tdata } <= {1'b0, 4'hA, seqnum, 16'd24, sid[15:0], sid[31:16] };
RC_RESP_TIME : { resp_tlast, resp_tdata } <= {1'b0, vita_time};
RC_RESP_DATA : { resp_tlast, resp_tdata } <= {1'b1, readback};
default : { resp_tlast, resp_tdata } <= 65'h0;
endcase // case (rc_state)
assign resp_tvalid = (rc_state == RC_RESP_HEAD) | (rc_state == RC_RESP_TIME) | (rc_state == RC_RESP_DATA);
endmodule // radio_ctrl_proc
-104
View File
@@ -1,104 +0,0 @@
`timescale 1ns/1ps
module radio_ctrl_proc_tb();
reg clk = 0;
reg reset = 1;
always #10 clk = ~clk;
initial $dumpfile("radio_ctrl_proc_tb.vcd");
initial $dumpvars(0,radio_ctrl_proc_tb);
initial
begin
#1000 reset = 0;
#20000;
$finish;
end
reg [63:0] vita_time = 64'd0;
always @(posedge clk)
if(reset) vita_time <= 64'd0;
else vita_time <= vita_time + 64'd1;
reg [63:0] tdata;
wire [63:0] tdata_int;
reg tlast;
wire tlast_int;
reg tvalid = 1'b0;
wire tvalid_int;
wire tready, tready_int;
wire [7:0] set_addr;
wire [31:0] set_data;
wire set_stb;
wire ready = 1'b1;
task send_packet;
input ec;
input timed;
input [11:0] seqnum;
input [31:0] sid;
input [63:0] vtime;
input [15:0] addr;
input [31:0] data;
begin
// Send a packet
@(posedge clk);
tlast <= 1'b0;
tdata <= { ec, 1'b0, timed, 1'b0, seqnum, timed ? 16'd6 : 16'd4, sid };
tvalid <= 1;
@(posedge clk);
if(timed)
begin
tdata <= vtime;
@(posedge clk);
end
tlast <= 1'b1;
tdata <= { 16'h0, addr, data };
@(posedge clk);
tvalid <= 0;
@(posedge clk);
end
endtask // send_packet
initial
begin
tvalid <= 1'b0;
while(reset)
@(posedge clk);
send_packet(1'b1,1'b0,12'h5,32'hDEAD_BEEF,64'h0,16'hB,32'hF00D_1234);
send_packet(1'b1,1'b1,12'h6,32'hDEAD_6789,64'h20,16'hC,32'hABCD_4321);
send_packet(1'b1,1'b1,12'h7,32'hDEAD_6789,64'h30,16'hC,32'hABCD_4321);
//send_packet(.ec(1), .timed(0), .seqnum(5), .sid(32'hDEAD_BEEF), .vtime(0), .addr(16'hB), .data(32'hF00D_1234));
end
axi_fifo_short #(.WIDTH(65)) axi_fifo_short
(.clk(clk), .reset(reset), .clear(1'b0),
.i_tdata({tlast,tdata}), .i_tvalid(tvalid), .i_tready(tready),
.o_tdata({tlast_int,tdata_int}), .o_tvalid(tvalid_int), .o_tready(tready_int));
wire [63:0] resp_tdata;
wire resp_tlast, resp_tvalid, resp_tready;
radio_ctrl_proc radio_ctrl_proc
(.clk(clk), .reset(reset), .clear(1'b0),
.ctrl_tdata(tdata_int), .ctrl_tlast(tlast_int), .ctrl_tvalid(tvalid_int), .ctrl_tready(tready_int),
.resp_tdata(resp_tdata), .resp_tlast(resp_tlast), .resp_tvalid(resp_tvalid), .resp_tready(resp_tready),
.vita_time(vita_time), .ready(ready),
.set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
.debug()
);
assign resp_tready = 1'b1;
always @(posedge clk)
if(resp_tvalid & resp_tready)
begin
$display("%x",resp_tdata);
if(resp_tlast)
$display("TLAST");
end
endmodule // radio_ctrl_proc_tb
-49
View File
@@ -1,49 +0,0 @@
//
// Copyright 2011 Ettus Research LLC
//
module ram_2port
#(parameter DWIDTH=32,
parameter AWIDTH=9)
(input clka,
input ena,
input wea,
input [AWIDTH-1:0] addra,
input [DWIDTH-1:0] dia,
output reg [DWIDTH-1:0] doa,
input clkb,
input enb,
input web,
input [AWIDTH-1:0] addrb,
input [DWIDTH-1:0] dib,
output reg [DWIDTH-1:0] dob);
reg [DWIDTH-1:0] ram [(1<<AWIDTH)-1:0];
/*
integer i;
initial
for(i=0;i<(1<<AWIDTH);i=i+1)
ram[i] <= {DWIDTH{1'b0}};
*/
always @(posedge clka) begin
if (ena)
begin
if (wea)
ram[addra] <= dia;
doa <= ram[addra];
end
end
always @(posedge clkb) begin
if (enb)
begin
if (web)
ram[addrb] <= dib;
dob <= ram[addrb];
end
end
endmodule // ram_2port
-28
View File
@@ -1,28 +0,0 @@
//
// Copyright 2011 Ettus Research LLC
//
module reset_sync
(input clk,
input reset_in,
output reset_out);
reg reset_int;
reg reset_out_tmp;
//synthesis attribute async_reg of reset_out_tmp is "true";
//synthesis attribute async_reg of reset_int is "true";
always @(posedge clk or posedge reset_in)
if(reset_in)
{reset_out_tmp,reset_int} <= 2'b11;
else
{reset_out_tmp,reset_int} <= {reset_int,1'b0};
assign reset_out = reset_out_tmp;
endmodule // reset_sync
-121
View File
@@ -1,121 +0,0 @@
module serial_to_settings
(
input clk,
input reset,
// Serial signals (async)
input scl,
input sda,
// Settngs bus out
output reg set_stb,
output reg [7:0] set_addr,
output reg [31:0] set_data,
// Debug
output [31:0] debug
);
reg [2:0] state;
localparam SEARCH = 3'h0;
localparam ADDRESS = 3'h1;
localparam DATA = 3'h2;
localparam STOP1 = 3'h3;
localparam STOP2 = 3'h4;
reg scl_pre_reg, scl_reg, scl_reg2;
reg sda_pre_reg, sda_reg, sda_reg2;
reg [4:0] counter;
always @(posedge clk) begin
scl_reg2 <= scl_reg;
scl_reg <= scl_pre_reg;
scl_pre_reg <= scl;
sda_reg2 <= sda_reg;
sda_reg <= sda_pre_reg;
sda_pre_reg <= sda;
end
always @(posedge clk)
if (reset) begin
state <= SEARCH;
counter <= 0;
set_addr <= 0;
set_data <= 0;
set_stb <= 0;
end else begin
case(state)
//
// Search for I2C like start indication: SDA goes low whilst clock is high.
//
SEARCH: begin
set_stb <= 0;
// Look for START.
if (scl_reg && scl_reg2 && !sda_reg && sda_reg2) begin
state <= ADDRESS;
counter <= 0;
end
end
//
// Count 8 Address bits.
// Master changes SDA on falling edge of SCL, we sample on the rising edge.
//
ADDRESS: begin
if (scl_reg && !scl_reg2) begin
set_addr[7:0] <= {set_addr[6:0],sda_reg};
if (counter == 7) begin
state <= DATA;
counter <= 0;
end else
counter <= counter + 1;
end
end
//
// Count 32 data bits.
// Master changes SDA on falling edge of SCL, we sample on the rising edge.
//
DATA: begin
if (scl_reg && !scl_reg2) begin
set_data[31:0] <= {set_data[30:0],sda_reg};
if (counter == 31) begin
state <= STOP1;
counter <= 0;
end else
counter <= counter + 1;
end
end
//
// Looks for rising SCL edge before STOP bit.
//
STOP1: begin
if (scl_reg && !scl_reg2) begin
state <= STOP2;
end
end
//
// Looks for STOP bit
//
STOP2: begin
if (scl_reg && scl_reg2 && sda_reg && !sda_reg2) begin
state <= SEARCH;
counter <= 0;
set_stb <= 1;
end
end
endcase // case(state)
end // else: !if(reset)
assign debug =
{
counter[4:0],
state[2:0],
scl_reg,
sda_reg
};
endmodule // serial_to_settings
-82
View File
@@ -1,82 +0,0 @@
module serial_to_settings_tb();
reg clk;
reg reset;
wire scl;
wire sda;
wire set_stb;
wire [7:0] set_addr;
wire [31:0] set_data;
//
// These registers optionaly used
// to drive nets through procedural assignments in test bench.
// These drivers default to tri-stated.
//
reg scl_r;
reg sda_r;
assign scl = scl_r;
assign sda = sda_r;
initial
begin
scl_r <= 1'bz;
sda_r <= 1'bz;
end
serial_to_settings serial_to_settings_i
(
.clk(clk),
.reset(reset),
// Serial signals (async)
.scl(scl),
.sda(sda),
// Settngs bus out
.set_stb(set_stb),
.set_addr(set_addr),
.set_data(set_data)
);
// Nasty HAck to convert settings to wishbone crudely.
reg wb_stb;
wire wb_ack_o;
always @(posedge clk)
if (reset)
wb_stb <= 0;
else
wb_stb <= set_stb ? 1 : ((wb_ack_o) ? 0 : wb_stb);
simple_uart debug_uart
(
.clk_i(clk),
.rst_i(reset),
.we_i(wb_stb),
.stb_i(wb_stb),
.cyc_i(wb_stb),
.ack_o(wb_ack_o),
.adr_i(set_addr[2:0]),
.dat_i(set_data[31:0]),
.dat_o(),
.rx_int_o(),
.tx_int_o(),
.tx_o(txd),
.rx_i(rxd),
.baud_o()
);
//
// Bring in a simulation script here
//
`include "simulation_script.v"
endmodule
-35
View File
@@ -1,35 +0,0 @@
//
// Copyright 2011-2012 Ettus Research LLC
//
//----------------------------------------------------------------------
//-- A settings register is a peripheral for the settings register bus.
//-- When the settings register sees strobe abd a matching address,
//-- the outputs will be become registered to the given input bus.
//----------------------------------------------------------------------
module setting_reg
#(parameter my_addr = 0,
parameter awidth = 8,
parameter width = 32,
parameter at_reset=0)
(input clk, input rst, input strobe, input wire [awidth-1:0] addr,
input wire [31:0] in, output reg [width-1:0] out, output reg changed);
always @(posedge clk)
if(rst)
begin
out <= at_reset;
changed <= 1'b0;
end
else
if(strobe & (my_addr==addr))
begin
out <= in[width-1:0];
changed <= 1'b1;
end
else
changed <= 1'b0;
endmodule // setting_reg
-26
View File
@@ -1,26 +0,0 @@
//
// Copyright 2011-2012 Ettus Research LLC
//
// This module takes the settings bus on one clock domain and crosses it over to another domain
// Typically it will be used with the input settings bus on the wishbone clock, and either
// the system or dsp clock on the output side
module settings_bus_crossclock
#(parameter FLOW_CTRL=0, parameter AWIDTH=8, parameter DWIDTH=32)
(input clk_i, input rst_i, input set_stb_i, input [AWIDTH-1:0] set_addr_i, input [DWIDTH-1:0] set_data_i,
input clk_o, input rst_o, output set_stb_o, output [AWIDTH-1:0] set_addr_o, output [DWIDTH-1:0] set_data_o, input blocked);
wire nfull, nempty;
axi_fifo_2clk #(.WIDTH(AWIDTH + DWIDTH), .SIZE(0)) settings_fifo
(.reset(rst_i),
.i_aclk(clk_i), .i_tdata({set_addr_i,set_data_i}), .i_tvalid(set_stb_i), .i_tready(nfull),
.o_aclk(clk_o), .o_tdata({set_addr_o,set_data_o}), .o_tready(set_stb_o), .o_tvalid(nempty));
assign set_stb_o = nempty & (~blocked | ~FLOW_CTRL);
endmodule // settings_bus_crossclock
-104
View File
@@ -1,104 +0,0 @@
//
// Copyright 2012 Ettus Research LLC
//
// Simple I2C core
// Settings reg map:
//
// BASE+0 control register
// byte0 - control bits, data byte, or command bits, prescaler
// byte1 - what to do? (documented in cpp file)
// write prescaler lo
// write prescaler hi
// write control
// write data
// write command
// read data
// read status
//
// Readback:
//
// byte0 has readback value based on the last read command
//
module simple_i2c_core
#(
//settings register base address
parameter BASE = 0,
//i2c line level at reset
parameter ARST_LVL = 1
)
(
//clock and synchronous reset
input clock, input reset,
//32-bit settings bus inputs
input set_stb, input [7:0] set_addr, input [31:0] set_data,
//32-bit data readback
output reg [31:0] readback,
//read is high when i2c core can begin another transaction
output reg ready,
// I2C signals
// i2c clock line
input scl_pad_i, // SCL-line input
output scl_pad_o, // SCL-line output (always 1'b0)
output scl_padoen_o, // SCL-line output enable (active low)
// i2c data line
input sda_pad_i, // SDA-line input
output sda_pad_o, // SDA-line output (always 1'b0)
output sda_padoen_o, // SDA-line output enable (active low)
//optional debug output
output [31:0] debug
);
//declare command settings register
wire [7:0] sr_what, sr_data;
wire sr_changed;
setting_reg #(.my_addr(BASE+0),.width(16)) i2c_cmd_sr(
.clk(clock),.rst(reset),.strobe(set_stb),.addr(set_addr),.in(set_data),
.out({sr_what, sr_data}),.changed(sr_changed));
//declare wb interface signals
wire [2:0] wb_addr;
wire [7:0] wb_data_mosi;
wire [7:0] wb_data_miso;
wire wb_we, wb_stb, wb_cyc;
wire wb_ack;
//create wishbone-based i2c core
i2c_master_top #(.ARST_LVL(ARST_LVL)) i2c
(.wb_clk_i(clock),.wb_rst_i(reset),.arst_i(1'b0),
.wb_adr_i(wb_addr),.wb_dat_i(wb_data_mosi),.wb_dat_o(wb_data_miso),
.wb_we_i(wb_we),.wb_stb_i(wb_stb),.wb_cyc_i(wb_cyc),
.wb_ack_o(wb_ack),.wb_inta_o(),
.scl_pad_i(scl_pad_i),.scl_pad_o(scl_pad_o),.scl_padoen_o(scl_padoen_o),
.sda_pad_i(sda_pad_i),.sda_pad_o(sda_pad_o),.sda_padoen_o(sda_padoen_o) );
//not ready between setting register and wishbone ack
always @(posedge clock) begin
if (reset || wb_ack) ready <= 1;
else if (sr_changed) ready <= 0;
end
//register wishbone data on every ack
always @(posedge clock) begin
if (wb_ack) readback <= {24'b0, wb_data_miso};
end
//assign wishbone signals
assign wb_addr = sr_what[2:0];
assign wb_stb = sr_changed;
assign wb_we = wb_stb && sr_what[3];
assign wb_cyc = wb_stb;
assign wb_data_mosi = sr_data;
endmodule //simple_i2c_core
-215
View File
@@ -1,215 +0,0 @@
//
// Copyright 2012 Ettus Research LLC
//
// Simple SPI core, the simplest, yet complete spi core I can think of
// Settings register controlled.
// 2 settings regs, control and data
// 1 32-bit readback and status signal
// Settings reg map:
//
// BASE+0 divider setting
// bits [15:0] spi clock divider
//
// BASE+1 configuration input
// bits [23:0] slave select, bit0 = slave0 enabled
// bits [29:24] num bits (1 through 32)
// bit [30] data input edge = in data bit latched on rising edge of clock
// bit [31] data output edge = out data bit latched on rising edge of clock
//
// BASE+2 input data
// Writing this register begins a spi transaction.
// Bits are latched out from bit 0.
// Therefore, load this register in reverse.
//
// Readback
// Bits are latched into bit 0.
// Therefore, data will be in-order.
module simple_spi_core
#(
//settings register base address
parameter BASE = 0,
//width of serial enables (up to 24 is possible)
parameter WIDTH = 8,
//idle state of the spi clock
parameter CLK_IDLE = 0,
//idle state of the serial enables
parameter SEN_IDLE = 24'hffffff
)
(
//clock and synchronous reset
input clock, input reset,
//32-bit settings bus inputs
input set_stb, input [7:0] set_addr, input [31:0] set_data,
//32-bit data readback
output [31:0] readback,
//read is high when spi core can begin another transaction
output ready,
//spi interface, slave selects, clock, data in, data out
output reg [WIDTH-1:0] sen,
output sclk,
output reg mosi,
input miso,
//optional debug output
output [31:0] debug
);
wire [15:0] sclk_divider;
setting_reg #(.my_addr(BASE+0),.width(16)) divider_sr(
.clk(clock),.rst(reset),.strobe(set_stb),.addr(set_addr),.in(set_data),
.out(sclk_divider),.changed());
wire [23:0] slave_select;
wire [5:0] num_bits;
wire datain_edge, dataout_edge;
setting_reg #(.my_addr(BASE+1),.width(32)) config_sr(
.clk(clock),.rst(reset),.strobe(set_stb),.addr(set_addr),.in(set_data),
.out({dataout_edge, datain_edge, num_bits, slave_select}),.changed());
wire [31:0] mosi_data;
wire trigger_spi;
setting_reg #(.my_addr(BASE+2),.width(32)) data_sr(
.clk(clock),.rst(reset),.strobe(set_stb),.addr(set_addr),.in(set_data),
.out(mosi_data),.changed(trigger_spi));
localparam WAIT_TRIG = 0;
localparam PRE_IDLE = 1;
localparam CLK_REG = 2;
localparam CLK_INV = 3;
localparam POST_IDLE = 4;
localparam IDLE_SEN = 5;
reg [2:0] state;
reg ready_reg;
assign ready = ready_reg && ~trigger_spi;
//serial clock either idles or is in one of two clock states
reg sclk_reg;
assign sclk = sclk_reg;
//serial enables either idle or enabled based on state
// IJB. One pipeline stage to break critical path from register in I/O pads.
wire sen_is_idle = (state == WAIT_TRIG) || (state == IDLE_SEN);
wire [23:0] sen24 = (sen_is_idle)? SEN_IDLE : (SEN_IDLE ^ slave_select);
reg [WIDTH-1:0] sen_reg;
always @(posedge clock)
sen_reg <= sen24[WIDTH-1:0];
always @(posedge clock)
sen <= sen_reg;
//data output shift register
// IJB. One pipeline stage to break critical path from register in I/O pads.
reg [31:0] dataout_reg;
wire [31:0] dataout_next = {dataout_reg[30:0], 1'b0};
always @(posedge clock)
mosi <= dataout_reg[31];
//data input shift register
// IJB. Two pipeline stages to break critical path from register in I/O pads.
reg miso_pipe, miso_pipe2;
always @(posedge clock) begin
miso_pipe2 <= miso;
miso_pipe <= miso_pipe2;
end
reg [31:0] datain_reg;
wire [31:0] datain_next = {datain_reg[30:0], miso_pipe};
assign readback = datain_reg;
//counter for spi clock
reg [15:0] sclk_counter;
wire sclk_counter_done = (sclk_counter == sclk_divider);
wire [15:0] sclk_counter_next = (sclk_counter_done)? 0 : sclk_counter + 1;
//counter for latching bits miso/mosi
reg [6:0] bit_counter;
wire [6:0] bit_counter_next = bit_counter + 1;
wire bit_counter_done = (bit_counter_next == num_bits);
always @(posedge clock) begin
if (reset) begin
state <= WAIT_TRIG;
sclk_reg <= CLK_IDLE;
ready_reg <= 0;
end
else begin
case (state)
WAIT_TRIG: begin
if (trigger_spi) state <= PRE_IDLE;
ready_reg <= ~trigger_spi;
dataout_reg <= mosi_data;
sclk_counter <= 0;
bit_counter <= 0;
sclk_reg <= CLK_IDLE;
end
PRE_IDLE: begin
if (sclk_counter_done) state <= CLK_REG;
sclk_counter <= sclk_counter_next;
sclk_reg <= CLK_IDLE;
end
CLK_REG: begin
if (sclk_counter_done) begin
state <= CLK_INV;
if (datain_edge != CLK_IDLE) datain_reg <= datain_next;
if (dataout_edge != CLK_IDLE && bit_counter != 0) dataout_reg <= dataout_next;
sclk_reg <= ~CLK_IDLE; //transition to rising when CLK_IDLE == 0
end
sclk_counter <= sclk_counter_next;
end
CLK_INV: begin
if (sclk_counter_done) begin
state <= (bit_counter_done)? POST_IDLE : CLK_REG;
bit_counter <= bit_counter_next;
if (datain_edge == CLK_IDLE) datain_reg <= datain_next;
if (dataout_edge == CLK_IDLE && ~bit_counter_done) dataout_reg <= dataout_next;
sclk_reg <= CLK_IDLE; //transition to falling when CLK_IDLE == 0
end
sclk_counter <= sclk_counter_next;
end
POST_IDLE: begin
if (sclk_counter_done) state <= IDLE_SEN;
sclk_counter <= sclk_counter_next;
sclk_reg <= CLK_IDLE;
end
IDLE_SEN: begin
if (sclk_counter_done) state <= WAIT_TRIG;
sclk_counter <= sclk_counter_next;
sclk_reg <= CLK_IDLE;
end
default: state <= WAIT_TRIG;
endcase //state
end
end
assign debug = {
trigger_spi, state, //4
sclk, mosi, miso, ready, //4
//sen[7:0], //8
1'b0, bit_counter[6:0], //8
sclk_counter_done, bit_counter_done, //2
sclk_counter[5:0] //6
};
endmodule //simple_spi_core