Generate specific clock slow down the simulation - clock

I have to generate multiple clock in my top (testbench).
The simulation ran ok until I added the following code:
initial begin
tb_pcie_clk_q0p = 1'b0;
forever begin
#5ns; //100MHz (half cycle)
tb_pcie_clk_q0p = ~tb_pcie_clk_q0p;
end
end
assign tb_pcie_clk_q0n = ~tb_pcie_clk_q0p;
In addition I have already had other clocks like:
initial begin
tb_fpga_clk = 1'b0;
forever begin
#4ns; //125 MHz
tb_fpga_clk = ~tb_fpga_clk;
end
end
assign tb_clk = dut.clk_rst_ctrl_i.clk_250;

I am not sure how much your simulation slows down exactly from your comment but I would imagine new clock would exercise more codes in your design and test bench which would impact the simulation performance. I think most of simulator supports to generate simulation profile so you can analysis which portions of code slows down.

Related

is Sql.execute() synchronous or asynchronous with groovy?

I stumbled onto a bit of groovy code deleting rows from a database by batches of a given size:
for (int index = 0; index <= loopCnt; index++) {
sql.execute("DELETE TOP(" + maxEntriesToDeleteAtOnce + ") FROM LoaderQueue WHERE Status = ? AND LastUpdated < ?", stateToDelete, date)
}
I have 0 experience with groovy, and I know that the delete statement can take a few seconds to be fully executed, even if the batch size is relatively small. I'm wondering if the execution will wait for each statement to be completed before looping , or if we might send a few statements in parallel ? In short I'm wondering if the sql.execute() command is synchronous
I can't really try anything yet as there is no DEV environment for the application involved.

GPS data blocked by other tasks in the while loop

