aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/sim/control
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/sim/control')
-rw-r--r--fpga/usrp3/sim/control/Makefile.srcs10
-rw-r--r--fpga/usrp3/sim/control/sim_set_rb_lib.svh169
2 files changed, 179 insertions, 0 deletions
diff --git a/fpga/usrp3/sim/control/Makefile.srcs b/fpga/usrp3/sim/control/Makefile.srcs
new file mode 100644
index 000000000..88372ddd8
--- /dev/null
+++ b/fpga/usrp3/sim/control/Makefile.srcs
@@ -0,0 +1,10 @@
+#
+# Copyright 2015 Ettus Research LLC
+#
+
+##################################################
+# Control/Readback simulation libraries
+##################################################
+SIM_CONTROL_SRCS = $(abspath $(addprefix $(BASE_DIR)/../sim/control/, \
+sim_set_rb_lib.svh \
+))
diff --git a/fpga/usrp3/sim/control/sim_set_rb_lib.svh b/fpga/usrp3/sim/control/sim_set_rb_lib.svh
new file mode 100644
index 000000000..14169a9b5
--- /dev/null
+++ b/fpga/usrp3/sim/control/sim_set_rb_lib.svh
@@ -0,0 +1,169 @@
+//
+// Copyright 2015 Ettus Research LLC
+//
+`ifndef INCLUDED_SIM_SET_RB_LIB
+`define INCLUDED_SIM_SET_RB_LIB
+
+interface settings_bus_t #(
+ parameter SR_AWIDTH = 8,
+ parameter SR_DWIDTH = 32,
+ parameter RB_AWIDTH = 8,
+ parameter RB_DWIDTH = 64,
+ parameter NUM_BUSES = 1
+)(
+ input clk
+);
+ logic [NUM_BUSES-1:0] set_stb;
+ logic [NUM_BUSES*SR_AWIDTH-1:0] set_addr;
+ logic [NUM_BUSES*SR_DWIDTH-1:0] set_data;
+ logic [NUM_BUSES-1:0] rb_stb;
+ logic [NUM_BUSES*RB_AWIDTH-1:0] rb_addr;
+ logic [NUM_BUSES*RB_DWIDTH-1:0] rb_data;
+
+ modport master (output set_stb, output set_addr, output set_data,
+ input rb_stb, output rb_addr, input rb_data);
+ modport slave (input set_stb, input set_addr, input set_data,
+ output rb_stb, input rb_addr, output rb_data);
+endinterface
+
+interface settings_bus_master #(
+ parameter SR_AWIDTH = 8,
+ parameter SR_DWIDTH = 32,
+ parameter RB_AWIDTH = 8,
+ parameter RB_DWIDTH = 64,
+ parameter NUM_BUSES = 1,
+ parameter TIMEOUT = 65535 // readback() timeout
+)(
+ input clk
+);
+ settings_bus_t #(
+ .SR_AWIDTH(SR_AWIDTH), .SR_DWIDTH(SR_DWIDTH),
+ .RB_AWIDTH(RB_AWIDTH), .RB_DWIDTH(RB_DWIDTH),
+ .NUM_BUSES(NUM_BUSES))
+ settings_bus (.clk(clk));
+
+ // Reset signals / properties used by this interface
+ task automatic reset;
+ settings_bus.set_stb = 0;
+ settings_bus.set_addr = 0;
+ settings_bus.set_data = 0;
+ settings_bus.rb_addr = 0;
+ endtask
+
+ // Push a transaction onto the settings bus
+ // Args:
+ // - set_addr: Settings bus address
+ // - set_data: Settings bus data
+ // - rb_addr: Readback bus address
+ task automatic write (
+ input logic [SR_AWIDTH-1:0] set_addr,
+ input logic [SR_DWIDTH-1:0] set_data,
+ input logic [RB_AWIDTH-1:0] rb_addr = 'd0,
+ input int bus = 0); // Optional
+ begin
+ if (clk) @(negedge clk);
+ settings_bus.set_stb[bus] = 1'b1;
+ settings_bus.set_addr[SR_AWIDTH*bus +: SR_AWIDTH] = set_addr;
+ settings_bus.set_data[SR_DWIDTH*bus +: SR_DWIDTH] = set_data;
+ settings_bus.rb_addr[RB_AWIDTH*bus +: RB_AWIDTH] = rb_addr;
+ @(negedge clk);
+ settings_bus.set_stb[bus] = 1'b0;
+ settings_bus.set_addr[SR_AWIDTH*bus +: SR_AWIDTH] = 'd0;
+ settings_bus.set_data[SR_DWIDTH*bus +: SR_DWIDTH] = 'd0;
+ settings_bus.rb_addr[RB_AWIDTH*bus +: RB_AWIDTH] = 'd0;
+ end
+ endtask
+
+ // Pull a transaction from the readback bus. Typically called immediately after write().
+ // Args:
+ // - rb_data: Readback data
+ task automatic readback (
+ output logic [RB_DWIDTH-1:0] rb_data,
+ input int bus = 0);
+ begin
+ integer timeout_counter = 0;
+ if (clk & ~settings_bus.rb_stb[bus]) @(negedge clk);
+ while (~settings_bus.rb_stb[bus]) begin
+ if (timeout_counter < TIMEOUT) begin
+ timeout_counter++;
+ end else begin
+ $error("settings_bus_t::readback(): Timeout waiting for readback strobe!");
+ break;
+ end
+ @(negedge clk);
+ end
+ rb_data = settings_bus.rb_data[RB_DWIDTH*bus +: RB_DWIDTH];
+ end
+ endtask
+
+endinterface
+
+interface settings_bus_slave #(
+ parameter SR_AWIDTH = 8,
+ parameter SR_DWIDTH = 32,
+ parameter RB_AWIDTH = 8,
+ parameter RB_DWIDTH = 64,
+ parameter NUM_BUSES = 1,
+ parameter TIMEOUT = 65535 // read() timeout
+)(
+ input clk
+);
+ settings_bus_t #(
+ .SR_AWIDTH(SR_AWIDTH), .SR_DWIDTH(SR_DWIDTH),
+ .RB_AWIDTH(RB_AWIDTH), .RB_DWIDTH(RB_DWIDTH),
+ .NUM_BUSES(NUM_BUSES))
+ settings_bus (.clk(clk));
+
+ // Reset signals / properties used by this interface
+ task automatic reset;
+ settings_bus.rb_stb = 0;
+ settings_bus.rb_data = 0;
+ endtask
+
+ // Pull a transaction from the settings bus
+ // Args:
+ // - set_addr: Settings bus address
+ // - set_data: Settings bus data
+ // - rb_addr: Readback bus address
+ task automatic read (
+ output logic [SR_AWIDTH-1:0] set_addr,
+ output logic [SR_DWIDTH-1:0] set_data,
+ output logic [RB_AWIDTH-1:0] rb_addr,
+ input int bus = 0);
+ begin
+ integer timeout_counter = 0;
+ while (~settings_bus.set_stb[bus]) begin
+ @(negedge clk);
+ if (timeout_counter < TIMEOUT) begin
+ timeout_counter++;
+ end else begin
+ $error("settings_bus_t::read(): Timeout waitling for settings bus strobe!");
+ break;
+ end
+ end
+ set_addr = settings_bus.set_addr[SR_AWIDTH*bus +: SR_AWIDTH];
+ set_data = settings_bus.set_data[SR_DWIDTH*bus +: SR_DWIDTH];
+ rb_addr = settings_bus.rb_addr[RB_AWIDTH*bus +: RB_AWIDTH];
+ @(negedge clk);
+ end
+ endtask
+
+ // Push a transaction onto the readback bus, typically called immediately after read()
+ // Args:
+ // - rb_data: Readback data
+ task writeback (
+ input logic [RB_AWIDTH-1:0] rb_data,
+ input int bus = 0);
+ begin
+ if (clk & ~settings_bus.set_stb[bus]) @(negedge clk);
+ settings_bus.rb_stb[bus] = 1'b1;
+ settings_bus.rb_data[RB_DWIDTH*bus +: RB_DWIDTH] = rb_data;
+ @(negedge clk);
+ settings_bus.rb_stb[bus] = 1'b0;
+ settings_bus.rb_data[RB_DWIDTH*bus +: RB_DWIDTH] = 'd0;
+ end
+ endtask
+
+endinterface
+
+`endif \ No newline at end of file