1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 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
|