Skip to content

Instantly share code, notes, and snippets.

@esynr3z
Last active August 17, 2022 16:50
Show Gist options
  • Save esynr3z/85036181fa618f126039db1933ac35f4 to your computer and use it in GitHub Desktop.
Save esynr3z/85036181fa618f126039db1933ac35f4 to your computer and use it in GitHub Desktop.
iverilog-pls vs iverilog-v11

iverilog-pls vs iverilog-v11

About PLS:

The project is developed based on icarus iverilog. Special thanks to Stephen Williams (steve@icarus.com).

PLS is a Verilog simulator, compiles verilog into a much faster optimized model, which executes about 20-100x faster than interpreted Verilog simulators such as icarus iverilog vvp.

Some performance metrics from authors.

Prepare container

Put Dockerfile and tb.sv in the same folder.

# clone repos to the same folder:
git clone -b v11-branch git@github.com:steveicarus/iverilog.git
git clone git@github.com:pytec8800/pint_iverilog.git

# build Docker container named 'iverilog_bench'
docker build -t iverilog_bench  .

Run containter

Run this to get an interactive console for further experiments:

docker run -i -v $(pwd):/project -u $(id -u):$(id -g) -t iverilog_bench

Another way is to run needed commands directly:

# simulate in iverilog-v11
docker run -i -v $(pwd):/project -u $(id -u):$(id -g) -t iverilog_bench iverilog-v11 tb.sv -g2012 && vvp-v11 -v a.out

# simulate in iverilog-pls
docker run -i -v $(pwd):/project -u $(id -u):$(id -g) -t iverilog_bench iverilog-pls tb.sv -g2012 && ./a.out

Or just

Results

My results for quite a synthetic testbench:

  • iverilog-v11: ~2h
  • iverilog-pls: ~3s
# Prepare system
FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y build-essential flex gperf bison libreadline6-dev libncurses5-dev autoconf
# Copy sources
COPY ./iverilog /src/iverilog
COPY ./pint_iverilog /src/pint_iverilog
WORKDIR /src
# Build iverilog-pls
RUN cd pint_iverilog && \
sh autoconf.sh && \
./configure --enable-suffix="-pls" && \
make -j$(nproc) && \
make install
# Build iverilog-v11
RUN cd iverilog && \
sh autoconf.sh && \
./configure --enable-suffix="-v11" && \
make -j$(nproc) && \
make install
# Prepare for work
WORKDIR /project
CMD ["/bin/bash"]
module xor_unit
#(
parameter DATA_W = 32
)(
input logic clk,
input logic rst_n,
input logic [DATA_W-1:0] in_a,
input logic [DATA_W-1:0] in_b,
output logic [DATA_W-1:0] res
);
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
res <= '0;
end else begin
res <= in_a ^ in_b;
end
end
endmodule
module tb;
localparam XOR_NUM = 512;
localparam DATA_W = 32;
bit clk = 0;
always #5 clk = ~clk;
bit rst_n = 0;
initial #42 rst_n = 1;
logic [XOR_NUM-1:0][DATA_W-1:0] in_a;
logic [XOR_NUM-1:0][DATA_W-1:0] in_b;
logic [XOR_NUM-1:0][DATA_W-1:0] res;
logic [DATA_W-1:0] drv_a;
logic [DATA_W-1:0] drv_b;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
drv_a <= '0;
drv_b <= '1;
end else begin
drv_a <= drv_a + 7;
drv_b <= drv_b - 13;
end
end
for (genvar i = 0; i < XOR_NUM; i++) begin
xor_unit #(
.DATA_W(DATA_W)
) xor_i (
.clk (clk),
.rst_n (rst_n),
.in_a (in_a[i]),
.in_b (in_b[i]),
.res (res[i])
);
assign in_a[i] = (i == 0) ? drv_a : drv_a + res[i-1];
assign in_b[i] = (i == 0) ? drv_b : drv_b + res[i-1];
end
logic [DATA_W-1:0] final_res;
always_comb begin
final_res = '0;
for (int i = 0; i < XOR_NUM; i++) begin
final_res += res[i];
end
end
initial begin
#1000;
$display("%0t Done! Result is %0x", $time, final_res);
$finish;
end
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment