-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Experimental support for Xyce co-simulation (#184)
- Loading branch information
Showing
14 changed files
with
673 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ compile_flags.txt | |
results.xml | ||
obj_dir | ||
.pytest_cache | ||
*.mt0 | ||
|
||
# queues | ||
queue-* | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Copyright (c) 2024 Zero ASIC Corporation | ||
# This code is licensed under Apache License 2.0 (see LICENSE for details) | ||
|
||
.PHONY: verilator | ||
verilator: | ||
./test.py --tool verilator | ||
|
||
.PHONY: icarus | ||
icarus: | ||
./test.py --tool icarus | ||
|
||
.PHONY: clean | ||
clean: | ||
rm -f queue-* *.q | ||
rm -f *.mt0 | ||
rm -f *.vcd *.fst *.fst.hier | ||
rm -rf obj_dir build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
RC circuit | ||
|
||
* Copyright (c) 2024 Zero ASIC Corporation | ||
* This code is licensed under Apache License 2.0 (see LICENSE for details) | ||
|
||
* voltage input | ||
YDAC DAC0 in 0 simpleDAC | ||
.model simpleDAC DAC (tr=5e-9 tf=5e-9) | ||
|
||
Rin in out 10k | ||
Cout out 0 10p | ||
|
||
* voltage output | ||
.measure tran ADC0 EQN V(out) | ||
|
||
.TRAN 0 1 | ||
|
||
.END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#!/usr/bin/env python3 | ||
|
||
# Example illustrating mixed-signal simulation | ||
|
||
# Copyright (c) 2024 Zero ASIC Corporation | ||
# This code is licensed under Apache License 2.0 (see LICENSE for details) | ||
|
||
from argparse import ArgumentParser | ||
from switchboard import SbDut | ||
|
||
|
||
def main(fast=False, period=10e-9, tool='verilator'): | ||
# build the simulator | ||
dut = SbDut(tool=tool, default_main=True, xyce=True) | ||
dut.input('testbench.sv') | ||
dut.build(fast=fast) | ||
|
||
# start chip simulation | ||
chip = dut.simulate(period=period) | ||
|
||
chip.wait() | ||
|
||
|
||
if __name__ == '__main__': | ||
parser = ArgumentParser() | ||
parser.add_argument('--fast', action='store_true', help='Do not build' | ||
' the simulator binary if it has already been built.') | ||
parser.add_argument('--tool', default='verilator', choices=['icarus', 'verilator'], | ||
help='Name of the simulator to use.') | ||
parser.add_argument('--period', type=float, default=10e-9, | ||
help='Period of the oversampling clock') | ||
args = parser.parse_args() | ||
|
||
main(fast=args.fast, period=args.period, tool=args.tool) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright (c) 2024 Zero ASIC Corporation | ||
// This code is licensed under Apache License 2.0 (see LICENSE for details) | ||
|
||
module testbench ( | ||
`ifdef VERILATOR | ||
input clk | ||
`endif | ||
); | ||
// clock | ||
|
||
`ifndef VERILATOR | ||
timeunit 1s; | ||
timeprecision 1fs; | ||
|
||
real period = 10e-9; | ||
initial begin | ||
$value$plusargs("period=%f", period); | ||
end | ||
|
||
reg clk; | ||
always begin | ||
clk = 1'b0; | ||
#(0.5 * period); | ||
clk = 1'b1; | ||
#(0.5 * period); | ||
end | ||
`endif | ||
|
||
xyce_intf xyce_intf_i (); | ||
|
||
real in = 0.0; | ||
real out = 0.0; | ||
|
||
integer bits = 0; | ||
integer count = 0; | ||
always @(posedge clk) begin | ||
if (count + 1 == 10) begin | ||
count <= 0; | ||
in = 1.0 - in; | ||
if (bits + 1 == 10) begin | ||
$finish; | ||
end else begin | ||
bits <= bits + 1; | ||
end | ||
end else begin | ||
count <= count + 1; | ||
end | ||
end | ||
|
||
always @(in) begin | ||
xyce_intf_i.put("DAC0", in); | ||
end | ||
|
||
always @(clk) begin | ||
xyce_intf_i.get("ADC0", out); | ||
end | ||
|
||
// Initialize | ||
|
||
initial begin | ||
/* verilator lint_off IGNOREDRETURN */ | ||
xyce_intf_i.init("rc.cir"); | ||
/* verilator lint_on IGNOREDRETURN */ | ||
end | ||
|
||
// Waveforms | ||
|
||
initial begin | ||
if ($test$plusargs("trace")) begin | ||
$dumpfile("testbench.vcd"); | ||
$dumpvars(0, testbench); | ||
end | ||
end | ||
|
||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// Copyright (c) 2024 Zero ASIC Corporation | ||
// This code is licensed under Apache License 2.0 (see LICENSE for details) | ||
|
||
#include <map> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#include <N_CIR_XyceCInterface.h> | ||
|
||
class XyceIntf { | ||
public: | ||
XyceIntf() {} | ||
|
||
~XyceIntf() { | ||
if (m_opened) { | ||
xyce_close(m_xyceObj); | ||
} | ||
|
||
if (m_xyceObj) { | ||
free(m_xyceObj); | ||
} | ||
} | ||
|
||
void init(std::string file) { | ||
// pointer to N_CIR_Xyce object | ||
m_xyceObj = (void**)malloc(sizeof(void* [1])); | ||
|
||
// xyce command | ||
char* argList[] = {(char*)("Xyce"), (char*)("-quiet"), (char*)file.c_str()}; | ||
int argc = sizeof(argList) / sizeof(argList[0]); | ||
char** argv = argList; | ||
|
||
// Open N_CIR_Xyce object | ||
xyce_open(m_xyceObj); | ||
m_opened = true; | ||
|
||
// Initialize N_CIR_Xyce object | ||
xyce_initialize(m_xyceObj, argc, argv); | ||
m_initialized = true; | ||
|
||
// Simulate for a small amount of time | ||
xyce_simulateUntil(m_xyceObj, 1e-10, &m_simTime); | ||
} | ||
|
||
void put(std::string name, double time, double value) { | ||
if (!m_time.count(name)) { | ||
m_time[name] = std::vector<double>(); | ||
} | ||
|
||
m_time[name].push_back(time); | ||
|
||
if (!m_value.count(name)) { | ||
m_value[name] = std::vector<double>(); | ||
} | ||
|
||
m_value[name].push_back(value); | ||
|
||
// TODO: prune old values for higher performance? | ||
|
||
if (m_initialized) { | ||
std::string fullName = "YDAC!" + name; | ||
|
||
xyce_updateTimeVoltagePairs(m_xyceObj, (char*)fullName.c_str(), m_time[name].size(), | ||
m_time[name].data(), m_value[name].data()); | ||
} | ||
} | ||
|
||
void get(std::string name, double time, double* value) { | ||
if (m_initialized) { | ||
// advance simulation if necessary | ||
if (time > m_simTime) { | ||
int status = xyce_simulateUntil(m_xyceObj, time, &m_simTime); | ||
} | ||
|
||
// read out the value | ||
xyce_obtainResponse(m_xyceObj, (char*)name.c_str(), value); | ||
} | ||
} | ||
|
||
private: | ||
void** m_xyceObj; | ||
double m_simTime; | ||
bool m_opened; | ||
bool m_initialized; | ||
std::map<std::string, std::vector<double>> m_time; | ||
std::map<std::string, std::vector<double>> m_value; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright (c) 2024 Zero ASIC Corporation | ||
// This code is licensed under Apache License 2.0 (see LICENSE for details) | ||
|
||
#include "svdpi.h" | ||
|
||
#include <string> | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#include "xyce.hpp" | ||
|
||
// function definitions | ||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
extern void pi_sb_xyce_init(char* file); | ||
extern void pi_sb_xyce_put(char* name, double time, double value); | ||
extern void pi_sb_xyce_get(char* name, double time, double* val); | ||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
XyceIntf x; | ||
|
||
void pi_sb_xyce_init(char* file) { | ||
x.init(std::string(file)); | ||
} | ||
|
||
void pi_sb_xyce_put(char* name, double time, double value) { | ||
x.put(std::string(name), time, value); | ||
} | ||
|
||
void pi_sb_xyce_get(char* name, double time, double* value) { | ||
x.get(std::string(name), time, value); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.