added verilog support

This commit is contained in:
ParkerTenBroeck 2026-03-13 13:28:26 -04:00
parent 5746846896
commit c3a3e89082
20 changed files with 633 additions and 88 deletions

96
relay/shim/shim.vhdl Normal file
View file

@ -0,0 +1,96 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tb is
end entity;
architecture sim of tb is
signal clk : std_logic := '0';
signal btn : std_logic_vector(31 downto 0) := (others => '0');
signal sw : std_logic_vector(31 downto 0) := (others => '0');
signal led : std_logic_vector(31 downto 0) := (others => '0');
signal segv : std_logic_vector(31 downto 0) := (others => '0');
signal segs : std_logic_vector(31 downto 0) := (others => '0');
procedure ffi_init is
begin
end procedure;
attribute foreign of ffi_init : procedure is
"VHPIDIRECT ffi_init";
function ffi_get_sw return integer is
begin
return 0;
end function;
attribute foreign of ffi_get_sw : function is
"VHPIDIRECT ffi_get_sw";
function ffi_get_btn return integer is
begin
return 0;
end function;
attribute foreign of ffi_get_btn : function is "VHPIDIRECT ffi_get_btn";
procedure ffi_set_outputs(led_i: integer; segv_i: integer; segs_i: integer) is
begin
end procedure;
attribute foreign of ffi_set_outputs : procedure is
"VHPIDIRECT ffi_set_outputs";
function clean_slv(v : std_logic_vector) return std_logic_vector is
variable r : std_logic_vector(v'range);
begin
for i in v'range loop
if v(i) = '1' then
r(i) := '1';
else
r(i) := '0';
end if;
end loop;
return r;
end function;
begin
dut: entity work.circuit
port map (
clk => clk,
btn => btn,
sw => sw,
led => led,
segv => segv,
segs => segs
);
-- 500 Hz clock (2 ms period)
clk <= not clk after 1 ms;
process
variable sw_i : integer;
variable btn_i : integer;
begin
ffi_init;
wait for 0 ns;
while true loop
wait until rising_edge(clk) or falling_edge(clk);
wait for 0 ns;
sw_i := ffi_get_sw;
btn_i := ffi_get_btn;
sw <= std_logic_vector(to_signed(sw_i, 32));
btn <= std_logic_vector(to_signed(btn_i, 32));
ffi_set_outputs(
to_integer(signed(clean_slv(led))),
to_integer(signed(clean_slv(segv))),
to_integer(signed(clean_slv(segs)))
);
end loop;
end process;
end architecture;

35
relay/shim/verilog.c Normal file
View file

@ -0,0 +1,35 @@
#include <cstdint>
#include "Vcircuit.h"
#include "verilated.h"
extern "C" void ffi_init();
extern "C" std::uint32_t ffi_get_sw();
extern "C" std::uint32_t ffi_get_btn();
extern "C" void ffi_set_outputs(std::uint32_t led, std::uint32_t segv, std::uint32_t segs);
int main(int argc, char** argv) {
Verilated::commandArgs(argc, argv);
Vcircuit top;
top.clk = 0;
top.btn = 0;
top.sw = 0;
ffi_init();
while (true) {
top.sw = ffi_get_sw();
top.btn = ffi_get_btn();
top.clk = 0;
top.eval();
ffi_set_outputs(top.led, top.segv, top.segs);
top.sw = ffi_get_sw();
top.btn = ffi_get_btn();
top.clk = 1;
top.eval();
ffi_set_outputs(top.led, top.segv, top.segs);
}
}