mirror of https://github.com/zachjs/sv2v.git
80 lines
2.4 KiB
Systemverilog
80 lines
2.4 KiB
Systemverilog
`default_nettype none
|
|
|
|
typedef enum {FOO, BAR} State_t;
|
|
|
|
typedef struct packed {
|
|
State_t state;
|
|
logic [31:0] data;
|
|
} MyStruct_t;
|
|
|
|
module Example(
|
|
input logic clock, clear,
|
|
input logic [7:0] dataIn,
|
|
output logic check1, check2,
|
|
output logic [63:0] checkData
|
|
);
|
|
|
|
// The automatic keyword here is super confusing, but generally does what
|
|
// you expect a C function to do. Sadly VTR doesn't support the automatic
|
|
// keyword.
|
|
function automatic State_t swapState(State_t state);
|
|
// The state variable is not shadowing the state variable in the global
|
|
// function since the function is declared above the state variable
|
|
// (Declaring functions at the start of the module before module scope
|
|
// variables is a good practice to avoid accidentally using a module scope
|
|
// in a function)
|
|
unique case(state)
|
|
FOO: return BAR;
|
|
BAR: return FOO;
|
|
endcase
|
|
endfunction : swapState
|
|
|
|
State_t state;
|
|
|
|
always_ff @(posedge clock)
|
|
if(clear)
|
|
state <= FOO;
|
|
else
|
|
state <= swapState(state);
|
|
|
|
logic [15:0] magicToken;
|
|
assign magicToken = 16'habcd;
|
|
|
|
function automatic MyStruct_t packStruct(State_t state, logic [7:0] data);
|
|
// Something interesting about system verilog is that all local variable
|
|
// declarations must be first in the function (at least for VCS to
|
|
// compile it)
|
|
logic [31:0] fullData;
|
|
State_t nextState;
|
|
// System Verilog functions can also access "local" variables from the
|
|
// module scope. This means that any variable with the same name in the
|
|
// function as something else defined in the module is shadowing the
|
|
// module variable (e.g. state in this function)
|
|
fullData = {~data, data, magicToken};
|
|
nextState = swapState(state);
|
|
return '{
|
|
state: nextState,
|
|
data: fullData
|
|
};
|
|
endfunction
|
|
|
|
MyStruct_t myStruct;
|
|
assign myStruct = packStruct(state, dataIn);
|
|
|
|
function automatic logic doCheck(MyStruct_t inputStruct);
|
|
return inputStruct.state == FOO;
|
|
endfunction : doCheck
|
|
|
|
assign check1 = doCheck(myStruct);
|
|
|
|
MyStruct_t myStruct2;
|
|
always_comb begin
|
|
myStruct2 = packStruct(swapState(state), ~dataIn);
|
|
check2 = doCheck(myStruct2);
|
|
end
|
|
|
|
assign checkData = {myStruct.data, myStruct2.data};
|
|
|
|
|
|
|
|
endmodule |