SystemVerilog.sv
The Verilog target in SystemVerilog dress, built against the 2012 standard.
`include "icore_defs.svh"
module DPT_Feedback_Discrete (
input logic clk,
input logic rst,
input logic signed [`ICORE_WIDTH-1:0] blk2_gain [1][1],
input logic signed [`ICORE_WIDTH-1:0] in_sig0 [1][1],
output logic signed [`ICORE_WIDTH-1:0] sig0 [1][1],
output logic signed [`ICORE_WIDTH-1:0] sig1 [1][1],
output logic signed [`ICORE_WIDTH-1:0] sig2 [1][1],
output logic signed [`ICORE_WIDTH-1:0] sig3 [1][1],
output logic signed [`ICORE_WIDTH-1:0] sig4 [1][1]
);
function automatic real to_real(logic signed [`ICORE_WIDTH-1:0] v);
return $itor(v) / (2.0 ** `ICORE_FRAC_BITS);
endfunction
function automatic logic signed [`ICORE_WIDTH-1:0] to_fx(real v);
return $rtoi(v * (2.0 ** `ICORE_FRAC_BITS) + (v >= 0.0 ? 0.5 : -0.5));
endfunction
function automatic int fx_to_int(logic signed [`ICORE_WIDTH-1:0] v);
return v >>> `ICORE_FRAC_BITS;
endfunction
logic signed [`ICORE_WIDTH-1:0] w_sig0 [1][1];
logic signed [`ICORE_WIDTH-1:0] w_sig1 [1][1];
logic signed [`ICORE_WIDTH-1:0] w_sig2 [1][1];
logic signed [`ICORE_WIDTH-1:0] w_sig3 [1][1];
logic signed [`ICORE_WIDTH-1:0] w_sig4 [1][1];
logic signed [2*`ICORE_WIDTH-1:0] acc;
logic signed [`ICORE_WIDTH-1:0] uh_blk3 [0:0][0:0];
logic signed [`ICORE_WIDTH-1:0] yh_blk3 [0:0][0:0];
always_ff @(posedge clk) begin
if (rst) begin
sig0[0][0] <= 0;
sig1[0][0] <= 0;
sig2[0][0] <= 0;
sig3[0][0] <= 0;
sig4[0][0] <= 0;
uh_blk3[0][0] <= 0;
yh_blk3[0][0] <= 0;
end else begin
w_sig0[0][0] = sig0[0][0];
w_sig1[0][0] = sig1[0][0];
w_sig2[0][0] = sig2[0][0];
w_sig3[0][0] = sig3[0][0];
w_sig4[0][0] = sig4[0][0];
acc = 0;
// blk0: ICore Blocks/Home/DPT_Feedback_Discrete/In1
w_sig0[0][0] = in_sig0[0][0];
// blk1: ICore Blocks/Home/DPT_Feedback_Discrete/Error
w_sig1[0][0] = $signed(w_sig0[0][0]) - $signed(w_sig3[0][0]);
// blk2: ICore Blocks/Home/DPT_Feedback_Discrete/Ctrl_Gain
acc = $signed(w_sig1[0][0]) * $signed(blk2_gain[0][0]);
w_sig2[0][0] = acc >>> `ICORE_FRAC_BITS;
// blk3: ICore Blocks/Home/DPT_Feedback_Discrete/Plant
acc = 0;
acc = acc + $signed(to_fx(0)) * $signed(w_sig2[0][0]);
acc = acc + $signed(to_fx(0.40000000000000002)) * $signed(uh_blk3[0][0]);
acc = acc - $signed(to_fx(-0.59999999999999998)) * $signed(yh_blk3[0][0]);
w_sig3[0][0] = acc >>> `ICORE_FRAC_BITS;
uh_blk3[0][0] <= w_sig2[0][0];
yh_blk3[0][0] <= acc >>> `ICORE_FRAC_BITS;
// blk4: ICore Blocks/Home/DPT_Feedback_Discrete/Out1
w_sig4[0][0] = w_sig3[0][0];
sig0[0][0] <= w_sig0[0][0];
sig1[0][0] <= w_sig1[0][0];
sig2[0][0] <= w_sig2[0][0];
sig3[0][0] <= w_sig3[0][0];
sig4[0][0] <= w_sig4[0][0];
end
end
initial begin
sig0[0][0] = 0;
sig1[0][0] = 0;
sig2[0][0] = 0;
sig3[0][0] = 0;
sig4[0][0] = 0;
end
endmodule
What Deploy writes for the reference model below, with only the file's
header banner removed. Identical structure to the Verilog export, written against 2012: signals are 2-D unpacked
arrays instead of packed buses, the process is always_ff, and the fixed-point
helpers are automatic functions. The arithmetic - double-width acc,
shift by ICORE_FRAC_BITS - is the same, so the two targets agree bit for bit.
From the diagram to your SystemVerilog build.
Deploy writes the folder, ICore checks it against the simulation, and your code calls it once per sample.
Deploy writes
icore_defs.svh<name>.sv<name>_tb.svMakefile (Icarus, -g2012)
Built, run and compared
Built with Icarus Verilog with -g2012, run across the simulation window and compared with the solver sample by sample, against a 1 % tolerance.
One call, one sample
Numbers are Q16.16 fixed point, and 749 of 806 library blocks export to SystemVerilog.
one clk edge = one sampleWhere SystemVerilog fits.
Same shape as the Verilog export - a clocked module, a testbench, shared definitions
in icore_defs.svh - emitted as SystemVerilog and built with Icarus in
-g2012 mode.
Signals are Q16.16, so the same fixed-point notes apply: the residual is quantisation-bound, not a codegen error. Choose this over plain Verilog when the rest of your project is SystemVerilog and you would rather not mix dialects in one build.
| Target class | Tolerance | Observed |
|---|---|---|
| Software · 7 languages | 0.1 % | ≈1e-11 % |
| HDL · Q16.16 | 1 % | ≈1e-3 % |
One model, ten targets.
Every target page shows the same model, so the ten are directly
comparable: an input, an error junction, a gain of 1.8, a discrete plant and an output,
with the plant's output fed back into the junction. The export-verification suite calls it
DPT_Feedback_Discrete - which is where the names in the file come
from.
See it run on your own model.
Download the application from the customer portal, or read the documentation first - the manual, a page for every block, and the full command reference are public.