improved testbench and removed unnecessary delay caused by 2PM
This commit is contained in:
parent
eb1bb5d328
commit
dd7683139c
@ -22,29 +22,30 @@ architecture rtl of socbridge_driver is
|
||||
|
||||
signal next_parity_out : std_logic;
|
||||
signal ext_in_rec : ext_protocol_t;
|
||||
signal ext_out_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0);
|
||||
shared variable ext_out_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0);
|
||||
signal test : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0);
|
||||
signal next_state : state_t;
|
||||
signal curr_command : command_t;
|
||||
signal curr_command_bits : std_logic_vector(4 downto 0);
|
||||
signal curr_respoonse : response_t;
|
||||
signal curr_response : response_t;
|
||||
signal curr_response_bits : std_logic_vector(4 downto 0);
|
||||
signal st : state_rec_t;
|
||||
begin
|
||||
next_parity_out <= calc_parity(ext_out_data_cmd);
|
||||
--- DEBUG GLOBAL BINDINGS ---
|
||||
-- synthesis translate_off
|
||||
G_next_parity_out <= next_parity_out;
|
||||
G_ext_in_rec <= ext_in_rec;
|
||||
G_ext_out_data_cmd <= ext_out_data_cmd;
|
||||
G_next_state <= next_state;
|
||||
G_ext_out_data_cmd <=test;
|
||||
G_curr_command <= curr_command;
|
||||
G_curr_command_bits <= curr_command_bits;
|
||||
G_curr_respoonse <= curr_respoonse;
|
||||
G_curr_response <= curr_response;
|
||||
G_curr_response_bits <= curr_response_bits;
|
||||
G_st <= st;
|
||||
-- synthesis translate_on
|
||||
|
||||
|
||||
ext_in_rec.data <= ext_in.payload;
|
||||
ext_in_rec.clk <= ext_in.control(1);
|
||||
ext_in_rec.parity <= ext_in.control(0);
|
||||
|
||||
comb_proc: process(ext_in, int_out, st)
|
||||
begin
|
||||
@ -53,10 +54,25 @@ begin
|
||||
int_in.payload <= st.ext_in_reg.data;
|
||||
|
||||
-- Helpful Bindings --
|
||||
ext_in_rec <= create_ext_protocol_from_io_type_in(ext_in);
|
||||
curr_response_bits <= ext_in_rec.data(7 downto 3);
|
||||
curr_response_bits <= ext_in.payload(7 downto 3); -- CANT USE EXT_IN_REC here for some reason, the assignment becomes stasteful
|
||||
-- Not sure that the two process method is helping here: if this was a normal
|
||||
-- signal assignment there would be no confusion.
|
||||
-- in the case ... <= ext_in_rec we get
|
||||
-- curr_resp | ext_in_rec | ext_in
|
||||
-- 00000 | 00000000 | 00001001
|
||||
-- 00000 | 00001001 | 00001001
|
||||
-- 00001 | 00001001 | 00001001
|
||||
-- 00001 | 00001001 | 00001001
|
||||
--
|
||||
-- but in the case ... <= ext_in we get
|
||||
-- curr_resp | ext_in_rec | ext_in
|
||||
-- 00000 | 00000000 | 00001001
|
||||
-- 00001 | 00001001 | 00001001
|
||||
-- 00001 | 00001001 | 00001001
|
||||
-- 00001 | 00001001 | 00001001
|
||||
|
||||
with curr_response_bits select
|
||||
curr_respoonse <= WRITE_ACK when "00001",
|
||||
curr_response <= WRITE_ACK when "00001",
|
||||
WRITE_ACK when "00101",
|
||||
READ_RESPONSE when "01000",
|
||||
READ_RESPONSE when "01100",
|
||||
@ -109,7 +125,7 @@ begin
|
||||
next_state <= TX_ACK;
|
||||
when TX_ACK =>
|
||||
-- Wait for write acknowledgement.
|
||||
if curr_respoonse = WRITE_ACK then
|
||||
if curr_response = WRITE_ACK then
|
||||
next_state <= IDLE;
|
||||
else
|
||||
next_state <= TX_ACK;
|
||||
@ -120,7 +136,7 @@ begin
|
||||
next_state <= RX_RESPONSE;
|
||||
when RX_RESPONSE =>
|
||||
-- Wait for read response.
|
||||
if curr_respoonse = READ_RESPONSE then
|
||||
if curr_response = READ_RESPONSE then
|
||||
next_state <= RX_BODY;
|
||||
else
|
||||
next_state <= RX_RESPONSE;
|
||||
@ -132,27 +148,42 @@ begin
|
||||
end case;
|
||||
|
||||
--- Combinatorial output based on current state ---
|
||||
ext_out_data_cmd <= (others => '0');
|
||||
ext_out_data_cmd := (others => '0');
|
||||
int_in.is_full_out <= '1';
|
||||
int_in.write_enable_in <= '0';
|
||||
case st.curr_state is
|
||||
when IDLE =>
|
||||
if cmd = WRITE or cmd = WRITE_ADD then
|
||||
ext_out_data_cmd := get_command_bits(WRITE) & "001";
|
||||
elsif cmd = READ or cmd = READ_ADD then
|
||||
ext_out_data_cmd := get_command_bits(READ) & "001";
|
||||
end if;
|
||||
when RESET =>
|
||||
when TX_HEADER =>
|
||||
curr_command <= WRITE;
|
||||
ext_out_data_cmd <= get_command_bits(WRITE) & "001";
|
||||
when TX_BODY =>
|
||||
ext_out_data_cmd <= int_out.payload;
|
||||
ext_out_data_cmd := int_out.payload;
|
||||
int_in.is_full_out <= '0';
|
||||
when TX_BODY =>
|
||||
-- here more logic is needed for mulit word transmission (and address setting)
|
||||
if cmd = WRITE_ADD then
|
||||
ext_out_data_cmd := int_out.payload;
|
||||
int_in.is_full_out <= '0';
|
||||
end if;
|
||||
when TX_ACK =>
|
||||
when RX_HEADER =>
|
||||
curr_command <= READ;
|
||||
ext_out_data_cmd <= curr_command_bits & "001";
|
||||
ext_out_data_cmd := curr_command_bits & "001";
|
||||
when RX_RESPONSE =>
|
||||
when RX_BODY =>
|
||||
end case;
|
||||
report "Running comb part with ext_out_data_cmd = " & to_string(ext_out_data_cmd) severity note;
|
||||
report "Running comb part with next_parity_out = " & std_logic'image(next_parity_out) severity note;
|
||||
next_parity_out <= calc_parity(ext_out_data_cmd);
|
||||
--- DEBUG GLOBAL BINDINGS ---
|
||||
-- synthesis translate_off
|
||||
test <= ext_out_data_cmd;
|
||||
report to_string(ext_out_data_cmd);
|
||||
report to_string(test);
|
||||
report to_string(G_ext_out_data_cmd);
|
||||
-- synthesis translate_on
|
||||
end process comb_proc;
|
||||
-- Process updating internal registers based on primary clock
|
||||
seq_proc: process(ext_in_rec.clk, rst)
|
||||
@ -165,14 +196,12 @@ begin
|
||||
st.curr_state <= IDLE;
|
||||
|
||||
elsif(rising_edge(ext_in_rec.clk)) then
|
||||
report "Running seq part with ext_out_data_cmd = " & to_string(ext_out_data_cmd) severity note;
|
||||
report "Running seq part with next_parity_out = " & std_logic'image(next_parity_out) severity note;
|
||||
st.ext_out_reg.parity <= next_parity_out;
|
||||
st.ext_in_reg.data <= ext_in_rec.data;
|
||||
st.ext_in_reg.clk <= ext_in_rec.clk;
|
||||
st.ext_in_reg.parity <= ext_in_rec.parity;
|
||||
st.ext_out_reg.data <= ext_out_data_cmd;
|
||||
st.ext_out_reg.clk <= not st.ext_out_reg.clk;
|
||||
st.ext_out_reg.parity <= next_parity_out;
|
||||
st.curr_state <= next_state;
|
||||
end if;
|
||||
end process seq_proc;
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
[*]
|
||||
[*] GTKWave Analyzer v3.3.120 (w)1999-2024 BSI
|
||||
[*] Wed Feb 26 15:43:46 2025
|
||||
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
|
||||
[*] Thu Feb 27 10:27:13 2025
|
||||
[*]
|
||||
[dumpfile] "/home/kryddan/repos/exjobb-public/src/wave/socbridge_driver_tb-tb.ghw"
|
||||
[dumpfile_mtime] "Wed Feb 26 15:43:13 2025"
|
||||
[dumpfile_size] 2378
|
||||
[savefile] "/home/kryddan/repos/exjobb-public/src/wave/socbridge_driver_tb.gtkw"
|
||||
[timestart] 0
|
||||
[size] 1920 1080
|
||||
[pos] -966 -6
|
||||
*-23.724968 40550000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||
[dumpfile] "/home/thesis1/repos/exjobb-public/src/wave/socbridge_driver_tb-tb.ghw"
|
||||
[dumpfile_mtime] "Thu Feb 27 10:26:19 2025"
|
||||
[dumpfile_size] 2417
|
||||
[savefile] "/home/thesis1/repos/exjobb-public/src/socbridge_driver_tb.gtkw"
|
||||
[timestart] 21800000
|
||||
[size] 956 1033
|
||||
[pos] -1 -1
|
||||
*-24.456779 22000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||
[treeopen] top.
|
||||
[treeopen] top.socbridge_driver_tb.
|
||||
[treeopen] top.socbridge_driver_tb_pkg.
|
||||
@ -37,6 +37,7 @@ top.socbridge_driver_tb.int_out.write_enable_out
|
||||
+{next_parity} top.socbridge_driver_tb_pkg.g_next_parity_out
|
||||
@22
|
||||
#{top.socbridge_driver_tb.ext_out.payload[7:0]} top.socbridge_driver_tb.ext_out.payload[7] top.socbridge_driver_tb.ext_out.payload[6] top.socbridge_driver_tb.ext_out.payload[5] top.socbridge_driver_tb.ext_out.payload[4] top.socbridge_driver_tb.ext_out.payload[3] top.socbridge_driver_tb.ext_out.payload[2] top.socbridge_driver_tb.ext_out.payload[1] top.socbridge_driver_tb.ext_out.payload[0]
|
||||
+{next_payload[7:0]} #{top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[7:0]} top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[7] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[6] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[5] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[4] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[3] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[2] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[1] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[0]
|
||||
@1000200
|
||||
-External
|
||||
-Outwards
|
||||
@ -67,9 +68,6 @@ top.socbridge_driver_tb.int_in.write_enable_in
|
||||
top.socbridge_driver_tb_pkg.g_st.curr_state
|
||||
+{next_state} top.socbridge_driver_tb_pkg.g_next_state
|
||||
top.socbridge_driver_tb_pkg.g_curr_command
|
||||
@23
|
||||
#{top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[7:0]} top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[7] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[6] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[5] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[4] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[3] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[2] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[1] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[0]
|
||||
@420
|
||||
top.socbridge_driver_tb_pkg.g_curr_respoonse
|
||||
@1000200
|
||||
-Internal Signals
|
||||
|
||||
@ -10,18 +10,51 @@ entity socbridge_driver_tb is
|
||||
end entity socbridge_driver_tb;
|
||||
|
||||
architecture tb of socbridge_driver_tb is
|
||||
impure function check_next_state(correct_state: state_t) return boolean is
|
||||
signal clk : std_logic := '0';
|
||||
signal rst : std_logic;
|
||||
signal cmd : command_t;
|
||||
signal ext_in : ext_socbridge_in_t;
|
||||
signal ext_out : ext_socbridge_out_t;
|
||||
signal int_in : int_socbridge_in_t;
|
||||
signal int_out : int_socbridge_out_t;
|
||||
signal curr_word : std_logic_vector(ext_in.payload'length - 1 downto 0);
|
||||
signal expected_out : std_logic_vector(ext_out.payload'length - 1 downto 0);
|
||||
|
||||
constant CLK_PERIOD : TIME := 10 ns;
|
||||
constant SIMULATION_CYCLE_COUNT : INTEGER := 100;
|
||||
|
||||
procedure fail(error_msg : string) is
|
||||
begin
|
||||
wait for CLK_PERIOD;
|
||||
report "Simulation ending due to: " & error_msg & ". Shutting down..." severity FAILURE;
|
||||
end procedure;
|
||||
|
||||
procedure check_next_state(correct_state: state_t) is
|
||||
begin
|
||||
if(not (correct_state = G_next_state)) then
|
||||
report "Next State is not what was expected, found " & state_t'image(G_next_state)
|
||||
& " but expected " & state_t'image(correct_state) severity error;
|
||||
return FALSE;
|
||||
fail("Next State");
|
||||
end if;
|
||||
return TRUE;
|
||||
end function;
|
||||
|
||||
|
||||
end procedure;
|
||||
|
||||
procedure check_data_out(correct_data: std_logic_vector(ext_out.payload'length - 1 downto 0)) is
|
||||
begin
|
||||
if(not (correct_data = ext_out.payload)) then
|
||||
report "Data out is not what was expected, found " & to_string(ext_out.payload)
|
||||
& " but expected " & to_string(correct_data) severity error;
|
||||
fail("Data out");
|
||||
end if;
|
||||
end procedure;
|
||||
|
||||
procedure check_parity(correct_data: std_logic_vector(ext_out.payload'length - 1 downto 0)) is
|
||||
begin
|
||||
if(not (calc_parity(correct_data) = calc_parity(ext_out.payload))) then
|
||||
report "Parity out is not what was expected, found " & std_logic'image(calc_parity(ext_out.payload))
|
||||
& " but expected " & std_logic'image(calc_parity(correct_data)) severity error;
|
||||
fail("Parity out");
|
||||
end if;
|
||||
end procedure;
|
||||
|
||||
component socbridge_driver is
|
||||
port(
|
||||
@ -34,18 +67,6 @@ architecture tb of socbridge_driver_tb is
|
||||
int_out : in int_socbridge_out_t
|
||||
);
|
||||
end component socbridge_driver;
|
||||
signal clk : std_logic := '0';
|
||||
signal rst : std_logic;
|
||||
signal cmd : command_t;
|
||||
signal ext_in : ext_socbridge_in_t;
|
||||
signal ext_out : ext_socbridge_out_t;
|
||||
signal int_in : int_socbridge_in_t;
|
||||
signal int_out : int_socbridge_out_t;
|
||||
|
||||
signal curr_word : std_logic_vector(ext_in.payload'length - 1 downto 0);
|
||||
|
||||
constant CLK_PERIOD : TIME := 10 ns;
|
||||
constant SIMULATION_CYCLE_COUNT : INTEGER := 100;
|
||||
|
||||
begin
|
||||
socbridge_driver_inst: entity work.socbridge_driver
|
||||
@ -68,7 +89,6 @@ begin
|
||||
end loop;
|
||||
wait;
|
||||
end process real_clk_proc;
|
||||
|
||||
|
||||
verify_clk: process
|
||||
variable last_clk : std_logic;
|
||||
@ -84,52 +104,64 @@ begin
|
||||
wait;
|
||||
end process verify_clk;
|
||||
|
||||
verify_parity: process
|
||||
verify_out_signals: process
|
||||
variable curr_parity : std_logic;
|
||||
begin
|
||||
for x in 0 to SIMULATION_CYCLE_COUNT * 10 loop
|
||||
curr_parity := calc_parity(ext_out.payload);
|
||||
if not (curr_parity = ext_out.control(0)) then
|
||||
report "Secondary side parity not correct" severity error;
|
||||
wait for CLK_PERIOD;
|
||||
report "Ending Simulation... " severity FAILURE;
|
||||
end if;
|
||||
wait for CLK_PERIOD / 10;
|
||||
wait for CLK_PERIOD / 2;
|
||||
for x in 0 to SIMULATION_CYCLE_COUNT loop
|
||||
check_data_out(expected_out);
|
||||
check_parity(expected_out);
|
||||
wait for CLK_PERIOD;
|
||||
end loop;
|
||||
wait;
|
||||
end process verify_parity;
|
||||
end process verify_out_signals;
|
||||
|
||||
verify_next_state : process
|
||||
verify_signals : process
|
||||
variable nsv: boolean;
|
||||
begin
|
||||
expected_out <= "00000000";
|
||||
wait for 3 * CLK_PERIOD;
|
||||
wait for CLK_PERIOD / 2;
|
||||
nsv := check_next_state(IDLE);
|
||||
wait for CLK_PERIOD / 3;
|
||||
expected_out <= "00000000";
|
||||
check_next_state(IDLE);
|
||||
wait for CLK_PERIOD /4;
|
||||
check_next_state(TX_HEADER);
|
||||
wait for CLK_PERIOD * 3 / 4;
|
||||
expected_out <= get_command_bits(WRITE) & "001";
|
||||
check_next_state(TX_BODY);
|
||||
wait for CLK_PERIOD;
|
||||
nsv := check_next_state(TX_HEADER);
|
||||
expected_out <= "00000001";
|
||||
check_next_state(TX_ACK);
|
||||
wait for CLK_PERIOD;
|
||||
nsv := check_next_state(TX_BODY);
|
||||
expected_out <= "00000000";
|
||||
check_next_state(TX_ACK);
|
||||
wait for CLK_PERIOD;
|
||||
nsv := check_next_state(TX_ACK);
|
||||
expected_out <= "00000000";
|
||||
check_next_state(IDLE);
|
||||
wait for CLK_PERIOD;
|
||||
nsv := check_next_state(TX_ACK);
|
||||
expected_out <= "00000000";
|
||||
check_next_state(IDLE);
|
||||
wait for CLK_PERIOD;
|
||||
nsv := check_next_state(IDLE);
|
||||
expected_out <= "00000000";
|
||||
check_next_state(IDLE);
|
||||
wait for CLK_PERIOD;
|
||||
nsv := check_next_state(IDLE);
|
||||
expected_out <= "00000000";
|
||||
check_next_state(IDLE);
|
||||
wait for CLK_PERIOD;
|
||||
nsv := check_next_state(IDLE);
|
||||
expected_out <= "00000000";
|
||||
check_next_state(IDLE);
|
||||
wait for CLK_PERIOD;
|
||||
nsv := check_next_state(IDLE);
|
||||
expected_out <= "00000000";
|
||||
check_next_state(IDLE);
|
||||
wait for CLK_PERIOD;
|
||||
nsv := check_next_state(IDLE);
|
||||
expected_out <= "00000000";
|
||||
check_next_state(IDLE);
|
||||
wait for CLK_PERIOD;
|
||||
nsv := check_next_state(IDLE);
|
||||
wait for CLK_PERIOD;
|
||||
nsv := check_next_state(IDLE);
|
||||
expected_out <= "00000000";
|
||||
check_next_state(IDLE);
|
||||
wait for CLK_PERIOD;
|
||||
wait;
|
||||
end process verify_next_state;
|
||||
end process verify_signals;
|
||||
|
||||
command_stimulus: process
|
||||
begin
|
||||
@ -150,9 +182,12 @@ begin
|
||||
|
||||
external_stimulus: process
|
||||
begin
|
||||
rst <= '0';
|
||||
wait for CLK_PERIOD / 1000;
|
||||
rst <= '1';
|
||||
curr_word <= "00000000";
|
||||
wait for 3 * CLK_PERIOD;
|
||||
wait for 999 * CLK_PERIOD / 1000;
|
||||
wait for 2 * CLK_PERIOD;
|
||||
rst <= '0';
|
||||
wait for CLK_PERIOD / 2;
|
||||
wait for 3* CLK_PERIOD;
|
||||
@ -167,24 +202,35 @@ begin
|
||||
wait for 3 * CLK_PERIOD;
|
||||
-- stimulus goes here
|
||||
int_out.write_enable_out <= '1';
|
||||
int_out.payload <= "00000000";
|
||||
int_out.payload <= "00000001";
|
||||
wait until int_in.is_full_out = '0';
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
int_out.payload <= "00000010";
|
||||
wait until int_in.is_full_out = '0';
|
||||
wait for CLK_PERIOD/2;
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
int_out.payload <= "00000100";
|
||||
wait until int_in.is_full_out = '0';
|
||||
wait for CLK_PERIOD/2;
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
int_out.payload <= "00001000";
|
||||
wait until int_in.is_full_out = '0';
|
||||
wait for CLK_PERIOD/2;
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
int_out.payload <= "00010000";
|
||||
wait until int_in.is_full_out = '0';
|
||||
wait for CLK_PERIOD/2;
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk);
|
||||
int_out.payload <= "00100000";
|
||||
wait until int_in.is_full_out = '0';
|
||||
wait for CLK_PERIOD/2;
|
||||
wait until rising_edge(clk);
|
||||
wait until rising_edge(clk); --- ??? Why all these rising_edge checks?
|
||||
wait;
|
||||
end process internal_stimulus;
|
||||
|
||||
|
||||
@ -27,9 +27,6 @@ package socbridge_driver_tb_pkg is
|
||||
impure function calc_parity(
|
||||
d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0)
|
||||
) return std_logic;
|
||||
pure function create_ext_protocol_from_io_type_in (
|
||||
input : ext_socbridge_in_t
|
||||
) return ext_protocol_t;
|
||||
pure function create_io_type_out_from_ext_protocol(
|
||||
input: ext_protocol_t
|
||||
) return ext_socbridge_out_t;
|
||||
@ -43,7 +40,7 @@ package socbridge_driver_tb_pkg is
|
||||
signal G_next_state : state_t;
|
||||
signal G_curr_command : command_t;
|
||||
signal G_curr_command_bits : std_logic_vector(4 downto 0);
|
||||
signal G_curr_respoonse : response_t;
|
||||
signal G_curr_response : response_t;
|
||||
signal G_curr_response_bits : std_logic_vector(4 downto 0);
|
||||
signal G_st : state_rec_t;
|
||||
-- synthesis translate_on
|
||||
@ -74,16 +71,6 @@ package body socbridge_driver_tb_pkg is
|
||||
return not parity;
|
||||
end function;
|
||||
|
||||
pure function create_ext_protocol_from_io_type_in(
|
||||
input : ext_socbridge_in_t
|
||||
) return ext_protocol_t is
|
||||
variable val : ext_protocol_t;
|
||||
begin
|
||||
val.data := input.payload;
|
||||
val.clk := input.control(1);
|
||||
val.parity := input.control(0);
|
||||
return val;
|
||||
end function;
|
||||
pure function create_io_type_out_from_ext_protocol(
|
||||
input : ext_protocol_t
|
||||
) return ext_socbridge_out_t is
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user