Commit 3dab222c authored by Dimitris Lampridis's avatar Dimitris Lampridis

Merge branch 'feature/generalize' into proposed_master

parents 822f2b34 563d4184
Subproject commit a60eac03a83cf136a5d3effac04346df874a24b0
Subproject commit afdb951621faa7c9f797b3f22b8ee3d948e6b219
......@@ -34,8 +34,8 @@ class WrtdAlarm extends WrtdRepCap;
protected int repeat_count;
protected uint32_t period_ns;
function new ( int core, int index, string name = "" );
super.new ( core, index, name );
function new ( string name = "" );
super.new ( name );
this.setup_time = new();
this.ev.ts = new();
this.ev.id = new();
......
......@@ -36,13 +36,18 @@
`define WRTD_IO_MSG_WORD_SIZE 2
`define WRTD_CFG_MSG_WORD_SIZE 5
`define WRTD_ROOT_WORD_SIZE 13
`define WRTD_ROOT_WORD_SIZE 12
`define WRTD_RULE_WORD_SIZE 40
`define WRTD_ALRM_WORD_SIZE 15
`define WRTD_DEST_CPU_LOCAL 'hfe
`define WRTD_DEST_CH_NET 'hff
`define WRTD_CAP_NET_RX 1
`define WRTD_CAP_NET_TX 2
`define WRTD_CAP_LOCAL_RX 4
`define WRTD_CAP_LOCAL_TX 8
enum {
WRTD_ACTION_GET_CONFIG,
WRTD_ACTION_READW,
......@@ -211,44 +216,15 @@ typedef struct {
typedef struct {
uint32_t addr;
uint32_t fw_id;
uint32_t nbr_alarms;
uint32_t alarms_addr;
uint32_t nbr_rules;
uint32_t capabilities;
uint32_t rules_addr;
uint32_t nbr_devs;
uint32_t devs_addr[4];
uint32_t nbr_channels[4];
uint32_t channel_dir[4];
} wrtd_root;
typedef struct {
int core;
int index;
int ch_en;
} wrtd_dev;
typedef struct {
string name;
uint32_t dir;
uint32_t nbr_chs;
string channels[];
/* -----\/----- EXCLUDED -----\/-----
enum wrtd_status (*configure)(struct wrtd_dev *wrtd,
unsigned cpu, unsigned dev,
unsigned int mask);
-----/\----- EXCLUDED -----/\----- */
} wrtd_mt_device;
typedef struct {
uint32_t fw_id;
uint32_t nbr_devices;
wrtd_mt_device devices[`WRTD_MAX_DEVS];
} wrtd_mt_cpu_config;
typedef struct {
uint32_t mt_app_id;
uint32_t nbr_cpus;
uint32_t tx_cpu;
uint32_t rx_cpu;
wrtd_mt_cpu_config cpus[`WRTD_MAX_CPUS];
} wrtd_mt_config;
`endif // `ifndef __WRTD_DEFINE_INCLUDED
......@@ -39,9 +39,7 @@ class WrtdDrv;
protected uint32_t nbr_cpus;
protected uint32_t free_rule_slots[];
protected uint32_t hmq_words[];
protected wrtd_mt_config cfg;
protected wrtd_root roots[];
protected wrtd_dev devices[$];
protected WrtdRepCapCollection rules;
protected WrtdRepCapCollection alarms;
......@@ -75,39 +73,12 @@ class WrtdDrv;
WrtdAlarm new_alarm;
wrtd_dev new_dev;
uint32_t data[];
this.ready = 0;
mt.init ( );
// TODO: replace with non-hardcoded values
this.cfg.mt_app_id = 'h115790d1;
this.cfg.nbr_cpus = 1;
this.cfg.tx_cpu = 0;
this.cfg.rx_cpu = 0;
this.cfg.cpus[0].fw_id = 'h35b0;
this.cfg.cpus[0].nbr_devices = 2;
this.cfg.cpus[0].devices[0].name = "FMC ADCin 5CH";
this.cfg.cpus[0].devices[0].dir = WRTD_DIR_INPUT;
this.cfg.cpus[0].devices[0].nbr_chs = 5;
this.cfg.cpus[0].devices[0].channels = new[5];
this.cfg.cpus[0].devices[0].channels[0] = "ADCI1";
this.cfg.cpus[0].devices[0].channels[1] = "ADCI2";
this.cfg.cpus[0].devices[0].channels[2] = "ADCI3";
this.cfg.cpus[0].devices[0].channels[3] = "ADCI4";
this.cfg.cpus[0].devices[0].channels[4] = "ADCI5";
this.cfg.cpus[0].devices[1].name = "FMC ADCout";
this.cfg.cpus[0].devices[1].dir = WRTD_DIR_OUTPUT;
this.cfg.cpus[0].devices[1].nbr_chs = 1;
this.cfg.cpus[0].devices[1].channels = new[1];
this.cfg.cpus[0].devices[1].channels[0] = "ADCO1";
this.nbr_cpus = mt.rom.getCoreCount ( );
this.free_rule_slots = new[this.nbr_cpus];
......@@ -135,9 +106,12 @@ class WrtdDrv;
while ( cpu_ready == 0 )
begin
val = 0;
mt.get_single_cpu_notification ( 0, val );
if ( val == TRTL_CPU_NOTIFY_MAIN )
cpu_ready = 1;
if ( mt.pending_cpu_notifications ( i ) != 0 )
begin
mt.get_single_cpu_notification ( i, val );
if ( val == TRTL_CPU_NOTIFY_MAIN )
cpu_ready = 1;
end
# 1us;
end
// retrieve address of root
......@@ -145,17 +119,23 @@ class WrtdDrv;
this.roots[i].addr = data[0];
// retrieve root
msg_readw ( i, this.roots[i].addr, `WRTD_ROOT_WORD_SIZE, data );
this.roots[i].nbr_rules = ( data[1] & 'h00ff0000 ) >> 16;
this.roots[i].nbr_alarms = ( data[1] & 'h0000ff00 ) >> 8;
this.roots[i].nbr_devs = ( data[1] & 'h000000ff ) >> 0;
this.roots[i].devs_addr[0:3] = data[4:7];
this.roots[i].rules_addr = data[8];
this.roots[i].alarms_addr = data[9];
this.roots[i].fw_id = data[1];
this.roots[i].capabilities = ( data[2] & 'hff000000 ) >> 24;
this.roots[i].nbr_rules = ( data[2] & 'h00ff0000 ) >> 16;
this.roots[i].nbr_alarms = ( data[2] & 'h0000ff00 ) >> 8;
this.roots[i].nbr_devs = ( data[2] & 'h000000ff ) >> 0;
for ( j = 0; j < 4; j++)
begin
this.roots[i].nbr_channels[j] = ( data[5] >> j*8 ) & 'hff;
this.roots[i].channel_dir[j] = ( data[6] >> j*8 ) & 'hff;
end
this.roots[i].rules_addr = data[7];
this.roots[i].alarms_addr = data[8];
// init free rule slots
this.free_rule_slots[i] = this.roots[i].nbr_rules;
// turn on all logging if enabled
if ( this.enable_logging )
msg_writew ( i, this.roots[i].addr + 12, 1, { data[3] | 32'hff } );
msg_writew ( i, this.roots[i].addr + 16, 1, { data[4] | 32'hff } );
end
// initialise rules
......@@ -163,7 +143,7 @@ class WrtdDrv;
for ( i = 0; i < this.nbr_cpus; i++ )
for ( j = 0; j < this.roots[i].nbr_rules; j++ )
begin
new_rule = new ( i, j, this.name );
new_rule = new ( this.name );
this.rules.collection.push_back ( new_rule );
end
......@@ -172,29 +152,14 @@ class WrtdDrv;
for ( i = 0; i < this.nbr_cpus; i++ )
for ( j = 0; j < this.roots[i].nbr_alarms; j++ )
begin
new_alarm = new ( i, j, this.name );
new_alarm = new ( this.name );
this.alarms.collection.push_back ( new_alarm );
end
// initialise devices
this.devices.delete();
for ( i = 0; i < this.nbr_cpus; i++ )
for ( j = 0; j < this.roots[i].nbr_devs; j++ )
begin
new_dev.core = i;
new_dev.index = j;
new_dev.ch_en = 0;
this.devices.push_back ( new_dev );
end
// TODO remove hard-coded ADC init
adc_init ();
this.ready = 1;
end
begin
while ( this.ready == 0 )
while ( i != this.nbr_cpus )
begin
mt.update ( );
# 1us;
......@@ -202,6 +167,8 @@ class WrtdDrv;
end
join
this.ready = 1;
endtask // init
task msg_get_config ( int core, ref uint32_t data[] );
......@@ -293,16 +260,6 @@ class WrtdDrv;
endtask // msg_writew
task adc_init ( );
uint32_t addr;
uint32_t data[1];
addr = this.roots[0].devs_addr[0] + 'h4;
data[0] = 'h10f;
msg_writew ( 0, addr, 1, data );
endtask // adc_init
task add_rule ( string rep_cap_id );
int idx;
idx = this.rules.add ( rep_cap_id );
......@@ -352,18 +309,50 @@ class WrtdDrv;
$cast ( rule, this.rules.collection[idx] );
hash = wrtd_gen_hash ( rule.get_src() ) % this.rules.collection.size();
hash = wrtd_gen_hash ( rule.get_src() ) % this.roots[core].nbr_rules;
core = rule.get_core ( );
addr = this.roots[core].rules_addr + hash * `WRTD_RULE_WORD_SIZE * 4;
data = rule.data_pack ( );
msg_writew ( core, addr, `WRTD_RULE_WORD_SIZE, data );
endtask // write_rule
function void map_local_channel_to_cpu ( string ch_id, int ch_dir,
ref int core, ref int ch_idx );
int i, j, k, idx_in, idx_out, dev_dir;
string dev_id;
idx_in = 1;
idx_out = 1;
core = -1;
ch_idx = -1;
for ( i = 0; i < this.nbr_cpus; i++ )
for ( j = 0; j < this.roots[i].nbr_devs; j++ )
begin
dev_dir = this.roots[i].channel_dir[j];
for ( k = 0; k < this.roots[i].nbr_channels[j]; k++ )
begin
if ( dev_dir == WRTD_DIR_INPUT )
dev_id = $sformatf ( "LC-I%0d", idx_in++ );
else
dev_id = $sformatf ( "LC-O%0d", idx_out++ );
if ( ( dev_dir == ch_dir ) && ( dev_id == ch_id ) )
begin
core = i;
ch_idx = k;
return;
end
end
end
endfunction // map_local_channel_to_cpu
task enable_rule ( string rep_cap_id );
int idx;
int idx, src_cpu, dst_cpu, src_ch, dst_ch;
string id;
uint32_t src_cpu;
WrtdRule rule;
......@@ -374,22 +363,65 @@ class WrtdDrv;
$cast ( rule, this.rules.collection[idx] );
rule.set_enable ( );
// TODO, replace hard-coding
src_cpu = 0;
if ( this.free_rule_slots[src_cpu] == 0 )
$error ( "no more available free rule slots on CPU %d", src_cpu );
this.free_rule_slots[src_cpu] -= 1;
rule.set_dest_cpu ( `WRTD_DEST_CPU_LOCAL );
id = rule.get_dst ( );
if ( id == "ADCO1" )
rule.set_dest_ch ( 0 );
else
rule.set_dest_ch ( `WRTD_DEST_CH_NET );
/* Place the rule on the same CPU as the input source.
If source is network, src_cpu = -1 for now */
map_local_channel_to_cpu ( rule.get_src(), WRTD_DIR_INPUT, src_cpu, src_ch );
// TODO: check if rule source is alarm
/* Set destination cpu and channel */
map_local_channel_to_cpu ( rule.get_dst(), WRTD_DIR_OUTPUT, dst_cpu, dst_ch );
if ( dst_cpu >= 0 ) // local output device
begin
/* If source is network message and this cpu can receive from
network, set cpu affinity to this cpu */
if ( ( src_cpu == -1 ) && ( this.roots[dst_cpu].capabilities & `WRTD_CAP_NET_RX ) )
src_cpu = dst_cpu;
/* Otherwise find the first cpu that is capable of net RX */
else
for ( src_cpu = 0; src_cpu < this.nbr_cpus; src_cpu++ )
if ( this.roots[src_cpu].capabilities & `WRTD_CAP_NET_RX )
break;
end
else // network destination
begin
dst_ch = `WRTD_DEST_CH_NET;
/* If source cpu can also send to
network, set dest cpu affinity to that cpu */
if ( ( src_cpu >= 0 ) && ( this.roots[src_cpu].capabilities & `WRTD_CAP_NET_TX ) )
dst_cpu = src_cpu;
/* Otherwise find the first cpu that is capable of net TX */
else
for ( dst_cpu = 0; dst_cpu < this.nbr_cpus; dst_cpu++ )
if ( this.roots[dst_cpu].capabilities & `WRTD_CAP_NET_TX )
break;
end
// TODO: handle network to network events
if ( ( src_cpu < 0 ) || ( dst_cpu < 0 ) ||
( src_cpu >= this.nbr_cpus ) || ( dst_cpu >= this.nbr_cpus ) )
$error ( "cannot determine source and/or destination cpu for rule" );
/* If the same CPU can handle both input and output, use special value so that
the firmware will know not to forward this event to another CPU (it does not
know its own index) */
if ( src_cpu == dst_cpu )
dst_cpu = `WRTD_DEST_CPU_LOCAL;
// TODO: handle free_rule_slots per cpu
rule.set_core ( src_cpu );
rule.set_dest_cpu ( dst_cpu );
rule.set_dest_ch ( dst_ch );
rule.set_enable ( 1 );
// TODO: properly recalculate and rewrite rules
write_rule ( idx );
endtask // enable_rule
// TODO: properly support alarms
task add_alarm ( string rep_cap_id );
int idx;
idx = this.alarms.add ( rep_cap_id );
......@@ -415,7 +447,7 @@ class WrtdDrv;
$error ( "cannot write alarm with negative index" );
core = this.alarms.collection[idx].get_core ( );
index = this.alarms.collection[idx].get_index ();
//index = this.alarms.collection[idx].get_index ();
addr = this.roots[core].alarms_addr + index * `WRTD_ALRM_WORD_SIZE * 4;
data = this.alarms.collection[idx].data_pack( );
......
......@@ -31,12 +31,9 @@ virtual class WrtdRepCap;
protected string name;
protected WrtdId rep_cap_id;
protected int core;
protected int index;
protected int enabled;
function new ( int core, int index, string name = "" );
this.core = core;
this.index = index;
function new ( string name = "" );
this.name = name;
this.rep_cap_id = new();
clear();
......@@ -44,7 +41,7 @@ virtual class WrtdRepCap;
function void clear ( );
this.rep_cap_id.clear();
this.enabled = 0;
this.enabled = 0;
endfunction // clear
task mdisplay ( string str );
......@@ -60,9 +57,9 @@ virtual class WrtdRepCap;
return this.core;
endfunction // get_core
function int get_index ( );
return this.index;
endfunction // get_index
function void set_core ( int core );
this.core = core;
endfunction // set_core
function string get_rep_cap_id ( );
return this.rep_cap_id.get();
......@@ -84,8 +81,11 @@ virtual class WrtdRepCap;
return ( this.enabled > 0 );
endfunction // is_enabled
function void set_enable ( );
this.enabled = 1;
function void set_enable ( int enable );
if ( enable > 0)
this.enabled = 1;
else
this.enabled = 0;
endfunction // set_enable
function void set_disable ( );
......
......@@ -53,8 +53,8 @@ class WrtdRule extends WrtdRepCap;
protected WrtdTstamp hold_off;
protected uint32_t seq;
function new ( int core, int index, string name = "" );
super.new ( core, index, name );
function new ( string name = "" );
super.new ( name );
this.src = new();
this.dst = new();
this.rx_last = new();
......
......@@ -69,7 +69,7 @@ module main;
devA = new (accA, MT_BASE, MtIrqMonitorA, "DUT:A");
devA.init();
devA.add_rule ( "rule0" );
devA.set_rule ( "rule0", "ADCI5", "NET0", 0 );
devA.set_rule ( "rule0", "LC-I5", "NET0", 0 );
devA.enable_rule ( "rule0" );
// Config DUTA to trigger on external trigger and get 64 samples
......@@ -85,7 +85,8 @@ module main;
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH3_SAT, 'h7fff);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_CH4_SAT, 'h7fff);
val = (1'b1 << `FMC_ADC_100MS_CSR_TRIG_EN_EXT_OFFSET);
val = (1'b1 << `FMC_ADC_100MS_CSR_TRIG_EN_EXT_OFFSET);
val |= (1'b1 << `FMC_ADC_100MS_CSR_TRIG_EN_FWD_EXT_OFFSET);
accA.write(`ADC_CSR_BASE + `ADDR_FMC_ADC_100MS_CSR_TRIG_EN, val);
expected = 'h39;
......@@ -103,7 +104,7 @@ module main;
devB = new (accB, MT_BASE, MtIrqMonitorB, "DUT:B");
devB.init();
devB.add_rule ( "rule0" );
devB.set_rule ( "rule0", "NET0", "ADCO1", 50000 );
devB.set_rule ( "rule0", "NET0", "LC-O1", 50000 );
devB.enable_rule ( "rule0" );
// Config DUTB to trigger on WRTD and get 64 samples
......
......@@ -26,7 +26,6 @@
`timescale 1ns/1ps
`include "vhd_wishbone_master.svh"
`include "simdrv_defs.svh"
module simple_tdc_driver
(
......@@ -78,7 +77,7 @@ module simple_tdc_driver
now = $time;
if (t.ts <= now)
$display("TDC: pulse in the past (%t now=%t)!", t.ts, now);
$display("[DUT] <%t> TDC: pulse in the past (%t now=%t)!", $realtime, t.ts, now);
else
begin
const int fifo_n = t.channel / 4;
......@@ -91,8 +90,8 @@ module simple_tdc_driver
val[17] = 1'b1;
val[16:0] = (t.ts - start_time) / 81ps;
$display("TDC: pulse at %t for channel %0d (start #0x%x, time_data 0x%x, start_time %t)",
t.ts, t.channel, start, val[16:0], start_time);
$display("[DUT] <%t> TDC: pulse at %t for channel %0d (start #0x%x, time_data 0x%x, start_time %t)",
$realtime, t.ts, t.channel, start, val[16:0], start_time);
fifos[t.channel / 4].push_back(val);
end
......@@ -137,7 +136,7 @@ module simple_tdc_driver
rdata <= start01;
end
else begin
$display("invalid ACAM read 0x%x", addr);
$display("[DUT] <%t> invalid ACAM read 0x%x", $realtime, addr);
end
end
end
......@@ -146,8 +145,9 @@ module simple_tdc_driver
assign ef2 = fifos[1].size() == 0;
always@(negedge wr) begin
// Unused in simulation mode.
$display("invalid ACAM write 0x%x <- 0x%08x", addr, data);
/* Not supposed to have writes to the ACAM if
firmware is compiled with -DSIMULATION */
$display("[DUT] <%t> invalid ACAM write 0x%x <- 0x%08x", $realtime, addr, data);
end
endmodule // simple_tdc_driver
......@@ -212,11 +212,11 @@ endmodule // simple_fdelay_mon
module dut_env
(
IVHDWishboneMaster host,
output sfp_txp_o, sfp_txn_o,
output clk_sys, rst_sys_n,
sfp_txp_o, sfp_txn_o,
input sfp_rxp_i, sfp_rxn_i
);
reg clk_125m_pll = 0;
reg clk_125m_gtp = 0;
reg clk_20m_vcxo = 0;
......@@ -240,6 +240,9 @@ module dut_env
wire sfp_scl, sfp_sda, sfp_sda_en;
assign clk_sys = DUT.clk_sys_62m5;
assign rst_sys_n = DUT.rst_sys_62m5_n;
//---------------------------------------------------------------------------
// The DUT
//---------------------------------------------------------------------------
......@@ -248,13 +251,12 @@ module dut_env
(
.g_SIMULATION (1),
.g_SIM_BYPASS_VME (1),
.g_WRPC_INITF ("../../../dependencies/wr-cores/bin/wrpc/wrc_phy8_sim.bram"),
.g_MT_CPU0_INITF ("../../../software/firmware/tdc/wrtd-rt-tdc.bram"),
.g_MT_CPU1_INITF ("../../../software/firmware/fd/wrtd-rt-fd.bram")
.g_WRPC_INITF ("../../../dependencies/wr-cores/bin/wrpc/wrc_phy8_sim.bram")
)
DUT
(
.rst_n_i (1'b1),
.vme_sysreset_n_i (1'b1),
.clk_125m_pllref_p_i (clk_125m_pll),
.clk_125m_pllref_n_i (~clk_125m_pll),
.clk_125m_gtp_p_i (clk_125m_gtp),
......@@ -367,10 +369,9 @@ module dut_env
push_pulse(1, start + 30us);
push_pulse(2, start + 50us);
#(start + 200us) ;
#(start + 1000us) ;
// Should have been finished by the FD monitor.
$fatal(1, "FAILED");
end
initial begin
......
//
// unit name: ListDriver
//
// description: A SystemVerilog Class to provide an abstraction of a complete
// LIST system.
//
//------------------------------------------------------------------------------
// Copyright CERN 2018
//------------------------------------------------------------------------------
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 2.0 (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-2.0.
// Unless required by applicable law or agreed to in writing, software,
// hardware and materials distributed under this License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.
//------------------------------------------------------------------------------
`ifndef __LIST_DRIVER_INCLUDED
`define __LIST_DRIVER_INCLUDED
`include "mock_turtle_driver.svh"
`define LIST_HMQ_LOG_SLOT 0
typedef struct {
uint32_t system;
uint32_t source_port;
uint32_t trigger;
} list_trig_id;
typedef struct {
uint64_t seconds;
uint32_t ticks;
uint32_t frac;
} wr_timestamp;
typedef enum {
NOT_MISSED = -1,
DEAD_TIME = 0,
OVERFLOW = 1,
NO_WR = 2,
TIMEOUT = 3
} list_log_miss_reason;
typedef enum {
RAW = (1 << 0),
SENT = (1 << 1),
PROMISC = (1 << 2),
FILTERED = (1 << 3),
EXECUTED = (1 << 4),
MISSED = (1 << 5)
} list_log_type;
typedef enum {
LIST_IN = 2,
LIST_OUT = 6
} list_log_origin;
class ListLogMsg;
list_log_origin origin;
list_log_type ltype;
uint32_t seq;
int channel;
list_trig_id id;
wr_timestamp ts;
list_log_miss_reason miss_reason;
function new ( MQueueMsg msg );
this.origin = list_log_origin'(msg.header.msg_id);
this.ltype = list_log_type'(msg.data[0]);
this.seq = msg.data[1];
this.channel = msg.data[2];
this.id.system = msg.data[3];
this.id.source_port = msg.data[4];
this.id.trigger = msg.data[5];
this.ts.seconds = (msg.data[7] << 32) | msg.data[6];
this.ts.ticks = msg.data[8];
this.ts.frac = msg.data[9];
if ( this.ltype == MISSED )
this.miss_reason = list_log_miss_reason'(msg.data[10]);
else
this.miss_reason = NOT_MISSED;
endfunction // new
function string tostring ();
string str;
str = $sformatf ( {"[%8s] TYPE: %8s, SEQ: %3d, CHANNEL: %2d, ",
"TRIG_SYS: %0d, TRIG_PORT: %0d, TRIG_ID: %0d, ",
"TS_SEC: %2d, TS_TICKS: %10dns" },
origin.name(), ltype.name(), seq, channel,
id.system, id.source_port, id.trigger,
ts.seconds, ts.ticks * 8);
if ( ts.frac > 0 )
str = { str, $sformatf ( ", TS_FRAC: %0d", ts.frac ) };
if ( miss_reason != NOT_MISSED )
str = { str, $sformatf ( ", MISS_REASON: %s", miss_reason ) };
return str;
endfunction // tostring
endclass // ListLogMsg
class ListDriver;
protected string name;
protected int hmq_log_slot;
protected MockTurtleDriver mt;
function new ( CBusAccessor acc, uint64_t base,
vIMockTurtleIRQ irq, string name = "" );
this.name = name;
this.mt = new (acc, base, irq, name);
endfunction // new
task mdisplay ( string str );
string tmp;
if (this.name == "")
tmp = $sformatf("<%t> %s", $realtime, str);
else
tmp = $sformatf("[%s] <%t> %s", this.name, $realtime, str);
$display (tmp);
endtask // mdisplay
task init ( string cpu0_fw = "",
string cpu1_fw = "");
mt.init ( );
mt.enable_console_irq ( 0, 1 );
mt.enable_console_irq ( 1, 1 );
mt.enable_hmqi_irq ( 0, 0, 1 );
mt.enable_hmqi_irq ( 1, 0, 1 );
mt.reset_core ( 0, 1 );
mt.reset_core ( 1, 1 );
if ( cpu0_fw != "" )
mt.load_firmware ( 0, cpu0_fw, 1'b0 );
if ( cpu1_fw != "" )
mt.load_firmware ( 0, cpu1_fw, 1'b0 );
mt.reset_core ( 0, 0 );
mt.reset_core ( 1, 0 );
endtask // init
task check_log_queue ( int core );
ListLogMsg log_msg;
MQueueMsg msg;
msg = new ( core, `LIST_HMQ_LOG_SLOT );
while ( mt.hmq_pending_messages ( core, `LIST_HMQ_LOG_SLOT ) )
begin
mt.hmq_receive_message ( msg );
log_msg = new ( msg );
mdisplay ( log_msg.tostring ( ) );
end
endtask // check_log_queue
task update ( );
mt.update ( );
fork
check_log_queue ( 0 );
check_log_queue ( 1 );
join
endtask // update
endclass // ListDriver
`endif // `ifndef __LIST_DRIVER_INCLUDED
......@@ -6,7 +6,7 @@
//
// unit name: main
//
// description: Testbench for the SPEC150T-based FMC ADC WRTD reference design.
// description: Testbench for the SVEC-based FMC TDC+FD WRTD reference design.
//
//------------------------------------------------------------------------------
// Copyright CERN 2018-2019
......@@ -27,50 +27,75 @@
`include "wrtd_driver.svh"
`include "vhd_wishbone_master.svh"
`define TDC_DIRECT_BASE 'h18000
module main;
wire clk_sys, rst_sys_n;
wire sfp_txp, sfp_txn, sfp_rxp, sfp_rxn;
IVHDWishboneMaster host (DUT.DUT.clk_sys_62m5, DUT.DUT.rst_sys_62m5_n);
IVHDWishboneMaster host (clk_sys, rst_sys_n);
dut_env DUT (host, sfp_txp, sfp_txn, sfp_rxp, sfp_rxn);
dut_env DUT (host, clk_sys, rst_sys_n, sfp_txp, sfp_txn, sfp_rxp, sfp_rxn);
IMockTurtleIRQ MtIrqMonitor (`MT_ATTACH_IRQ(DUT.DUT.cmp_mock_turtle));
assign sfp_rxp = sfp_txp;
assign sfp_rxn = sfp_txn;
CBusAccessor acc;
WrtdDrv dev;
const uint64_t MT_BASE = 'h0002_0000;
CBusAccessor acc;
initial begin
$timeformat (-6, 3, "us", 10);
@(posedge DUT.DUT.rst_sys_62m5_n);
@(posedge DUT.DUT.clk_sys_62m5);
#10us;
acc = host.get_accessor();
acc.set_default_xfer_size(4);
dev = new (acc, MT_BASE, MtIrqMonitor, "DUT");
dev.init();
dev.add_rule ( "rule0" );
dev.set_rule ( "rule0", "NET0", "FD", 100000 );
dev.set_rule ( "rule0", "NET0", "LC-O1", 150000 );
dev.enable_rule ( "rule0" );
dev.add_rule ( "rule1" );
dev.set_rule ( "rule1", "TDC", "NET0", 0 );
dev.set_rule ( "rule1", "NET1", "LC-O2", 150000 );
dev.enable_rule ( "rule1" );
dev.add_rule ( "rule2" );
dev.set_rule ( "rule2", "NET2", "LC-O3", 150000 );
dev.enable_rule ( "rule2" );
dev.add_rule ( "rule3" );
dev.set_rule ( "rule3", "LC-I1", "NET0", 0 );
dev.enable_rule ( "rule3" );
dev.add_rule ( "rule4" );
dev.set_rule ( "rule4", "LC-I2", "NET1", 0 );
dev.enable_rule ( "rule4" );
dev.add_rule ( "rule5" );
dev.set_rule ( "rule5", "LC-I3", "NET2", 0 );
dev.enable_rule ( "rule5" );
// Set dead-time
acc.write(`TDC_DIRECT_BASE + 'h4, 'h40);
// Enable channels
acc.write(`TDC_DIRECT_BASE + 'h0, 'h1f);
end
initial begin
forever begin
if ( ( dev != null ) && ( dev.ready ) )
dev.update ();
#1us;
end
end
endmodule // main
vsim -quiet -t 10fs -L unisim work.main
vsim -quiet -t 10fs -L unisim work.main -suppress 1270,8617,8683,8684,8822
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
......
# Modelsim run script for continuous integration
# execute: vsim -c -do "run_ci.do"
vsim -quiet -t 10fs -L unisim work.main
vsim -quiet -t 10fs -L unisim work.main -suppress 1270,8617,8683,8684,8822
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
......
......@@ -70,7 +70,6 @@ static void adcin_input(struct wrtd_adcin_dev *adcin)
if(!(status & ALT_TRIGOUT_TS_PRESENT))
return;
/* FIXME: MSB word ? */
mask = adcin_readl(adcin, ALT_TRIGOUT_TS_MASK_SEC + 0);
ev.ts.seconds = adcin_readl(adcin, ALT_TRIGOUT_TS_MASK_SEC + 4);
ev.ts.ns = adcin_readl(adcin, ALT_TRIGOUT_TS_CYCLES) * 8;
......@@ -87,9 +86,9 @@ static void adcin_input(struct wrtd_adcin_dev *adcin)
continue;
memset(ev.id, 0, WRTD_ID_LEN);
ev.id[0] = 'A';
ev.id[1] = 'D';
ev.id[2] = 'C';
ev.id[0] = 'L';
ev.id[1] = 'C';
ev.id[2] = '-';
ev.id[3] = 'I';
ev.id[4] = '1' + i;
ev.flags = 0;
......@@ -104,9 +103,6 @@ static void adcin_input(struct wrtd_adcin_dev *adcin)
static int adcin_init(struct wrtd_adcin_dev *adcin)
{
/* Disable all channels. */
adcin_writel(adcin, 0, ALT_TRIGOUT_ENABLE);
pr_debug("adcin initialization complete\n\r");
return 0;
......
......@@ -183,24 +183,6 @@ static void adcout_local_output(struct wrtd_adcout_dev *dev,
*pq_ev = *ev;
}
#if 0
/**
* It disable the given channel and clear its internal queue
*/
static int wrtd_out_disable(struct trtl_fw_msg *msg_i,
struct trtl_fw_msg *msg_o)
{
uint32_t ch = ((uint32_t *)msg_i->payload)[0];
pulse_queue_init(&wrtd_out_channels[ch].queue);
fd_ch_writel(&wrtd_out_channels[ch], FD_DCR_MODE, FD_REG_DCR);
msg_o->header->msg_id = msg_i->header->msg_id;
return 0;
}
#endif
static void adcout_init(struct wrtd_adcout_dev *dev)
{
adcout_out_queue_init(&dev->queue);
......
......@@ -14,19 +14,18 @@
#define NBR_CPUS 1
#define CPU_IDX 0
#define NBR_LOCAL_INPUTS 5
#define NBR_LOCAL_OUTPUTS 1
#define NBR_RULES 16
#define NBR_DEVICES 2
#define NBR_ALARMS 1
/* Addresses comes from cpu0 crossbar. */
#define DEVICES_IO_ADDR { TRTL_ADDR_DP_BASE + 0x0000, TRTL_ADDR_DP_BASE + 0x1000, 0, 0}
#define APP_ID WRTD_APP_ADCIO_5CH
#define DEVICES_NBR_CHS { 5, 1, 0, 0}
#define DEVICES_CHS_DIR { WRTD_CH_DIR_IN, WRTD_CH_DIR_OUT, 0, 0}
#define APP_ID 0x35B0
#define APP_VER RT_VERSION(2, 0)
#define APP_NAME "wrtd-adc"
#define WRTD_NET_TX
#define WRTD_NET_RX
#define WRTD_NET_TX 1
#define WRTD_NET_RX 1
#define WRTD_LOCAL_TX 1
#define WRTD_LOCAL_RX 1
#include "wrtd-rt-common.h"
......@@ -78,6 +77,9 @@ static inline void wr_enable_lock(int enable)
static inline int wr_sync_timeout(void)
{
#ifdef SIMULATION
return 0;
#else
int res, val;
res = 0;
......@@ -87,6 +89,7 @@ static inline int wr_sync_timeout(void)
val = adcout_wr_sync_timeout();
res = val > res ? val : res;
return res;
#endif
}
static void wrtd_local_output(struct wrtd_event *ev, unsigned ch)
......@@ -102,7 +105,7 @@ static int wrtd_user_init(void)
wr_enable_lock(0);
pr_debug("rt-input firmware initialized.\n\r");
pr_debug("rt-adc firmware initialized.\n\r");
return 0;
}
......
/*
* Copyright (C) 2013-2018 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*/
#include "mockturtle-rt.h"
#include <mockturtle-framework.h>
#include "wrtd-common.h"
#include "fmc_adc_alt_trigout.h"
#define NBR_CPUS 1
#define CPU_IDX 0
#define NBR_LOCAL_INPUTS 5
#define NBR_LOCAL_OUTPUTS 0
#define NBR_RULES 16
#define NBR_DEVICES 1
#define NBR_ALARMS 0
#define DEVICES_IO_ADDR { TRTL_ADDR_DP_BASE + 0x0000, 0, 0, 0}
#define APP_ID WRTD_APP_ADCIN_5CH
#define APP_VER RT_VERSION(2, 0)
#define APP_NAME "wrtd-adcin"
#define WRTD_NET_TX
#include "wrtd-rt-common.h"
#include "wrtd-adcout.c"
static struct wrtd_adcout_dev adcout0 =
{
.io_addr = 0x0,
};
static inline int wr_link_up(void)
{
return adcout_wr_link_up(&adcout0);
}
static inline int wr_time_locked(void)
{
return adcout_wr_time_locked(&adcout0);
}
static inline int wr_time_ready(void)
{
return adcout_wr_time_ready(&adcout0);
}
static inline void wr_enable_lock(int enable)
{
}
static inline int wr_sync_timeout(void)
{
return 0;
}
static void wrtd_local_output(struct wrtd_event *ev, unsigned ch)
{
/* No output. */
return;
}
#ifdef SIMULATION
static int wrtd_i_sim_init(struct wrtd_tdc_dev *tdc)
{
/* TODO: preconfigure the rules. */
int i;
for(i = 0; i < TDC_NUM_CHANNELS; i++) {
wrtd_in_channels[i].config.log_level = WRTD_LOG_ALL;
wrtd_in_channels[i].config.id.system = 0;
wrtd_in_channels[i].config.id.source_port = i;
wrtd_in_channels[i].config.id.trigger = i;
wrtd_in_channels[i].config.flags =
WRTD_ENABLED | WRTD_ARMED | WRTD_TRIGGER_ASSIGNED;
}
tdc_writel(tdc, 0x40, BASE_DP_TDC_DIRECT + DR_REG_DEAD_TIME);
tdc_writel(tdc, 0x1f, BASE_DP_TDC_DIRECT + DR_REG_CHAN_ENABLE);
return 0;
}
#endif
static int wrtd_user_init(void)
{
#ifdef SIMULATION
/* Skip WR sync and automatically generate some events when
simulating */
wrtd_i_sim_init(&tdc0);
#else
adcout_init(&adcout0);
#endif
wr_enable_lock(0);
pr_debug("rt-input firmware initialized.\n\r");
return 0;
}
static void wrtd_io(void)
{
adcout_input(&adcout0);
}
......@@ -2,16 +2,18 @@
#define NBR_CPUS xxx
#define CPU_IDX xxx
#define NBR_LOCAL_INPUTS xxx
#define NBR_RULES xxx
#define NBR_DEVICES xxx
#define NBR_ALARMS xxx
#define DEVICES_IO_ADDR { xxx, 0, 0, 0}
#define DEVICES_NBR_CHS { xxx, 0, 0, 0}
#define DEVICES_CHS_DIR { WRTD_CH_DIR_IN, 0, 0, 0}
#define APP_ID WRTD_APP_xxx
#define APP_VER RT_VERSION(xxx, 0)
#define APP_NAME xxx
#define/#undef WRTD_NET_RX
#define/#undef WRTD_NET_TX
#define WRTD_NET_RX x // 1 = enabled, 0 = disabled
#define WRTD_NET_TX x
#define WRTD_LOCAL_RX x
#define WRTD_LOCAL_TX x
#include "wrtd-rt-common.h"
*/
......@@ -23,15 +25,14 @@
#define WRTD_UDP_PORT 5044
/* Functions defined by the user. */
static int wr_link_up(void);
static int wr_time_locked(void);
static int wr_time_ready(void);
static void wr_enable_lock(int enable);
static int wr_sync_timeout(void);
static void wrtd_local_output(struct wrtd_event *ev, unsigned ch);
static int wrtd_user_init(void);
static void wrtd_io(void);
static int wrtd_user_init(void);
static void wr_update_link(void);
static int wr_sync_timeout(void);
static void wr_enable_lock(int enable);
static int wr_time_ready(void);
static int wr_time_locked(void);
static int wr_link_up(void);
static struct wrtd_rule rules[NBR_RULES];
static struct wrtd_alarm alarms[NBR_ALARMS];
......@@ -43,16 +44,24 @@ static struct wrtd_root root =
.ver_major = WRTD_VERSION_MAJOR,
.ver_minor = WRTD_VERSION_MINOR,
.fw_id = APP_ID,
.nbr_devices = NBR_DEVICES,
.nbr_alarms = NBR_ALARMS,
.nbr_rules = NBR_RULES,
.capabilities = (((WRTD_NET_RX > 0) << 0) |
((WRTD_NET_TX > 0) << 1) |
((WRTD_LOCAL_RX > 0) << 2) |
((WRTD_LOCAL_TX > 0) << 3)),
.wr_state = WR_LINK_OFFLINE,
.log_flags = 0,
.freeze_flag = 0,
.devices_io_addr = DEVICES_IO_ADDR,
.devices_nbr_chs = DEVICES_NBR_CHS,
.devices_chs_dir = DEVICES_CHS_DIR,
.rules_addr = (uint32_t)rules,
.alarms_addr = (uint32_t)alarms
};
......@@ -80,7 +89,7 @@ static void wr_update_link(void)
break;
case WR_LINK_SYNCING:
if (wr_time_locked()) {
pr_debug("rt-tdc: WR synced, waiting for TDC plumbing to catch up...\n\r");
pr_debug("sync detected, waiting for plumbing to catch up...\n\r");
root.wr_state = WR_LINK_WAIT;
tai_start = lr_readl(MT_CPU_LR_REG_TAI_SEC);
}
......@@ -89,7 +98,7 @@ static void wr_update_link(void)
if (wr_sync_timeout() == 0
|| (lr_readl(MT_CPU_LR_REG_TAI_SEC)
>= (tai_start + wr_sync_timeout()))) {
pr_debug("rt-tdc: WR TDC synced\n\r");
pr_debug("WR synced\n\r");
root.wr_state = WR_LINK_SYNCED;
}
break;
......@@ -98,7 +107,7 @@ static void wr_update_link(void)
}
if (root.wr_state != WR_LINK_OFFLINE && !wr_link_up()) {
pr_error("rt-tdc: WR sync lost\n\r");
pr_error("WR sync lost\n\r");
root.wr_state = WR_LINK_OFFLINE;
wr_enable_lock(0);
}
......@@ -255,7 +264,7 @@ static void wrtd_log(uint32_t type, uint32_t reason,
root.log_nbr_sent++;
}
#ifdef WRTD_NET_TX
#if WRTD_NET_TX > 0
static void wrtd_init_tx(void)
{
static const struct trtl_ep_eth_address addr = {
......@@ -409,7 +418,7 @@ static void wrtd_route(struct wrtd_rule *rule, const struct wrtd_event *ev)
rule->stat.tx_last = ev->ts;
if (rule->conf.dest_ch == WRTD_DEST_CH_NET) {
#ifdef WRTD_NET_TX
#if WRTD_NET_TX > 0
wrtd_send_network(&tev);
#else
wrtd_remote_output
......@@ -429,8 +438,8 @@ static void wrtd_route(struct wrtd_rule *rule, const struct wrtd_event *ev)
}
}
#if defined(WRTD_NET_RX) || NBR_ALARMS > 0 || NBR_LOCAL_INPUTS > 0
/* Route an event coming from network, or alarm. */
#if WRTD_LOCAL_RX > 0 || WRTD_NET_RX > 0 || NBR_ALARMS > 0
/* Route an event coming from a local input, network, or alarm. */
static void wrtd_route_in(struct wrtd_event *ev)
{
struct wrtd_rule *rule;
......@@ -438,7 +447,7 @@ static void wrtd_route_in(struct wrtd_event *ev)
rule = &rules[hash];
while (1) {
/* A disabled rule cannot be followed by an enabled one. */
/* A disabled rule cannot be followed by an enabled one. */
if (!rule->conf.enabled)
break;
......@@ -452,7 +461,7 @@ static void wrtd_route_in(struct wrtd_event *ev)
}
#endif
#ifdef WRTD_NET_RX
#if WRTD_NET_RX > 0
static void wrtd_init_rx(void)
{
static const struct trtl_ep_eth_address addr = {
......@@ -626,7 +635,7 @@ static int wrtd_main(void)
while (1) {
if (!root.freeze_flag) {
wrtd_io();
#ifdef WRTD_NET_RX
#if WRTD_NET_RX > 0
wrtd_recv_network();
#endif
#if NBR_CPUS > 1
......@@ -646,10 +655,10 @@ static int wrtd_main(void)
static int wrtd_sys_init(void)
{
#ifdef WRTD_NET_RX
#if WRTD_NET_RX > 0
wrtd_init_rx();
#endif
#ifdef WRTD_NET_TX
#if WRTD_NET_TX > 0
wrtd_init_tx();
#endif
......
......@@ -124,17 +124,13 @@ int fd_init(struct wrtd_fd_dev *fd)
}
#ifdef SIMULATION
int fd_sim_init(void)
int fd_sim_init(struct wrtd_fd_dev *fd)
{
int err;
pr_debug("Initializing the Fine Delay board...\n");
fd_do_reset(1);
err = fd_reset_again();
if (err)
return err;
fd_do_reset(fd, 1);
return 0;
}
......
......@@ -295,24 +295,6 @@ static void fd_outputs(struct wrtd_fd_dev *fd)
fd_output(fd, i);
}
#if 0
/**
* It disable the given channel and clear its internal queue
*/
static int wrtd_out_disable(struct trtl_fw_msg *msg_i,
struct trtl_fw_msg *msg_o)
{
uint32_t ch = ((uint32_t *)msg_i->payload)[0];
pulse_queue_init(&wrtd_out_channels[ch].queue);
fd_ch_writel(&wrtd_out_channels[ch], FD_DCR_MODE, FD_REG_DCR);
msg_o->header->msg_id = msg_i->header->msg_id;
return 0;
}
#endif
static void wrtd_fd_data_init(struct wrtd_fd_dev *fd)
{
unsigned i;
......
......@@ -104,7 +104,7 @@ void fd_gpio_val(struct wrtd_fd_dev *fd, int pin, int val);
void fd_gpio_set_clr(struct wrtd_fd_dev *fd, int pin, int set);
int fd_init(struct wrtd_fd_dev *fd);
int fd_sim_init(void);
int fd_sim_init(struct wrtd_fd_dev *fd);
#define fd_gpio_set(fd, pin) fd_gpio_set_clr(fd, (pin), 1)
#define fd_gpio_clr(fd, pin) fd_gpio_set_clr(fd, (pin), 0)
......@@ -134,8 +134,6 @@ static inline void fd_drv_ch_writel(struct wrtd_fd_dev *fd, int ch,
fd_writel(fd, v, 0x100 + ch * 0x100 + reg);
}
// Alessandro, I f*****ing hate you. And all kernel devs. To express my hatred I will use
// C++ style comments intermixed with C style comments!
static inline uint64_t div_u64(uint64_t dividend, uint32_t divisor)
{
return dividend / divisor;
......
......@@ -13,18 +13,19 @@
#include "wrtd-fd.h"
#define NBR_CPUS 2
#define CPU_IDX 0
#define NBR_LOCAL_INPUTS 0
#define NBR_LOCAL_OUTPUTS FD_NUM_CHANNELS
#define CPU_IDX 1
#define NBR_RULES 16
#define NBR_DEVICES 1
#define NBR_ALARMS 1
#define DEVICES_IO_ADDR { TRTL_ADDR_DP_BASE, 0, 0, 0}
#define APP_ID WRTD_APP_FD_4CH
#define DEVICES_NBR_CHS { FD_NUM_CHANNELS, 0, 0, 0}
#define DEVICES_CHS_DIR { WRTD_CH_DIR_OUT, 0, 0, 0}
#define APP_ID 0x35E0
#define APP_VER RT_VERSION(2, 0)
#define APP_NAME "wrtd-fd"
#define WRTD_NET_TX 0
#define WRTD_NET_RX 1
#define WRTD_LOCAL_TX 1
#define WRTD_LOCAL_RX 0
#include "wrtd-rt-common.h"
......@@ -56,7 +57,11 @@ static void wr_enable_lock(int enable)
static inline int wr_sync_timeout(void)
{
#ifdef SIMULATION
return 0;
#else
return fd_wr_sync_timeout();
#endif
}
static void wrtd_local_output(struct wrtd_event *ev, unsigned ch)
......@@ -64,36 +69,6 @@ static void wrtd_local_output(struct wrtd_event *ev, unsigned ch)
fd_local_output(&fd0, ev, ch);
}
#ifdef SIMULATION
static int wrtd_o_sim_init(void)
{
int i;
for (i = 0; i < FD_NUM_CHANNELS; i++) {
int hidx;
wrtd_out_channels[i].config.log_level = WRTD_LOG_ALL;
wrtd_out_channels[i].config.state = OUT_ST_ARMED;
wrtd_out_channels[i].config.flags =
WRTD_ENABLED | WRTD_ARMED | WRTD_TRIGGER_ASSIGNED;
triggers[i].id.system = 0;
triggers[i].id.source_port = i;
triggers[i].id.trigger = i;
triggers[i].flags = ENTRY_FLAG_VALID;
triggers[i].ocfg[i].delay_cycles = 100 * 125; // 1 cycle is 8ns
triggers[i].ocfg[i].delay_frac = 0;
triggers[i].ocfg[i].state = HASH_ENT_DIRECT;
hidx = wrtd_out_hash_table_free(&triggers[i].id);
tlist_count++;
ht[hidx] = &triggers[i];
}
return 0;
}
#endif
/**
* Initialize data structures, RT application and variables
*/
......@@ -110,9 +85,7 @@ static int wrtd_user_init(void)
wrtd_fd_data_init(&fd0);
#ifdef SIMULATION
/* Skip WR sync and automatically generate some events when simulating */
wrtd_o_sim_init();
fd_sim_init();
fd_sim_init(&fd0);
#else
fd_init(&fd0);
#endif
......
......@@ -14,17 +14,18 @@
#define NBR_CPUS 2
#define CPU_IDX 0
#define NBR_LOCAL_INPUTS 5
#define NBR_LOCAL_OUTPUTS 0
#define NBR_RULES 16
#define NBR_DEVICES 1
#define NBR_ALARMS 0
#define DEVICES_IO_ADDR { TRTL_ADDR_DP_BASE, 0, 0, 0}
#define APP_ID WRTD_APP_TDC_5CH
#define DEVICES_NBR_CHS { 5, 0, 0, 0}
#define DEVICES_CHS_DIR { WRTD_CH_DIR_IN, 0, 0, 0}
#define APP_ID 0x35D0
#define APP_VER RT_VERSION(2, 0)
#define APP_NAME "wrtd-tdc"
#define WRTD_NET_TX
#define WRTD_NET_TX 1
#define WRTD_NET_RX 0
#define WRTD_LOCAL_TX 0
#define WRTD_LOCAL_RX 1
#include "wrtd-rt-common.h"
......@@ -70,41 +71,13 @@ static void wrtd_local_output(struct wrtd_event *ev, unsigned ch)
return;
}
#ifdef SIMULATION
static int wrtd_i_sim_init(struct wrtd_tdc_dev *tdc)
{
/* TODO: preconfigure the rules. */
int i;
for(i = 0; i < TDC_NUM_CHANNELS; i++) {
wrtd_in_channels[i].config.log_level = WRTD_LOG_ALL;
wrtd_in_channels[i].config.id.system = 0;
wrtd_in_channels[i].config.id.source_port = i;
wrtd_in_channels[i].config.id.trigger = i;
wrtd_in_channels[i].config.flags =
WRTD_ENABLED | WRTD_ARMED | WRTD_TRIGGER_ASSIGNED;
}
tdc_writel(tdc, 0x40, BASE_DP_TDC_DIRECT + DR_REG_DEAD_TIME);
tdc_writel(tdc, 0x1f, BASE_DP_TDC_DIRECT + DR_REG_CHAN_ENABLE);
return 0;
}
#endif
static int wrtd_user_init(void)
{
#ifdef SIMULATION
/* Skip WR sync and automatically generate some events when
simulating */
wrtd_i_sim_init(&tdc0);
#else
tdc_init(&tdc0);
#endif
wr_enable_lock(0);
pr_debug("rt-input firmware initialized.\n\r");
pr_debug("rt-tdc firmware initialized.\n\r");
return 0;
}
......
......@@ -184,6 +184,7 @@ static int tdc_init(struct wrtd_tdc_dev *tdc)
tdc_writel(tdc, 0x0, BASE_DP_TDC_DIRECT + DR_REG_CHAN_ENABLE);
tdc_writel(tdc, DEFAULT_DEAD_TIME, BASE_DP_TDC_DIRECT + DR_REG_DEAD_TIME);
#ifndef SIMULATION
tdc_enable_acquisition(tdc, 0);
err = tdc_acam_init(tdc);
......@@ -199,6 +200,7 @@ static int tdc_init(struct wrtd_tdc_dev *tdc)
return err;
tdc_enable_acquisition(tdc, 1);
#endif
pr_debug("%s: TDC initialization complete\n\r", __func__);
......@@ -215,6 +217,13 @@ static inline int tdc_wr_time_locked(struct wrtd_tdc_dev *tdc)
return tdc_readl(tdc, BASE_DP_TDC_REGS + TDC_REG_WR_STAT) & TDC_WR_STAT_AUX_LOCKED;
}
static void tdc_wr_enable_lock(struct wrtd_tdc_dev *tdc, int enable)
{
tdc_writel(tdc, TDC_CTRL_DIS_ACQ, BASE_DP_TDC_REGS + TDC_REG_CTRL);
tdc_writel(tdc, enable ? TDC_WR_CTRL_ENABLE : 0, BASE_DP_TDC_REGS + TDC_REG_WR_CTRL);
tdc_writel(tdc, TDC_CTRL_EN_ACQ, BASE_DP_TDC_REGS + TDC_REG_CTRL);
}
static inline int tdc_wr_time_ready(struct wrtd_tdc_dev *tdc)
{
return tdc_readl(tdc, BASE_DP_TDC_REGS + TDC_REG_WR_STAT) & TDC_WR_STAT_TIME_VALID;
......@@ -222,7 +231,7 @@ static inline int tdc_wr_time_ready(struct wrtd_tdc_dev *tdc)
static inline int tdc_wr_sync_timeout(void)
{
/* Wait 3 seconds until the tcd is ready (+ 1 for truncation). */
/* Wait 3 seconds until the tdc is ready (+ 1 for truncation). */
return 4;
}
......@@ -243,13 +252,12 @@ static void tdc_input(struct wrtd_tdc_dev *tdc)
if(fifo_sr & DR_FIFO_CSR_EMPTY)
return;
/* FIXME: MSB word ? */
ev.ts.seconds = tdc_readl(tdc, BASE_DP_TDC_DIRECT + DR_REG_FIFO_R0);
ev.ts.ns = tdc_readl(tdc, BASE_DP_TDC_DIRECT + DR_REG_FIFO_R1) * 8;
meta = tdc_readl(tdc, BASE_DP_TDC_DIRECT + DR_REG_FIFO_R2);
/* Convert from ACAM bins (81ps) to WR time format. Numerical
hack used to avoid time-consuming division.
hack used to avoid time-consuming division.
1 frac = 1 tick / 4096 = 8ns / 4096.
1bin * 5308 / 128 * 1 frac = 0.0809937ns */
uint32_t frac = ( (meta & 0x3ffff) * 5308 ) >> 7;
......@@ -264,22 +272,16 @@ static void tdc_input(struct wrtd_tdc_dev *tdc)
int channel = (meta >> 19) & 0x7;
memset(ev.id, 0, WRTD_ID_LEN);
ev.id[0] = 'T';
ev.id[1] = 'D';
ev.id[2] = 'C';
ev.id[3] = '1' + channel; /* channel starts from 0. */
ev.id[0] = 'L';
ev.id[1] = 'C';
ev.id[2] = '-';
ev.id[3] = 'I';
ev.id[4] = '1' + channel; /* channel starts from 0. */
ev.flags = 0;
wrtd_log(WRTD_LOG_MSG_EV_GENERATED,
WRTD_LOG_GENERATED_DEVICE + channel, &ev, NULL);
WRTD_LOG_GENERATED_DEVICE + (channel * 8), &ev, NULL);
/* Pass to wrtd. */
wrtd_route_in(&ev);
}
static void tdc_wr_enable_lock(struct wrtd_tdc_dev *tdc, int enable)
{
tdc_writel(tdc, TDC_CTRL_DIS_ACQ, BASE_DP_TDC_REGS + TDC_REG_CTRL);
tdc_writel(tdc, enable ? TDC_WR_CTRL_ENABLE : 0, BASE_DP_TDC_REGS + TDC_REG_WR_CTRL);
tdc_writel(tdc, TDC_CTRL_EN_ACQ, BASE_DP_TDC_REGS + TDC_REG_CTRL);
}
......@@ -20,6 +20,17 @@
#ifndef __WRTD_COMMON_H
#define __WRTD_COMMON_H
/* Maximum number of CPUS per MT (allow less than the MT arch). */
#define WRTD_MAX_CPUS 4
/* Maximum number of devices per CPU. */
#define WRTD_MAX_DEVS 4
/* Length of WRTD ID strings (not null-terminated). */
#define WRTD_ID_LEN 16
#define WRTD_ID_NET 0xff
/**
* WRTD timestamp format
*/
......@@ -30,11 +41,6 @@ struct wrtd_tstamp {
uint32_t frac;
};
/* Length of WRTD ID strings (not null-terminated). */
#define WRTD_ID_LEN 16
#define WRTD_ID_NET 0xff
struct wrtd_event {
/* Time of the event. */
struct wrtd_tstamp ts;
......@@ -151,6 +157,14 @@ enum wrtd_wr_link {
#define WRTD_VERSION_MAJOR 1
#define WRTD_VERSION_MINOR 4
#define WRTD_CH_DIR_IN 0
#define WRTD_CH_DIR_OUT 1
#define WRTD_CAP_NET_RX (1 << 0)
#define WRTD_CAP_NET_TX (1 << 1)
#define WRTD_CAP_LOCAL_RX (1 << 2)
#define WRTD_CAP_LOCAL_TX (1 << 3)
struct wrtd_root {
/* Version. */
uint8_t ver_major;
......@@ -158,11 +172,14 @@ struct wrtd_root {
uint8_t pad0_0;
uint8_t pad0_1;
uint32_t fw_id;
/* Config. */
uint8_t nbr_devices;
uint8_t nbr_alarms;
uint8_t nbr_rules;
uint8_t pad1_0;
/* Made of WRTD_CAP_* flags. */
uint8_t capabilities;
/* Status from firmware. Must not be modified by the user. */
enum wrtd_wr_link wr_state;
......@@ -173,7 +190,9 @@ struct wrtd_root {
uint8_t pad3_0;
uint8_t pad3_1;
uint32_t devices_io_addr[4];
uint8_t devices_nbr_chs[WRTD_MAX_DEVS];
/* Array of WRTD_CH_DIR_* values */
uint8_t devices_chs_dir[WRTD_MAX_DEVS];
uint32_t rules_addr;
uint32_t alarms_addr;
......@@ -200,10 +219,6 @@ struct wrtd_io_msg {
uint32_t data[];
};
#define WRTD_APP_TDC_5CH 0x35D0
#define WRTD_APP_FD_4CH 0x35E0
#define WRTD_APP_ADCIO_5CH 0x35B0
enum wrtd_trtl_actions {
/* Always the first one, to get root and version. */
WRTD_ACTION_GET_CONFIG,
......
......@@ -9,13 +9,12 @@ REPO_PARENT ?= ..
-include $(REPO_PARENT)/parent_common.mk
WRTD_DEP_TRTL ?= ../../dependencies/mock-turtle/
WRTD_DEP_FMC_ADC ?= ../../dependencies/fmc-adc-100m14b4cha-gw
LIB = libwrtd.a
OBJS := libwrtd-base.o libwrtd-devices.o libwrtd-attributes.o libwrtd-rules.o
OBJS := libwrtd-base.o libwrtd-attributes.o libwrtd-rules.o
INCFLAGS=-I. -I../include -I$(WRTD_DEP_TRTL)/software/include \
-I$(WRTD_DEP_TRTL)/software/lib -I../firmware/tdc -I$(WRTD_DEP_FMC_ADC)/hdl/rtl/wb_gen/
-I$(WRTD_DEP_TRTL)/software/lib
CFLAGS += -fno-strict-aliasing $(INCFLAGS)
CFLAGS += -Wall -Werror
......
......@@ -43,7 +43,11 @@ enum wrtd_status wrtd_init(const char *resource_name,
const char *options_str,
struct wrtd_dev **dev)
{
int i;
struct trtl_dev *trtl;
const struct trtl_config_rom *cfgrom;
struct wrtd_config_msg msg;
enum wrtd_status status;
/* In case of error... */
*dev = NULL;
......@@ -79,9 +83,31 @@ enum wrtd_status wrtd_init(const char *resource_name,
return WRTD_ERROR_OUT_OF_MEMORY;
memset(res, 0, sizeof(*res));
res->trtl = trtl;
res->trtl = trtl;
cfgrom = trtl_config_get(res->trtl);
/* Set HMQ words. */
for (i = 0; i < cfgrom->n_cpu; i++)
if (cfgrom->n_hmq[i] < 0)
res->hmq_words[i] = TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD
(cfgrom->hmq[i][0].sizes);
if (cfgrom->n_cpu > WRTD_MAX_CPUS)
return wrtd_return_error(res, WRTD_ERROR_INVALID_VALUE,
"incorrect number of cpus");
for (i = 0; i < cfgrom->n_cpu; i++) {
status = wrtd_msg_get_config(res, i, &msg);
WRTD_RETURN_IF_ERROR(status);
res->root_addr[i] = msg.root_addr;
/* FIXME: check firmware version ? */
}
res->nbr_cpus = cfgrom->n_cpu;
*dev = res;
return WRTD_SUCCESS;
}
......@@ -106,42 +132,38 @@ enum wrtd_status wrtd_get_firmware_id(struct wrtd_dev *dev,
unsigned *nbr_ids,
uint32_t *ids)
{
const struct wrtd_mt_config *cfg;
enum wrtd_status status;
int i;
/* Find config. */
status = wrtd_find_config(dev, &cfg);
status = wrtd_fill_roots(dev);
WRTD_RETURN_IF_ERROR(status);
/* Find firmwares. */
*nbr_ids = cfg->nbr_cpus;
for (i = 0; i < cfg->nbr_cpus; i++) {
ids[i] = cfg->cpus[i].fw_id;
*nbr_ids = dev->nbr_cpus;
for (i = 0; i < dev->nbr_cpus; i++) {
ids[i] = dev->roots[i].fw_id;
}
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_load_firmware(struct wrtd_dev *dev, unsigned verbose,
unsigned int nbr_firmwares,
struct wrtd_firmware *fw)
{
struct trtl_fw_version version;
const struct wrtd_mt_config *cfg;
enum wrtd_status status;
int err;
int i, j;
struct wrtd_firmware *map[WRTD_MAX_CPUS];
/* Find config. */
status = wrtd_find_config(dev, &cfg);
status = wrtd_fill_roots(dev);
WRTD_RETURN_IF_ERROR(status);
/* Find firmwares. */
for (i = 0; i < cfg->nbr_cpus; i++) {
for (i = 0; i < dev->nbr_cpus; i++) {
map[i] = NULL;
for (j = 0; j < nbr_firmwares; j++)
if (cfg->cpus[i].fw_id == fw[j].id) {
if (dev->roots[i].fw_id == fw[j].id) {
map[i] = &fw[j];
break;
}
......@@ -150,12 +172,12 @@ enum wrtd_status wrtd_load_firmware(struct wrtd_dev *dev, unsigned verbose,
return wrtd_return_error
(dev, WRTD_ERROR_RESOURCE_UNKNOWN,
"no firmware for app 0x%x",
cfg->cpus[i].fw_id);
dev->roots[i].fw_id);
}
}
/* Load firmwares. */
for (i = 0; i < cfg->nbr_cpus; i++) {
for (i = 0; i < dev->nbr_cpus; i++) {
if (verbose)
printf("loading cpu %d with %s\n", i, map[i]->path);
err = trtl_cpu_load_application_file (dev->trtl,
......@@ -175,7 +197,7 @@ enum wrtd_status wrtd_load_firmware(struct wrtd_dev *dev, unsigned verbose,
}
/* Check CPUs. */
for (i = 0; i < cfg->nbr_cpus; i++) {
for (i = 0; i < dev->nbr_cpus; i++) {
if (verbose)
printf("waiting cpu %d to be ready\n", i);
......@@ -201,7 +223,6 @@ enum wrtd_status wrtd_load_firmware(struct wrtd_dev *dev, unsigned verbose,
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_msg_get_config(struct wrtd_dev *wrtd, unsigned cpu,
struct wrtd_config_msg *res)
{
......@@ -253,44 +274,6 @@ enum wrtd_status wrtd_get_sys_time(struct wrtd_dev *wrtd,
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_fill_config(struct wrtd_dev *wrtd)
{
int i;
const struct trtl_config_rom *cfgrom;
struct wrtd_config_msg msg;
enum wrtd_status status;
/* Need to be fetched only once. */
if (wrtd->config != NULL)
return WRTD_SUCCESS;
status = wrtd_find_config(wrtd, &wrtd->config);
WRTD_RETURN_IF_ERROR(status);
cfgrom = trtl_config_get(wrtd->trtl);
/* Set HMQ words. */
for (i = 0; i < cfgrom->n_cpu; i++)
if (cfgrom->n_hmq[i] < 0)
wrtd->hmq_words[i] = TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD
(cfgrom->hmq[i][0].sizes);
if (cfgrom->n_cpu > WRTD_MAX_CPUS)
return wrtd_return_error(wrtd, WRTD_ERROR_INVALID_VALUE,
"incorrect number of cpus");
for (i = 0; i < cfgrom->n_cpu; i++) {
status = wrtd_msg_get_config(wrtd, i, &msg);
WRTD_RETURN_IF_ERROR(status);
wrtd->root_addr[i] = msg.root_addr;
/* FIXME: check firmware version ? */
}
wrtd->nbr_cpus = cfgrom->n_cpu;
return WRTD_SUCCESS;
}
enum wrtd_status wrtd_fill_roots(struct wrtd_dev *wrtd)
{
enum wrtd_status status;
......@@ -299,9 +282,6 @@ enum wrtd_status wrtd_fill_roots(struct wrtd_dev *wrtd)
if (wrtd->roots[0].ver_major != 0)
return WRTD_SUCCESS;
status = wrtd_fill_config(wrtd);
WRTD_RETURN_IF_ERROR(status);
for (cpu = 0; cpu < wrtd->nbr_cpus; cpu++) {
status = wrtd_msg_readw(wrtd, cpu,
wrtd->root_addr[cpu],
......@@ -398,12 +378,6 @@ enum wrtd_status wrtd_msg_readw(struct wrtd_dev *wrtd, unsigned cpu,
uint32_t addr, uint32_t count,
uint32_t *dest)
{
enum wrtd_status status;
/* Be sure the HMQ length is known. */
status = wrtd_fill_config(wrtd);
WRTD_RETURN_IF_ERROR(status);
while (count > 0) {
uint32_t tlen;
struct trtl_msg msg;
......@@ -454,12 +428,6 @@ enum wrtd_status wrtd_msg_writew(struct wrtd_dev *wrtd, unsigned cpu,
uint32_t addr, uint32_t count,
const uint32_t *src)
{
enum wrtd_status status;
/* Be sure the HMQ length is known. */
status = wrtd_fill_config(wrtd);
WRTD_RETURN_IF_ERROR(status);
while (count > 0) {
uint32_t tlen;
struct trtl_msg msg;
......@@ -671,16 +639,10 @@ enum wrtd_status wrtd_log_read(struct wrtd_dev *wrtd,
struct wrtd_log_entry *log,
int poll_timeout)
{
enum wrtd_status status;
struct trtl_msg msg;
struct polltrtl p[WRTD_MAX_CPUS];
int ret, i;
/* To get nbr cpus. */
status = wrtd_fill_config(wrtd);
WRTD_RETURN_IF_ERROR(status);
for (i = 0; i < wrtd->nbr_cpus; ++i) {
p[i].trtl = wrtd->trtl;
p[i].idx_hmq = WRTD_HMQ;
......
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include "libmockturtle.h"
#include "libwrtd.h"
#include "libwrtd-private.h"
#include "hw/fmctdc-direct.h"
#include "fmc_adc_alt_trigout.h"
/* FIXME: duplicated macro. */
#define BASE_DP_TDC_DIRECT 0x8000
static enum wrtd_status wrtd_none_configure(struct wrtd_dev *wrtd,
unsigned cpu, unsigned dev,
unsigned int ch_mask)
{
return WRTD_SUCCESS;
}
static enum wrtd_status wrtd_tdc_configure(struct wrtd_dev *wrtd,
unsigned cpu, unsigned dev,
unsigned int ch_mask)
{
enum wrtd_status status;
uint32_t val;
uint32_t addr;
assert((ch_mask & 0x1f) == ch_mask);
/* Just set the enable bits. */
val = ch_mask;
addr = wrtd->roots[cpu].devices_io_addr[dev]
+ BASE_DP_TDC_DIRECT + DR_REG_CHAN_ENABLE;
printf("wrtd: tdc write 0x%08x at 0x%08x on cpu#%u\n", val, addr, cpu);
status = wrtd_msg_writew(wrtd, cpu, addr, 1, &val);
return status;
}
static enum wrtd_status wrtd_adcin_configure(struct wrtd_dev *wrtd,
unsigned cpu, unsigned dev,
unsigned int ch_mask)
{
enum wrtd_status status;
uint32_t val;
uint32_t addr;
assert((ch_mask & 0x1f) == ch_mask);
/* Just set the enable bits. */
val = (ch_mask & 0x0f) | ((ch_mask & 0x10) << 4);
addr = wrtd->roots[cpu].devices_io_addr[dev] + ALT_TRIGOUT_ENABLE;
printf("wrtd: adcin write 0x%08x at 0x%08x on cpu#%u\n", val, addr, cpu);
status = wrtd_msg_writew(wrtd, cpu, addr, 1, &val);
return status;
}
static const char * const tdc_channels[] =
{
"TDC1", "TDC2", "TDC3", "TDC4", "TDC5"
};
static const char * const fd_channels[] =
{
"FD1", "FD2", "FD3", "FD4"
};
static const char * const adcin_channels[] =
{
"ADCI1", "ADCI2", "ADCI3", "ADCI4", "ADCI5",
};
static const char * const adcout_channels[] =
{
"ADCO1",
};
static const struct wrtd_mt_device tdc_device =
{
.name = "FMC-TDC 5CH",
.dir = wrtd_input,
.nbr_chs = 5,
.channels = tdc_channels,
.configure = wrtd_tdc_configure
};
static const struct wrtd_mt_device fd_device =
{
.name = "FMC-FD 4CH",
.dir = wrtd_output,
.nbr_chs = 4,
.channels = fd_channels,
.configure = wrtd_none_configure
};
static const struct wrtd_mt_device adcin_device =
{
.name = "FMC ADCin 5CH",
.dir = wrtd_input,
.nbr_chs = 5,
.channels = adcin_channels,
.configure = wrtd_adcin_configure
};
static const struct wrtd_mt_device adcout_device =
{
.name = "FMC ADCout",
.dir = wrtd_output,
.nbr_chs = 1,
.channels = adcout_channels,
.configure = wrtd_none_configure
};
static const struct wrtd_mt_config configs[] =
{
/* TDC + FD board. */
{
.mt_app_id = 0x115790de,
.nbr_cpus = 2,
.tx_cpu = 0,
.rx_cpu = 1,
.cpus = {
{
WRTD_APP_TDC_5CH,
1,
{
&tdc_device
}
},
{
WRTD_APP_FD_4CH,
1,
{
&fd_device
}
}
}
},
/* ADC board. */
{
.mt_app_id = 0x115790d1,
.nbr_cpus = 1,
.tx_cpu = 0,
.rx_cpu = 0,
.cpus = {
{
WRTD_APP_ADCIO_5CH,
2,
{
&adcin_device,
&adcout_device
}
}
}
}
};
enum wrtd_status wrtd_find_config(struct wrtd_dev *dev,
const struct wrtd_mt_config **config)
{
const struct trtl_config_rom *cfgrom;
int i;
cfgrom = trtl_config_get(dev->trtl);
for (i = 0; i < sizeof(configs) / sizeof(configs[0]); i++)
if (configs[i].mt_app_id == cfgrom->app_id
&& configs[i].nbr_cpus == cfgrom->n_cpu) {
*config = &configs[i];
return WRTD_SUCCESS;
}
return wrtd_return_error(dev, WRTD_ERROR_RESOURCE_UNKNOWN,
"mt app_id 0x%x n_cpu=%d unknown",
cfgrom->app_id, cfgrom->n_cpu);
}
......@@ -5,12 +5,6 @@
#include "libwrtd.h"
#include "libmockturtle.h"
/* Maximum number of CPUS per MT (allow less than the MT arch). */
#define WRTD_MAX_CPUS 4
/* Maximum number of devices per CPU. */
#define WRTD_MAX_DEVS 4
#define WRTD_RETURN_IF_ERROR(status) if(status != WRTD_SUCCESS) return status
/* Alarm when in user space. */
......@@ -36,9 +30,6 @@ struct wrtd_dev {
/* Associated mock-turtle device. */
struct trtl_dev *trtl;
/* Device/cpu configuration. */
const struct wrtd_mt_config *config;
/* Last error. */
enum wrtd_status err;
......@@ -94,52 +85,6 @@ enum wrtd_status wrtd_load_firmware(struct wrtd_dev *dev, unsigned verbose,
unsigned int nbr_firmwares,
struct wrtd_firmware *fw);
enum wrtd_dir { wrtd_input, wrtd_output };
/* Device/FMC description. */
struct wrtd_mt_device {
/* Name of the FMC. */
const char *name;
/* Direction. */
enum wrtd_dir dir;
/* Number of channels. */
unsigned int nbr_chs;
/* Channels name. */
const char * const *channels;
/* HW configuration. */
enum wrtd_status (*configure)(struct wrtd_dev *wrtd,
unsigned cpu, unsigned dev,
unsigned int mask);
};
/* Per CPU configuration. */
struct wrtd_mt_cpu_config {
/* Firmware id to be loaded. Matches the firwmare app id. */
uint32_t fw_id;
/* Devices/FMC controlled by this cpu. */
unsigned nbr_devices;
const struct wrtd_mt_device *devices[WRTD_MAX_DEVS];
/* TODO: add network in, network out, loopback in. */
};
struct wrtd_mt_config {
/* From MT config rom. */
uint32_t mt_app_id;
uint32_t nbr_cpus;
/* CPU for network rx/tx. */
uint32_t tx_cpu;
uint32_t rx_cpu;
/* APP_ID for each cpu. */
struct wrtd_mt_cpu_config cpus[WRTD_MAX_CPUS];
};
/* Find device configuration for wrtd. */
enum wrtd_status wrtd_find_config(struct wrtd_dev *wrtd,
const struct wrtd_mt_config **config);
/* Be sure the config is set in WRTD. */
enum wrtd_status wrtd_fill_config(struct wrtd_dev *wrtd);
/* Do the get_config action. */
enum wrtd_status wrtd_msg_get_config(struct wrtd_dev *wrtd, unsigned cpu,
struct wrtd_config_msg *res);
......
This diff is collapsed.
......@@ -19,9 +19,6 @@ CFLAGS += $(EXTRACFLAGS)
LDLIBS += ../lib/libwrtd.a $(WRTD_DEP_TRTL)/software/lib/libmockturtle.a
PROGS := wrtd-boot wrtd-config wrtd-logging
#PROGS += wrtd-in-config
#PROGS += wrtd-out-config
#PROGS += wrtd-logging
all: $(PROGS)
......@@ -29,7 +26,6 @@ install:
install -d $(DESTDIR)/bin
install -D $(PROGS) $(DESTDIR)/bin
wrtd-inout-common.o: wrtd-inout-common.c
$(CC) -c $(CFLAGS) $^ -o $@
......
......@@ -71,12 +71,15 @@ static void disp_root_config(const struct wrtd_root *root)
printf("root:\n");
printf(" version major: %d, minor: %d\n",
root->ver_major, root->ver_minor);
printf(" devices: %d; IO addr:", root->nbr_devices);
for (j = 0; j < root->nbr_devices; j++)
printf(" 0x%08x", root->devices_io_addr[j]);
printf("\n");
printf(" firmware id: 0x%08x\n", root->fw_id);
printf(" nbr devices: %d\n", root->nbr_devices);
for (j = 0; j < root->nbr_devices; j++) {
printf(" dev %d, channels = %d, direction = %d\n",
j, root->devices_nbr_chs[j], root->devices_chs_dir[j]);
}
printf(" nbr alarms: %d\n", root->nbr_alarms);
printf(" nbr rules: %d\n", root->nbr_rules);
printf(" cap flags: 0x%02x\n", root->capabilities);
printf(" wr state: %u\n", root->wr_state);
printf(" log_flags: 0x%02x\n", root->log_flags);
printf(" freeze_flag: %d\n", root->freeze_flag);
......@@ -233,34 +236,51 @@ static enum wrtd_status disp_cpu_config(struct wrtd_dev *wrtd, int cpu,
return WRTD_SUCCESS;
}
static void disp_config(const struct wrtd_mt_config *config)
static void disp_mt_config(struct wrtd_dev *wrtd)
{
unsigned cpu;
printf("MT app_id: 0x%08x, nbr_cpus: %u\n",
config->mt_app_id, config->nbr_cpus);
printf(" tx_cpu: %u, rx_cpu: %u\n",
config->tx_cpu, config->rx_cpu);
for (cpu = 0; cpu < config->nbr_cpus; cpu++) {
const struct wrtd_mt_cpu_config *cpucfg =
&config->cpus[cpu];
unsigned dev;
printf("CPU#%d:\n", cpu);
printf(" firmware id: 0x%04x\n", cpucfg->fw_id);
for (dev = 0; dev < cpucfg->nbr_devices; dev++) {
const struct wrtd_mt_device *devcfg =
cpucfg->devices[dev];
unsigned ch;
printf(" device %u: %s\n",
dev, devcfg->name);
printf(" ");
switch (devcfg->dir) {
case wrtd_input: printf("inputs :"); break;
case wrtd_output: printf("outputs:"); break;
}
for (ch = 0; ch < devcfg->nbr_chs; ch++)
printf (" %s(%u)",
devcfg->channels[ch], ch);
printf("\n");
const struct trtl_config_rom *cfg;
int i, k;
cfg = trtl_config_get(wrtd->trtl);
fprintf(stdout, "signature: 0x%08"PRIx32"\n", cfg->signature);
fprintf(stdout, "version: 0x%08"PRIx32"\n", cfg->version);
fprintf(stdout, "clock-freq: %"PRId32"\n", cfg->clock_freq);
fprintf(stdout, "flags: 0x%"PRIx32"\n", cfg->flags);
fprintf(stdout, "application-id: 0x%08"PRIx32"\n", cfg->app_id);
fprintf(stdout, "shm-size (32bit words): %"PRId32"\n", cfg->smem_size);
fprintf(stdout, "cpus:\n");
for (i = 0; i < cfg->n_cpu; ++i) {
fprintf(stdout, "\t- index: %d\n", i);
fprintf(stdout, "\t mem-size (32bit words): %d\n", cfg->mem_size[i]);
fprintf(stdout, "\t hmq:\n");
for (k = 0; k < cfg->n_hmq[i]; ++k) {
uint32_t sizes = cfg->hmq[i][k].sizes;
fprintf(stdout, "\t\t- index: %d\n", k);
fprintf(stdout, "\t\t width-header: %"PRId32"\n",
TRTL_CONFIG_ROM_MQ_SIZE_HEADER(sizes));
fprintf(stdout, "\t\t width-payload: %"PRId32"\n",
TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD(sizes));
fprintf(stdout, "\t\t depth: %"PRId32"\n",
TRTL_CONFIG_ROM_MQ_SIZE_ENTRIES(sizes));
fprintf(stdout, "\t\t endpoint-id: %"PRId32"\n",
cfg->hmq[i][k].endpoint_id);
}
fprintf(stdout, "\t rmq:\n");
for (k = 0; k < cfg->n_rmq[i]; ++k) {
uint32_t sizes = cfg->rmq[i][k].sizes;
fprintf(stdout, "\t\t- index: %d\n", k);
fprintf(stdout, "\t\t width-header: %"PRId32"\n",
TRTL_CONFIG_ROM_MQ_SIZE_HEADER(sizes));
fprintf(stdout, "\t\t width-payload: %"PRId32"\n",
TRTL_CONFIG_ROM_MQ_SIZE_PAYLOAD(sizes));
fprintf(stdout, "\t\t depth: %"PRId32"\n",
TRTL_CONFIG_ROM_MQ_SIZE_ENTRIES(sizes));
fprintf(stdout, "\t\t endpoint-id: %"PRId32"\n",
cfg->hmq[i][k].endpoint_id);
}
}
}
......@@ -268,18 +288,12 @@ static void disp_config(const struct wrtd_mt_config *config)
static enum wrtd_status wrtd_cmd_dump_all(struct wrtd_dev *wrtd,
int argc, char *argv[])
{
const struct wrtd_mt_config *config;
enum wrtd_status status;
int cpu;
status = wrtd_fill_config(wrtd);
WRTD_RETURN_IF_ERROR(status);
config = wrtd->config;
disp_mt_config(wrtd);
disp_config(config);
for (cpu = 0; cpu < config->nbr_cpus; cpu++) {
for (cpu = 0; cpu < wrtd->nbr_cpus; cpu++) {
status = disp_cpu_config(wrtd, cpu, 1, 1);
WRTD_RETURN_IF_ERROR(status);
}
......@@ -287,15 +301,10 @@ static enum wrtd_status wrtd_cmd_dump_all(struct wrtd_dev *wrtd,
return WRTD_SUCCESS;
}
static enum wrtd_status wrtd_cmd_dump_config(struct wrtd_dev *wrtd,
int argc, char *argv[])
static enum wrtd_status wrtd_cmd_dump_mt_config(struct wrtd_dev *wrtd,
int argc, char *argv[])
{
enum wrtd_status status;
status = wrtd_fill_config(wrtd);
WRTD_RETURN_IF_ERROR(status);
disp_config(wrtd->config);
disp_mt_config(wrtd);
return WRTD_SUCCESS;
}
......@@ -303,16 +312,10 @@ static enum wrtd_status wrtd_cmd_dump_config(struct wrtd_dev *wrtd,
static enum wrtd_status wrtd_cmd_dump_cpus(struct wrtd_dev *wrtd,
int argc, char *argv[])
{
const struct wrtd_mt_config *config;
enum wrtd_status status;
int cpu;
status = wrtd_fill_config(wrtd);
WRTD_RETURN_IF_ERROR(status);
config = wrtd->config;
for (cpu = 0; cpu < config->nbr_cpus; cpu++) {
for (cpu = 0; cpu < wrtd->nbr_cpus; cpu++) {
status = disp_cpu_config(wrtd, cpu, 0, 0);
WRTD_RETURN_IF_ERROR(status);
}
......@@ -797,8 +800,8 @@ static enum wrtd_status wrtd_cmd_set_log(struct wrtd_dev *wrtd,
static struct wrtd_commands cmds[] = {
{ "dump-all", "", "shows wrtd config",
wrtd_cmd_dump_all },
{ "dump-config", "", "shows wrtd config",
wrtd_cmd_dump_config },
{ "dump-mt-config", "", "shows wrtd MT config",
wrtd_cmd_dump_mt_config },
{ "dump-cpu", "", "shows wrtd cpu",
wrtd_cmd_dump_cpus },
{ "dump-rules", "", "shows wrtd rules",
......@@ -868,8 +871,8 @@ static struct wrtd_commands cmds[] = {
static void help(void)
{
fprintf(stderr, "wrtd-in-config -D DEVICE -- COMMAND [cmd-options]\n\n");
fprintf(stderr, "It configures an input channel on a White-Rabbit Trigger-Distribution node\n\n");
fprintf(stderr, "wrtd-config -D DEVICE -- COMMAND [cmd-options]\n\n");
fprintf(stderr, "It configures a White-Rabbit Trigger-Distribution node\n\n");
fprintf(stderr, "-D\tdevice id\n");
help_commands(cmds);
exit(1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment