Final project - RO module
Code
`timescale 1ns/1ps
module ro (
input wire enable, // to enable the inverters chain
// verilator lint_off UNOPTFLAT
output wire endOfChain // The output of the selected RO for that challenge
// verilator lint_on UNOPTFLAT
);
localparam num_inv = 7; // number of inverters in a chain
genvar i;
wire[num_inv:0] inter_wire; // connections between the inverters
// build a chain of inverters
generate
for (i = 0; i < num_inv; i = i+1) begin
`ifndef SYNTHESIS
assign #5 inter_wire[i+1] = ~inter_wire[i];
`else
sky130_fd_sc_hd__inv_2 inv (
.A (inter_wire[i]),
.Y (inter_wire[i+1])
);
`endif
end
endgenerate
// First inverter input = enable signal AND a feed-back from the last inverter
// First inverter output = a wire to the second inverter
`ifndef SYNTHESIS
and #5 beginOfChain(inter_wire[0], endOfChain, enable);
`else
sky130_fd_sc_hd__and2_2 beginOfChain (
.A (endOfChain),
.B (enable),
.Y (inter_wire[0])
);
`endif
// Connect the last inverter to the end of chain
assign endOfChain = inter_wire[num_inv];
endmodule
Lint
verilator --lint-only -Wall -Ilib puf/ro.v config.vlt
- V e r i l a t i o n R e p o r t: Verilator 5.044 2026-01-01 rev v5.044
- Verilator: Built from 0.037 MB sources in 2 modules, into 0.074 MB in 3 C++ files needing 0.000 MB
- Verilator: Walltime 0.009 s (elab=0.000, cvt=0.004, bld=0.000); cpu 0.009 s on 1 threads; alloced 30.348 MB
Test harness
`timescale 1ns/1ps
module test_ro;
// Inputs are reg (we drive them)
reg enable;
// Outputs are wire (DUT drives them)
wire endOfChain;
// Instantiate Device Under Test
ro myRo (
.enable(enable),
.endOfChain(endOfChain)
);
// Test stimulus
initial begin
$dumpfile("waves.vcd");
$dumpvars(0, test_ro);
// Initialize
$display("Initialize");
enable = 0;
#50;
// Start oscillating
$display("==> Test case 1");
enable = 1;
#500;
enable = 0; // stop
#100;
$finish;
end
// measure frequency (optional)
real period, last_rise;
initial begin
last_rise = 0;
forever begin
@(posedge endOfChain);
if (last_rise > 0) begin
period = $realtime - last_rise;
$display("Period = %0.1f ns | Freq = %0.2f MHz",
period, 1000.0/period);
end
last_rise = $realtime;
end
end
endmodule
Test run in simulation
Initialize
==> Test case 1
Period = 90.0 ns | Freq = 11.11 MHz
Period = 80.0 ns | Freq = 12.50 MHz
Period = 80.0 ns | Freq = 12.50 MHz
Period = 80.0 ns | Freq = 12.50 MHz
Period = 80.0 ns | Freq = 12.50 MHz
Period = 80.0 ns | Freq = 12.50 MHz
Period = 60.0 ns | Freq = 16.67 MHz
puf/test_ro.v:34: $finish called at 650000 (1ps)