diff --git a/cosimulation/icarus/myhdl.c b/cosimulation/icarus/myhdl.c index 03bc1fd8..6ef93aa2 100644 --- a/cosimulation/icarus/myhdl.c +++ b/cosimulation/icarus/myhdl.c @@ -25,17 +25,16 @@ static int wpipe; static vpiHandle from_myhdl_systf_handle = NULL; static vpiHandle to_myhdl_systf_handle = NULL; -typedef struct to_myhdl_data { - vpiHandle systf_handle; - short int sync_flag; -} s_to_myhdl_data, *p_to_myhdl_data; +typedef struct cb_user_data { + char buf[MAXLINE]; +} s_cb_user_data, *p_cb_user_data; /* prototypes */ static PLI_INT32 from_myhdl_calltf(PLI_BYTE8 *user_data); static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data); -static PLI_INT32 to_myhdl_sensitivity_callback(p_cb_data cb_data); -static PLI_INT32 to_myhdl_readwrite_callback(p_cb_data cb_data); +static PLI_INT32 to_myhdl_readonly_callback(p_cb_data cb_data); static PLI_INT32 to_myhdl_delay_callback(p_cb_data cb_data); +static PLI_INT32 to_myhdl_delta_callback(p_cb_data cb_data); static int init_pipes(); @@ -126,7 +125,6 @@ static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data) s_cb_data cb_data_s; s_vpi_time time_s; s_vpi_value value_s; - p_to_myhdl_data to_myhdl_data; static int to_myhdl_flag = 0; if (to_myhdl_flag) { @@ -164,13 +162,13 @@ static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data) } buf[n] = '\0'; - // register write callback // + // register read-only callback // time_s.type = vpiSimTime; time_s.high = 0; time_s.low = 0; - cb_data_s.reason = cbReadWriteSynch; + cb_data_s.reason = cbReadOnlySynch; cb_data_s.user_data = NULL; - cb_data_s.cb_rtn = to_myhdl_readwrite_callback; + cb_data_s.cb_rtn = to_myhdl_readonly_callback; cb_data_s.obj = NULL; cb_data_s.time = &time_s; cb_data_s.value = NULL; @@ -180,7 +178,7 @@ static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data) } -static PLI_INT32 to_myhdl_readwrite_callback(p_cb_data cb_data) +static PLI_INT32 to_myhdl_readonly_callback(p_cb_data cb_data) { vpiHandle systf_handle; vpiHandle net_iter, net_handle; @@ -190,6 +188,8 @@ static PLI_INT32 to_myhdl_readwrite_callback(p_cb_data cb_data) s_cb_data cb_data_s; s_vpi_time time_s; char buf[MAXLINE]; + p_cb_user_data cb_user_data; + char bufcp[MAXLINE]; int n; char *time_high_string; char *time_low_string; @@ -199,6 +199,7 @@ static PLI_INT32 to_myhdl_readwrite_callback(p_cb_data cb_data) static int start_flag = 1; + if (start_flag) { start_flag = 0; write(wpipe, "START", 5); @@ -213,10 +214,12 @@ static PLI_INT32 to_myhdl_readwrite_callback(p_cb_data cb_data) buf[0] = '\0'; current_time.type = vpiSimTime; vpi_get_time(systf_handle, ¤t_time); - sprintf(buf, "%x%08x ", current_time.high, current_time.low); + sprintf(buf, "%xd%08x ", current_time.high, current_time.low); + vpi_printf("%d: RW trigger\n", current_time.low); value_s.format = vpiHexStrVal; while ((net_handle = vpi_scan(net_iter)) != NULL) { vpi_get_value(net_handle, &value_s); + vpi_printf("val %s\n", value_s.value.str); strcat(buf, value_s.value.str); strcat(buf, " "); } @@ -227,8 +230,11 @@ static PLI_INT32 to_myhdl_readwrite_callback(p_cb_data cb_data) return(0); } buf[n] = '\0'; - - reg_iter = vpi_iterate(vpiArgument, from_myhdl_systf_handle); + + /* save copy for later callback */ + cb_user_data = (p_cb_user_data)malloc(sizeof(s_cb_user_data)); + strcpy(cb_user_data->buf, buf); + time_high_string = strtok(buf, " "); time_low_string = strtok(NULL, " "); time_high = (PLI_UINT32) strtoul(time_high_string, (char **) NULL, 16); @@ -241,6 +247,7 @@ static PLI_INT32 to_myhdl_readwrite_callback(p_cb_data cb_data) } else { delay = time_low - current_time.low; } + vpi_printf("schedule delay callback\n"); // register cbAfterDelay callback // time_s.type = vpiSimTime; time_s.high = 0; @@ -252,33 +259,24 @@ static PLI_INT32 to_myhdl_readwrite_callback(p_cb_data cb_data) cb_data_s.time = &time_s; cb_data_s.value = NULL; vpi_register_cb(&cb_data_s); - // We're done for now - if (reg_iter != NULL) { - vpi_free_object(reg_iter); - } -/* while ((reg_handle = vpi_scan(reg_iter)) != NULL) { */ -/* value_s.value.str = strtok(NULL, " "); */ - // } return(0); } - while ((reg_handle = vpi_scan(reg_iter)) != NULL) { - value_s.value.str = strtok(NULL, " "); - vpi_put_value(reg_handle, &value_s, NULL, vpiNoDelay); - } + /* hack: emulate cbEndOfTimeSync by cbAfterDelay */ - // register myself again // + // register callback // + vpi_printf("schedule delta callback\n"); time_s.type = vpiSimTime; time_s.high = 0; - time_s.low = 0; - cb_data_s.reason = cbReadWriteSynch; - cb_data_s.user_data = NULL; - cb_data_s.cb_rtn = to_myhdl_readwrite_callback; + time_s.low = 1; + cb_data_s.reason = cbAfterDelay; + cb_data_s.user_data = (PLI_BYTE8 *) cb_user_data; + cb_data_s.cb_rtn = to_myhdl_delta_callback; cb_data_s.obj = NULL; cb_data_s.time = &time_s; cb_data_s.value = NULL; vpi_register_cb(&cb_data_s); - + vpi_printf("scheduled delta callback\n"); return(0); } @@ -287,15 +285,58 @@ static PLI_INT32 to_myhdl_delay_callback(p_cb_data cb_data) s_cb_data cb_data_s; s_vpi_time time_s; s_vpi_time current_time; + vpi_printf("Got here delta \n"); vpi_get_time(NULL, ¤t_time); - // register readwrite callback // + // register readonly callback // time_s.type = vpiSimTime; time_s.high = 0; time_s.low = 0; cb_data_s.reason = cbReadWriteSynch; cb_data_s.user_data = NULL; - cb_data_s.cb_rtn = to_myhdl_readwrite_callback; + cb_data_s.cb_rtn = to_myhdl_readonly_callback; + cb_data_s.obj = NULL; + cb_data_s.time = &time_s; + cb_data_s.value = NULL; + vpi_register_cb(&cb_data_s); + return(0); +} + +static PLI_INT32 to_myhdl_delta_callback(p_cb_data cb_data) +{ + s_cb_data cb_data_s; + s_vpi_time time_s; + s_vpi_time current_time; + p_cb_user_data cb_user_data; + vpiHandle systf_handle; + vpiHandle reg_iter, reg_handle; + s_vpi_value value_s; + + vpi_printf("Got here delta \n"); + cb_user_data = (p_cb_user_data)cb_data->user_data; + + /* skip time values */ + strtok(cb_user_data->buf, " "); + strtok(NULL, " "); + + reg_iter = vpi_iterate(vpiArgument, from_myhdl_systf_handle); + + while ((value_s.value.str = strtok(NULL, " ")) != NULL) { + reg_handle = vpi_scan(reg_iter); + vpi_put_value(reg_handle, &value_s, NULL, vpiNoDelay); + } + if (reg_iter != NULL) { + vpi_free_object(reg_iter); + } + + vpi_get_time(NULL, ¤t_time); + // register readonly callback // + time_s.type = vpiSimTime; + time_s.high = 0; + time_s.low = 0; + cb_data_s.reason = cbReadWriteSynch; + cb_data_s.user_data = NULL; + cb_data_s.cb_rtn = to_myhdl_readonly_callback; cb_data_s.obj = NULL; cb_data_s.time = &time_s; cb_data_s.value = NULL; diff --git a/cosimulation/icarus/test/test_all.py b/cosimulation/icarus/test/test_all.py index e64ed3d5..6a0ca1a7 100644 --- a/cosimulation/icarus/test/test_all.py +++ b/cosimulation/icarus/test/test_all.py @@ -30,6 +30,8 @@ sys.path.append("../../test") import test_bin2gray, test_inc modules = (test_bin2gray, test_inc) +modules = (test_bin2gray, ) +modules = (test_inc, ) import unittest diff --git a/cosimulation/test/test_inc.py b/cosimulation/test/test_inc.py index 844df421..499f7ad8 100644 --- a/cosimulation/test/test_inc.py +++ b/cosimulation/test/test_inc.py @@ -2,10 +2,12 @@ from __future__ import generators import unittest from unittest import TestCase +import random from random import randrange +random.seed(2) from myhdl import Simulation, StopSimulation, Signal, \ - delay, intbv, negedge, posedge + delay, intbv, negedge, posedge, now from inc import inc @@ -44,9 +46,9 @@ class TestInc(TestCase): while 1: yield posedge(clock) if enable: - expect = (count + 1) % n + expect = (expect + 1) % n yield delay(1) - print "count %s expect %s" % (count, expect) + print "%d count %s expect %s" % (now(), count, expect) # self.assertEqual(count, expect) Simulation(clockGen(), stimulus(), INC_1, check()).run(quiet=1) diff --git a/cosimulation/test/verilog/bin2gray.v b/cosimulation/test/verilog/bin2gray.v index 21c731c9..1a655f0a 100644 --- a/cosimulation/test/verilog/bin2gray.v +++ b/cosimulation/test/verilog/bin2gray.v @@ -12,7 +12,7 @@ module bin2gray(B, G); always @(extB) begin // $display("Ver B %D", extB); for (i=0; i < width; i=i+1) - G[i] = extB[i+1] ^ extB[i]; + G[i] <= extB[i+1] ^ extB[i]; end endmodule // bin2gray diff --git a/cosimulation/test/verilog/inc.v b/cosimulation/test/verilog/inc.v index 54ace389..929404f0 100644 --- a/cosimulation/test/verilog/inc.v +++ b/cosimulation/test/verilog/inc.v @@ -7,7 +7,12 @@ module inc(count, enable, clock, reset); output [15:0] count; reg [15:0] count; + initial + count = 0; + + always @(posedge clock or negedge reset) begin + $display("Always triggered: count %d", count); if (reset == 0) begin count <= 0; end @@ -17,6 +22,12 @@ module inc(count, enable, clock, reset); end // $display("count %d", count); end + end // always @ (posedge clock or negedge reset) + + always @ (count) begin + $display("%d count %d", $time, count); end + + endmodule // inc diff --git a/myhdl/Cosimulation.py b/myhdl/Cosimulation.py index 9ff7d23e..e727f593 100644 --- a/myhdl/Cosimulation.py +++ b/myhdl/Cosimulation.py @@ -81,6 +81,7 @@ class Cosimulation(object): self._toSigs = toSigs = [] self._hasChange = 0 + self._isActive = 0 child_pid = self._child_pid = os.fork() @@ -139,7 +140,7 @@ class Cosimulation(object): def _get(self): s = os.read(self._rt, _MAXLINE) - # print "Reading " + s + print "Reading " + s if not s: raise SimulationEndError e = s.split() @@ -157,12 +158,15 @@ class Cosimulation(object): if t[-1] == 'L': t = t[:-1] # strip trailing L t = (9 - len(t)) * '0' + t # zero-extend to more than 32 bits - buf = t[:-8] + " " + t[-8:] + " " # high and low time - for s in self._fromSigs: - buf += hex(s)[2:] - buf += " " + buf = t[:-8] + " " + t[-8:] # high and low time # print "clear change" - self._hasChange = 0 + if self._isActive: + self._isActive -= 1 + if self._hasChange: + self._hasChange = 0 + for s in self._fromSigs: + buf += " " + buf += hex(s)[2:] # print "Writing " + buf os.write(self._wf, buf) @@ -170,8 +174,10 @@ class Cosimulation(object): sigs = tuple(self._fromSigs) while 1: yield sigs + # print sigs # print "detected change" self._hasChange = 1 + self._isActive = 3 def __del__(self): """ Clear flag when this object destroyed - to suite unittest. """ diff --git a/myhdl/Simulation.py b/myhdl/Simulation.py index 4a346715..923a2ba3 100644 --- a/myhdl/Simulation.py +++ b/myhdl/Simulation.py @@ -130,7 +130,9 @@ class Simulation(object): # print _siglist if cosim: cosim._get() - if _siglist or cosim._hasChange: + if _siglist or cosim._isActive: +## if cosim._isActive: + print "CA:" + ` cosim._isActive` + " S:" + `_siglist` cosim._put(t) continue elif _siglist: diff --git a/myhdl/test_Cosimulation.py b/myhdl/test_Cosimulation.py index 980438d4..3c97393f 100644 --- a/myhdl/test_Cosimulation.py +++ b/myhdl/test_Cosimulation.py @@ -201,6 +201,7 @@ class CosimulationTest(TestCase): def testFromSignalVals(self): cosim = Cosimulation(exe + ".cosimFromSignalVals", **allSigs) os.read(cosim._rt, MAXLINE) + cosim._hasChange = 1 cosim._put(0) def cosimFromSignalVals(self):