aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/sim/axi/sim_axis_lib.svh
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/sim/axi/sim_axis_lib.svh')
-rw-r--r--fpga/usrp3/sim/axi/sim_axis_lib.svh219
1 files changed, 219 insertions, 0 deletions
diff --git a/fpga/usrp3/sim/axi/sim_axis_lib.svh b/fpga/usrp3/sim/axi/sim_axis_lib.svh
new file mode 100644
index 000000000..bdee113de
--- /dev/null
+++ b/fpga/usrp3/sim/axi/sim_axis_lib.svh
@@ -0,0 +1,219 @@
+//
+// Copyright 2016 Ettus Research
+//
+`ifndef INCLUDED_SIM_AXIS_LIB
+`define INCLUDED_SIM_AXIS_LIB
+
+interface axis_t #(parameter DWIDTH = 32, parameter NUM_STREAMS = 1)(input clk);
+ logic [NUM_STREAMS*DWIDTH-1:0] tdata;
+ logic [NUM_STREAMS-1:0] tvalid;
+ logic [NUM_STREAMS-1:0] tlast;
+ logic [NUM_STREAMS-1:0] tready;
+
+ modport master (
+ output tdata,
+ output tvalid,
+ output tlast,
+ input tready);
+
+ modport slave (
+ input tdata,
+ input tvalid,
+ input tlast,
+ output tready);
+endinterface
+
+// Interface to push data onto a master AXI-stream bus
+interface axis_master #(parameter DWIDTH = 32, parameter NUM_STREAMS = 1)(input clk);
+ axis_t #(.DWIDTH(DWIDTH), .NUM_STREAMS(NUM_STREAMS)) axis(.clk(clk));
+
+ // Check that stream is actually in use
+ function void check_stream(int stream);
+ assert (stream < NUM_STREAMS) else
+ $error("axis_master::check_stream(): Tried to perform operation on unused stream %0d", stream);
+ endfunction
+
+ // Reset signals / properties used by this interface
+ task automatic reset;
+ begin
+ axis.tvalid = 0;
+ axis.tlast = 0;
+ axis.tdata = 0;
+ end
+ endtask
+
+ // Push a word onto the AXI-Stream bus and wait for it to transfer
+ // Args:
+ // - word: The data to push onto the bus
+ // - eop (optional): End of packet (asserts tlast)
+ // - stream: Stream to use (Optional)
+ task automatic push_word (
+ input logic [DWIDTH-1:0] word,
+ input logic eop = 1'b0,
+ input int stream = 0);
+ begin
+ check_stream(stream);
+ if (clk) @(negedge clk); // Align with negative edge
+ axis.tvalid[stream] = 1;
+ axis.tlast[stream] = eop;
+ axis.tdata[DWIDTH*stream +: DWIDTH] = word;
+ @(posedge clk); // Put sample on data bus
+ while(~axis.tready[stream]) @(posedge clk); // Wait until receiver ready
+ @(negedge clk); // Put sample on data bus
+ axis.tvalid[stream] = 0;
+ axis.tlast[stream] = 0;
+ end
+ endtask
+
+ // Push a bubble cycle onto the AXI-Stream bus
+ // Args:
+ // - stream: Stream to use (Optional)
+ task automatic push_bubble (input int stream = 0);
+ begin
+ check_stream(stream);
+ axis.tvalid[stream] = 0;
+ @(negedge clk);
+ end
+ endtask
+
+ // Push a packet with random data onto to the AXI Stream bus
+ // Args:
+ // - num_samps: Packet size.
+ task automatic push_rand_pkt (
+ input int num_samps,
+ input int stream = 0);
+ begin
+ check_stream(stream);
+ if (clk) @(negedge clk);
+ repeat(num_samps-1) begin
+ push_word({(((DWIDTH-1)/32)+1){$random}}, 0, stream);
+ end
+ push_word({(((DWIDTH-1)/32)+1){$random}}, 1, stream);
+ end
+ endtask
+
+ // Push a packet with a ramp on to the AXI Stream bus
+ // Args:
+ // - num_samps: Packet size.
+ // - ramp_start: Start value for the ramp
+ // - ramp_inc: Increment per clock cycle
+ // - stream: Stream to use (Optional)
+ task automatic push_ramp_pkt (
+ input integer num_samps,
+ input [DWIDTH-1:0] ramp_start,
+ input [DWIDTH-1:0] ramp_inc,
+ input int stream = 0);
+ begin
+ automatic integer counter = 0;
+ check_stream(stream);
+ if (clk) @(negedge clk);
+ repeat(num_samps-1) begin
+ push_word(ramp_start+(counter*ramp_inc), 0, stream);
+ counter = counter + 1;
+ end
+ push_word(ramp_start+(counter*ramp_inc), 1, stream);
+ end
+ endtask
+
+endinterface
+
+
+// Interface to push data onto a master AXI-stream bus
+interface axis_slave #(parameter DWIDTH = 32, parameter NUM_STREAMS = 1)(input clk);
+ axis_t #(.DWIDTH(DWIDTH), .NUM_STREAMS(NUM_STREAMS)) axis(.clk(clk));
+
+ // Check that stream is actually in use
+ function void check_stream(int stream);
+ assert (stream < NUM_STREAMS) else
+ $error("axis_slave::check_stream(): Tried to perform operation on unused stream %0d", stream);
+ endfunction
+
+ // Reset signals / properties used by this interface
+ task automatic reset;
+ begin
+ axis.tready = 0;
+ end
+ endtask
+
+ // Pull a word from the AXI Stream bus and
+ // return the data and last
+ // Args:
+ // - word: The data pulled from the bus
+ // - eop: End of packet (tlast)
+ // - stream: Stream to use (Optional)
+ task automatic pull_word (
+ output logic [DWIDTH-1:0] word,
+ output logic eop,
+ input int stream = 0);
+ begin
+ check_stream(stream);
+ if (clk) @(negedge clk);
+ axis.tready[stream] = 1;
+ while(~axis.tvalid[stream]) @(posedge clk);
+ word = axis.tdata[DWIDTH*stream +: DWIDTH];
+ eop = axis.tlast[stream];
+ @(negedge clk);
+ axis.tready[stream] = 0;
+ end
+ endtask
+
+ // Wait for a sample to be transferred on the AXI Stream
+ // bus and return the data and last. Note, this task only
+ // observes the bus and does not affect the AXI control
+ // signals.
+ // Args:
+ // - word: The data pulled from the bus
+ // - eop: End of packet (tlast)
+ // - stream: Stream to use (Optional)
+ task automatic copy_word (
+ output logic [DWIDTH-1:0] word,
+ output logic eop,
+ input int stream = 0);
+ begin
+ check_stream(stream);
+ while(~(axis.tready[stream]&axis.tvalid[stream])) @(posedge clk); // Wait until sample is transferred
+ word = axis.tdata[DWIDTH*stream +: DWIDTH];
+ eop = axis.tlast[stream];
+ @(negedge clk);
+ end
+ endtask
+
+ // Wait for a bubble cycle on the AXI Stream bus
+ // Args:
+ // - stream: Stream to use (Optional)
+ task automatic wait_for_bubble (
+ input int stream = 0);
+ begin
+ check_stream(stream);
+ while(axis.tready[stream]&axis.tvalid[stream]) @(posedge clk);
+ @(negedge clk);
+ end
+ endtask
+
+ // Wait for a packet to finish on the bus
+ // Args:
+ // - stream: Stream to use (Optional)
+ task automatic wait_for_pkt (
+ input int stream = 0);
+ begin
+ check_stream(stream);
+ while(~(axis.tready[stream]&axis.tvalid[stream]&axis.tlast[stream])) @(posedge clk);
+ @(negedge clk);
+ end
+ endtask
+
+ // Drop a word on the bus
+ // Args:
+ // - stream: Stream to use (Optional)
+ task automatic drop_word (
+ input int stream = 0);
+ begin
+ logic [DWIDTH-1:0] dropped_word;
+ logic dropped_eop;
+ pull_word(dropped_word, dropped_eop, stream);
+ end
+ endtask
+
+endinterface
+
+`endif \ No newline at end of file