I am trying to parse GPS data while reading pressure sensor, IMU sensor and writing some data to SD card. Since reading pressure sensor, IMU sensor and writing SD card takes some time and GPS don't wait my command to send its data, I lost some GPS data so my parser can not find meaningful message. I use uart_receive interrupt to take GPS data and circular buffer to save its data. After I parse it. Since I don't know how much bytes come from GPS, I read one by one. I tried FreeRTOS but it did not work. How can I prevent other tasks to block GPS data. I am using STM32f401cc.
Here is my FreeRTOS task;
void StartDefaultTask(void* argument)
{
IMU_setParameters(&imu, &hi2c1, imu_ADD_LOW, GPIOB, GPIOB,
GPIO_PIN_1, GPIO_PIN_2);
IMU_init(&imu, &htim3);
while ((calState.accel != 3 || calState.system != 3 || calState.gyro != 3 || calState.mag != 3) && calibFlg)
{
IMU_getCalibrationState(&imu, &calState);
}
preSensor_init_default_params(&preSensor.params);
preSensor.addr = preSensor_I2C_ADDRESS_1;
preSensor.i2c = &hi2c1;
preSensor_init(&preSensor, &preSensor.params);
initSD_CARD(&USERFatFS, USERPath);
samplePacket(&telemetry);
controlRecoveryFile(&recoveryFile, "recoveryFile.txt", &telemetry);
for (;;)
{
IMU_getDatas(&imu, &calState, &linearAccel, &IMU, &imuFlg, &offsetFlg, &calibCount);
preSensor_force_measurement(&preSensor);
preSensor_read_float(&preSensor, &temperature, &pressure, &humidty);
preSensor_get_height(pressure, &height);
telemetry.Altitude_PL = height;
telemetry.Pressure_PL = pressure;
telemetry.Temperature = temperature;
telemetry.YRP[0] = IMU.yaw;
telemetry.YRP[1] = IMU.roll;
telemetry.YRP[2] = IMU.pitch;
if (calibCount % 10 == 0)
{
writoToTelemetryDatas(&logFile, "tulparLog.txt", &telemetry, 0);
if (!writeToRecoveryDatas(&recoveryFile, "recoveryFile.txt", &telemetry))
connectionFlg = 1;
}
osDelay(1);
}
}
void StartTask02(void* argument)
{
arrangeCircularBuffer(&gpsCircular, buffer, BUFFER_LENGTH);
initGPS(&huart1, &rDATA, &gps);
for (;;)
{
getGPSdata(&huart1, &gpsCircular, &gps, &rDATA);
osDelay(1);
}
}
Here is my solution to problem.
First of all I do not use FreeRtos at all. I do all the thing in main loop. Problem is "Race Condition". In my GPS data parser, there are 4 states. MSG_ID, Finish, Check, Parse. These four states do not take four loops to find meaningfull message. It depends on message length. It can be at most 103 loop. Besides, In main loop my imu sensor, pressure sensor and SD card module takes approximately 80 ms. As you know, GPS works independent from our code. It does not wait our command to send data. Every 1 second it sends its datas. Now, imagine that your GPS sends datas every 1 seconds and your CircularBuffer has 200 bytes. Your parser begin to parse message. But your parser needs at least 30+ loops to find message. Now, 30*80 = 2400 ms (2.4 s). Untill you find meaningfull data GPS sent 2 more datas and overflow happened. To fix this situation, I write for loop for my GPS parser in the main loop and I send command to GPS for just taking GPGGA and GPRMC datas (for GPS command you can look at here. I use uart_receive_ınterrupt to store data to my circularbuffer. After taking 2 '\n', I stop taking data and wait my parser to parse these datas. At the end I start uart operation taking meaningfull datas. Important thing here is calling parser in a for loop. (it can be 8-16-24 loops depends on your other tasks delay)

Running Things in Parallel with SAS Enterprise Guide

Good afternoon, Stack Overflow gods and goddesses. I have a question about running code in SAS Enterprise Guide 7.1 in parallel.
Currently, I have 5 small PROC SQLs running in a project. The code runs fine, but it executes in series (IE: One at a time) and even though I have each piece broken out in an individual section, I can't seem to get all 5 to run at once. For example, take the code below:
PROC SQL;
connect to Oracle (user = "&Oracle_ID." password = "&Oracle_PW." path = "&Oracle_Path.");
Create table place.base_balance_data as select * from connection to Oracle (
Select
DEBR.Acct_Ref_Id
,case when DEBR.Acct_Typ_Cd = '2' and DEBR.Settle_Dt_Bal_Amt > 0
then sum(settle_dt_bal_amt)
else sum(0)
end as Typ_2_Settle_Dt_Bal_Amt
,case when DEBR.Acct_Typ_Cd = '5' and DEBR.Settle_Dt_Bal_Amt > 0
then sum(settle_dt_bal_amt)
else sum(0)
end as Typ_5_Settle_Dt_Bal_Amt
,case when DEBR.Acct_Typ_Cd = '1' and DEBR.Settle_Dt_Bal_Amt < 0
then sum(settle_dt_bal_amt)
else sum(0)
end as Typ_1_Settle_Dt_Bal_Amt
,case when DEBR.Acct_Typ_Cd = '1' and DEBR.Settle_Dt_Bal_Amt < 0
then sum(Csh_Free_Cr_Amt)
else sum(0)
end as Csh_Free_Cr_Amt
,case when DEBR.Acct_Typ_Cd = '1' and DEBR.Settle_Dt_Bal_Amt < 0
then coalesce(DEBR.Cr_Avbl_Amt,0)
end as Credit_Aval_Amt
From Cool.DataStuff DEBR
Where DEBR.Date_ID = &lm_bus_dID.
Group by DEBR.Acct_Ref_Id, DEBR.Acct_Typ_Cd, DEBR.Cr_Avbl_Amt, DEBR.Settle_Dt_Bal_Amt
Order by DEBR.Acct_Ref_ID asc offset 0 rows
);
Disconnect from Oracle;
Currently, the EG project looks like this:
I'm trying desperately to get all 5 of those pieces on the right to run at the same time, but alas, every time I try to do that, I get errors involving the passing of macro variables and not being able to connect to multiple sessions.
Has anyone had any luck doing this before? Could you maybe tell me what I'm missing here?
Thanks!
If you have SAS/CONNECT installed, you can break everything out into rsubmit blocks that will all run in parallel. You can ensure that each session gets the required macro vars using %syslput.
When running things in rsubmit blocks, think of each block as its own unique, independent worker session that's running code - almost like a thread. This worker lives in its own world and only knows what is in its session. The main session which kicked off the worker sessions is free to do whatever it pleases while the workers perform their specific tasks.
Below is an example of how to set this up.
Setup code
This will handle signing on to a metadata server in a new session automatically and make all code run asynchronously.
options autosignon=yes
sascmd='!sascmd'
connectwait=no
;
Create Macro Variables and pass them to your worker sessions
This will do two things:
Start a new asynchronous session
Send your macro variables from your main session to your worker session
..
<code to create macro vars>;
/* Send macro variables over to a new remote session */
%syslput mymacrovar / remote=worker1;
...
If you want to, you can use %syslput _USER_ / remote=worker1 to send all user-made macro variables to a new session.
Enclose all worker code in rsubmit blocks
libname workmain "%sysfunc(getoption(work))";
rsubmit remote=worker1 inheritlib=(<my libraries here> workmain);
<code here>;
endrsubmit;
Note the libname statement, workmain. rsubmit cannot inherit the work library of the main session. This is by design since each of these sessions have their own work library whose name cannot be overwritten. You can get around it by creating a new library that points to your main session's work library.
Wait for everything to finish
Finally, you can add one last piece of code to wait for everything to finish up - or, you're free to have the main thread run more independent light tasks.
waitfor _ALL_;

Unable to exit while loop in UVM monitor

This might be a silly mistake from my side that I have overlooked but I'm fairly new to UVM and I tried tinkering with my code for a while before this. I'm trying to send in a stream of 8 bit data within a packet using Data valid stall protocol from my UVM driver to the DUT. I'm facing an issue with my input monitor not being able to pick up these transactions that are driven.
I have a while loop with a condition that the valid bit must be high and the stall bit should be low. As long as this condition holds good, the monitor needs to pick up the data byte and push into the queue. I know for a fact that the data is being picked up and pushed to a queue as I used $display statements along the way. The problem is arising once all the data bytes are received and the valid bit goes low. Ideally, this should cause the exit from the while loop but isn't doing so. Any help here would be appreciated. I have attached a snippet of the code below. Thanks in advance.
virtual task main_phase (uvm_phase phase);
$display("Run phase of input monitor");
collect_transfer();
endtask: main_phase
virtual task collect_transfer();
fork
forever begin
wait_for_valid_transaction_cycle();
create_and_populate_pkt();
broadcast_pkt();
#(iP0_vif.cb_iP0_MON);
end
join_none
endtask: collect_transfer
virtual task wait_for_valid_transaction_cycle();
wait(iP0_vif.cb_iP0_MON.ip_valid && ~iP0_vif.cb_iP0_MON.ip_stall);
endtask: wait_for_valid_transaction_cycle
virtual task create_and_populate_pkt();
pkt = Router_seq_item :: type_id :: create("pkt");
pkt.valid = iP0_vif.cb_iP0_MON.ip_valid;
pkt.sop = iP0_vif.cb_iP0_MON.ip_sop;
$display("before data collection");
while(iP0_vif.cb_iP0_MON.ip_valid === `HIGH && iP0_vif.cb_iP0_MON.ip_stall === `LOW) begin
$display("After checking for stall");
pkt.data = iP0_vif.cb_iP0_MON.ip_data;
$display(pkt.data);
pkt.data_q.push_front(pkt.data);
pkt.eop = iP0_vif.cb_iP0_MON.ip_eop;
$display("print check in input monitor # time = %0t", $time);
#(iP0_vif.cb_iP0_MON);
end
$display("before printing input packet from monitor");
Check_for_port_route_and_populate_packet_field(pkt);
print_packet(pkt);
endtask: create_and_populate_pkt
The $display statement "before printing input packet from monitor" is not being displayed.
HIGH is defined as a binary 1 and LOW is defined as a binary 0.
The output of the code in terms of display statements is as below.
before data collection
before checking for stall
After checking for stall
2
print check in input monitor # time = 105
before checking for stall
After checking for stall
1
print check in input monitor # time = 115
before checking for stall
After checking for stall
3
print check in input monitor # time = 125
It's possible that the main phase objection is being dropped elsewhere in your environment. UVM will automatically kill any threads that were spawned during a phase when it ends.
To fix this, do not object to the main phase in your monitor. Objecting to that phase is the responsibility of the threads creating the stimulus. Instead, you should be launching this monitor during the run_phase, which will ensure that your loop is not killed until the end of simulation.
Also, during the shutdown phase, you will want your monitor to object whenever it is currently seeing a packet. This will ensure that simulation doesn't end as soon as stimulus has been sent in, giving your other monitors time to collect responses from the DUT.

Using multiple threads for DB updates results in higher write time per update

So I have a script that is supposed to update a giant table (Postgres). Since the table has about 150m rows and I want to complete this as fast as possible, using multiple threads seemed like a perfect answer. However, I'm seeing something very weird.
When I use a single thread, the write time to an update is much much lower than when I use multiple threads.
require 'sequel'
.....
DB = Sequel.connect(DB_CREDS)
queue = Queue.new
read_query = query = DB["
SELECT id, extra_fields
FROM objects
WHERE XYZ IS FALSE
"]
read_query.use_cursor(:rows_per_fetch => 1000).each do |row|
queue.push(row)
end
Up until this point, IMO it shouldn't matter because we're just reading stuff from the DB and it has nothing to do with writing. From here, I've tried two approaches. Single-threaded and Multi-threaded.
NOTE - This is not the actual UPDATE query that I want to execute, it's just a pseudo one for demonstration purposes. The actual query is a lot longer and plays with JSON and stuff so I can't really update the entire table using a single query.
Single-threaded
until queue.empty?
photo = queue.shift
id = photo[:id]
update_query = DB["
UPDATE objects
SET XYZ = TRUE
WHERE id = #{id}
"]
result = update_query.update
end
If I execute this, I see in my DB logs that each update query takes time less than 0.01 seconds
I, [2016-08-15T10:45:48.095324 #54495] INFO -- : (0.001441s) UPDATE
objects SET XYZ = TRUE WHERE id = 84395179
I, [2016-08-15T10:45:48.103818 #54495] INFO -- : (0.008331s) UPDATE
objects SET XYZ = TRUE WHERE id = 84395181
I, [2016-08-15T10:45:48.106741 #54495] INFO -- : (0.002743s) UPDATE
objects SET XYZ = TRUE WHERE id = 84395182
Multi-threaded
MAX_THREADS = 5
num_threads = 0
all_threads = []
until queue.empty?
if num_threads < MAX_THREADS
photo = queue.shift
num_threads += 1
all_threads << Thread.new {
id = photo[:id]
update_query = DB["
UPDATE photos
SET cv_tagged = TRUE
WHERE id = #{id}
"]
result = update_query.update
num_threads -= 1
Thread.exit
}
end
end
all_threads.each do |thread|
thread.join
end
Now, in theory it should be faster right? But each update takes about 0.5 seconds. I'm so surprised what that is the case.
I, [2016-08-15T11:02:10.992156 #54583] INFO -- : (0.414288s)
UPDATE objects
SET XYZ = TRUE
WHERE id = 119498834
I, [2016-08-15T11:02:11.097004 #54583] INFO -- : (0.622775s)
UPDATE objects
SET XYZ = TRUE
WHERE id = 119498641
I, [2016-08-15T11:02:11.097074 #54583] INFO -- : (0.415521s)
UPDATE objects
SET XYZ = TRUE
WHERE id = 119498826
Any ideas on -
Why this is happening?
How can I increase the update speed for multiple threads approach.
Have you configured Sequel so that it has a connection pool of 5 connections?
Have you considered doing multiple updates per call via an IN clause?
If you haven't done 1, you have N threads fighting over N-n connections, which equates to resource starvation, which is a classic concurrency issue.
Your example can be reduced to: DB[:objects].where(:XYZ=>false).update(:XYZ=>true)
I'm guessing your actual need is not that simple. But the same approach may still work. Instead of issuing a query per row, use a single query to update all related rows.
I went through something similar on a project ("import all history from a legacy database into a new one with completely different structure and organization"). Unless you managed to shoot yourself in the foot somewhere else, you have 2 basic bottlenecks to look for:
the database's disk IO
the ruby process' CPU
Some suggestions,
database IO: use DB transactions, update 1000 records per transaction (you can tweak the exact number but 1000 is usually good) - huge DB table usually means a lot of indexes too, every couple of update actions will trigger a REINDEX and AUTOVACUUM actions within the DB which will result in a significant drop of update speed, a transaction basically allows you to push a 1000 updated records without REINDEX and AUTOVACUUM and then perform both actions, the result is MUCH faster (something like an order of magnitude)
database IO: change indexes, drop every index you can live without during the update process, ideally you will have only 1 very streamlined index which allows unique row lookups for update purposes
ruby CPU: unless you are using JRuby or Rubinius, or REALLY paying the price of network latency to your DB, threads will do you no big benefit, use fork/processes (see GIL). You did a great job choosing Sequel over AR for this
ruby CPU: if you decide to go threads + JRuby with this don't forget to try and plug in jProfiler, it's amazing at tracing bottlenecks in Java and author of SideKiq swears it is amazing for JRuby too - unfortunately, afaik, there is no equivalent of jProfiler for C Ruby (there are profiling tools, but nowhere as useful)
After you implement these suggestions you know you did all you could when:
all of the CPUs on the Ruby box are on 100% load
the hard disk IO of the DB is on 100% throughput
Find this sweet spot and don't add additional ruby update threads/processes after that (or add more hardware) and that's that
PS check out https://github.com/ruby-concurrency/concurrent-ruby - it's a great parallelization lib