Skip to content

Instantly share code, notes, and snippets.

@cjmeyer
Created December 20, 2012 20:29
Show Gist options
  • Save cjmeyer/4348271 to your computer and use it in GitHub Desktop.
Save cjmeyer/4348271 to your computer and use it in GitHub Desktop.
VHDL: Resolved BFM control/command channel.
ype bfm_uctrl_vector_t is
array (integer range <>) of bfm_uctrl_t;
function resolve_bfm_ctrl (
s : bfm_uctrl_vector_t ) return bfm_uctrl_t;
subtype bfm_ctrl_t is
resolve_bfm_ctrl bfm_uctrl_t;
procedure do_req (
signal ctrl : inout bfm_ctrl_t;
constant req : in bfm_req_t;
variable cmd : inout bfm_ctrl_t );
function resolve_bfm_ctrl (
s : bfm_uctrl_vector_t) return bfm_uctrl_t is
variable result : bfm_uctrl_t;
variable req_drivers : natural;
variable ack_drivers : natural;
begin
for i in s'range loop
assert s(i).req = none or not s(i).ack
report "resolve_bfm_ctrl: Are you a client or a server?"
severity failure;
if s(i).req /= none then
req_drivers := req_drivers + 1;
result := s(i);
elsif s(i).ack then
ack_drivers := ack_drivers + 1;
if req_drivers = 0 then
result := s(i);
end if;
end if;
end loop;
assert ack_drivers <= 1
report "resolve_bfm_ctrl: More than one acknowledge active."
severity failure;
if req_drivers > 1 then
report "resolve_bfm_ctrl: More than one request active."
severity failure;
result.req := none;
end if;
result.ack := ack_drivers = 1;
return result;
end function;
procedure do_req (
signal ctrl : inout bfm_ctrl_t;
constant req : in bfm_req_t;
variable cmd : inout bfm_ctrl_t ) is
begin
cmd.req := req;
cmd.ack := false;
ctrl <= cmd;
wait until ctrl.ack;
ctrl.req <= none;
wait for 0 ns;
cmd := ctrl;
end procedure;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment