reference implementation for tcp parser

reference implementation for tcp parser

import BUtils::*;
import BuildVector::*;
import CBus::*;
import ClientServer::*;
import Connectable::*;
import DbgDefs::*;
import DefaultValue::*;
import Ethernet::*;
import FIFO::*;
import FIFOF::*;
import FShow::*;
import GetPut::*;
import List::*;
import MIMO::*;
import MatchTable::*;
import PacketBuffer::*;
import Pipe::*;
import Register::*;
import SpecialFIFOs::*;
import StmtFSM::*;
import TxRx::*;
import Utils::*;
import Vector::*;
typedef struct {
  Bit#(9) ingress_port;
  Bit#(32) packet_length;
  Bit#(9) egress_spec;
  Bit#(9) egress_port;
  Bit#(32) egress_instance;
  Bit#(32) instance_type;
  Bit#(32) clone_spec;
  Bit#(5) _padding;
} StandardMetadataT deriving (Bits, Eq);
instance DefaultValue#(StandardMetadataT);
  defaultValue = unpack(0);
endinstance
instance DefaultMask#(StandardMetadataT);
  defaultMask = unpack(maxBound);
endinstance
function StandardMetadataT extract_standard_metadata_t(Bit#(160) data);
  return unpack(byteSwap(data));
endfunction

typedef struct {
  Bit#(48) dstAddr;
  Bit#(48) srcAddr;
  Bit#(16) etherType;
} EthernetT deriving (Bits, Eq);
instance DefaultValue#(EthernetT);
  defaultValue = unpack(0);
endinstance
instance DefaultMask#(EthernetT);
  defaultMask = unpack(maxBound);
endinstance
function EthernetT extract_ethernet_t(Bit#(112) data);
  return unpack(byteSwap(data));
endfunction

typedef struct {
  Bit#(4) version;
  Bit#(4) ihl;
  Bit#(8) diffserv;
  Bit#(16) totalLen;
  Bit#(16) identification;
  Bit#(3) flags;
  Bit#(13) fragOffset;
  Bit#(8) ttl;
  Bit#(8) protocol;
  Bit#(16) hdrChecksum;
  Bit#(32) srcAddr;
  Bit#(32) dstAddr;
} Ipv4T deriving (Bits, Eq);
instance DefaultValue#(Ipv4T);
  defaultValue = unpack(0);
endinstance
instance DefaultMask#(Ipv4T);
  defaultMask = unpack(maxBound);
endinstance
function Ipv4T extract_ipv4_t(Bit#(160) data);
  return unpack(byteSwap(data));
endfunction

typedef struct {
  Bit#(16) srcPort;
  Bit#(16) dstPort;
  Bit#(32) seqNo;
  Bit#(32) ackNo;
  Bit#(4) dataOffset;
  Bit#(3) res;
  Bit#(3) ecn;
  Bit#(1) urg;
  Bit#(1) ack;
  Bit#(1) push;
  Bit#(1) rst;
  Bit#(1) syn;
  Bit#(1) fin;
  Bit#(16) window;
  Bit#(16) checksum;
  Bit#(16) urgentPtr;
} TcpT deriving (Bits, Eq);
instance DefaultValue#(TcpT);
  defaultValue = unpack(0);
endinstance
instance DefaultMask#(TcpT);
  defaultMask = unpack(maxBound);
endinstance
function TcpT extract_tcp_t(Bit#(160) data);
  return unpack(byteSwap(data));
endfunction

typedef struct {
  Bit#(8) kind;
} OptionsEndT deriving (Bits, Eq);
instance DefaultValue#(OptionsEndT);
  defaultValue = unpack(0);
endinstance
instance DefaultMask#(OptionsEndT);
  defaultMask = unpack(maxBound);
endinstance
function OptionsEndT extract_options_end_t(Bit#(8) data);
  return unpack(byteSwap(data));
endfunction

typedef struct {
  Bit#(8) kind;
} OptionsNopT deriving (Bits, Eq);
instance DefaultValue#(OptionsNopT);
  defaultValue = unpack(0);
endinstance
instance DefaultMask#(OptionsNopT);
  defaultMask = unpack(maxBound);
endinstance
function OptionsNopT extract_options_nop_t(Bit#(8) data);
  return unpack(byteSwap(data));
endfunction

typedef struct {
  Bit#(8) kind;
  Bit#(8) len;
  Bit#(16) mss;
} OptionsMssT deriving (Bits, Eq);
instance DefaultValue#(OptionsMssT);
  defaultValue = unpack(0);
endinstance
instance DefaultMask#(OptionsMssT);
  defaultMask = unpack(maxBound);
endinstance
function OptionsMssT extract_options_mss_t(Bit#(32) data);
  return unpack(byteSwap(data));
endfunction

typedef struct {
  Bit#(8) kind;
  Bit#(8) len;
  Bit#(8) wscale;
} OptionsWscaleT deriving (Bits, Eq);
instance DefaultValue#(OptionsWscaleT);
  defaultValue = unpack(0);
endinstance
instance DefaultMask#(OptionsWscaleT);
  defaultMask = unpack(maxBound);
endinstance
function OptionsWscaleT extract_options_wscale_t(Bit#(24) data);
  return unpack(byteSwap(data));
endfunction

typedef struct {
  Bit#(8) kind;
  Bit#(8) len;
} OptionsSackT deriving (Bits, Eq);
instance DefaultValue#(OptionsSackT);
  defaultValue = unpack(0);
endinstance
instance DefaultMask#(OptionsSackT);
  defaultMask = unpack(maxBound);
endinstance
function OptionsSackT extract_options_sack_t(Bit#(16) data);
  return unpack(byteSwap(data));
endfunction

typedef struct {
  Bit#(8) kind;
  Bit#(8) len;
  Bit#(64) ttee;
} OptionsTsT deriving (Bits, Eq);
instance DefaultValue#(OptionsTsT);
  defaultValue = unpack(0);
endinstance
instance DefaultMask#(OptionsTsT);
  defaultMask = unpack(maxBound);
endinstance
function OptionsTsT extract_options_ts_t(Bit#(80) data);
  return unpack(byteSwap(data));
endfunction

typedef struct {
  Bit#(8) parse_tcp_options_counter;
} MyMetadataT deriving (Bits, Eq);
instance DefaultValue#(MyMetadataT);
  defaultValue = unpack(0);
endinstance
instance DefaultMask#(MyMetadataT);
  defaultMask = unpack(maxBound);
endinstance
function MyMetadataT extract_my_metadata_t(Bit#(8) data);
  return unpack(byteSwap(data));
endfunction

typedef struct {
  Bit#(48) ingress_global_timestamp;
  Bit#(32) lf_field_list;
  Bit#(16) mcast_grp;
  Bit#(16) egress_rid;
} IntrinsicMetadataT deriving (Bits, Eq);
instance DefaultValue#(IntrinsicMetadataT);
  defaultValue = unpack(0);
endinstance
instance DefaultMask#(IntrinsicMetadataT);
  defaultMask = unpack(maxBound);
endinstance
function IntrinsicMetadataT extract_intrinsic_metadata_t(Bit#(112) data);
  return unpack(byteSwap(data));
endfunction

typedef struct {
  PacketInstance pkt;
  MetadataT meta;
} MetadataRequest deriving (Bits, Eq);
typedef union tagged {
  struct {
    PacketInstance pkt;
    MetadataT meta;
  } ForwardTblForwardRspT;
  struct {
    PacketInstance pkt;
    MetadataT meta;
  } ForwardTblDropRspT;
} MetadataResponse deriving (Bits, Eq);
typedef struct {
  Maybe#(Bit#(9)) standard_metadata$egress_spec;
  Maybe#(Bit#(9)) runtime_port;
  Maybe#(Bit#(48)) ethernet$dstAddr;
} MetadataT deriving (Bits, Eq);
instance DefaultValue#(MetadataT);
  defaultValue = unpack(0);
endinstance
// ====== PARSER ======

typedef enum {
  StateStart,
  StateParseEthernet,
  StateParseIpv4,
  StateParseTcp,
  StateParseTcpOptions,
  StateParseEnd,
  StateParseNop,
  StateParseMss,
  StateParseWscale,
  StateParseSack,
  StateParseTs
} ParserState deriving (Bits, Eq);
interface Parser;
  interface Put#(EtherData) frameIn;
  interface Get#(MetadataT) meta;
  interface Put#(int) verbosity;
  method ParserPerfRec read_perf_info ();
endinterface
module mkParser  (Parser);
  PulseWire w_parse_tcp_options_parse_mss <- mkPulseWireOR();
  PulseWire w_parse_mss_parse_tcp_options <- mkPulseWireOR();
  PulseWire w_parse_ipv4_start <- mkPulseWireOR();
  PulseWire w_parse_tcp_options_parse_sack <- mkPulseWireOR();
  PulseWire w_parse_ethernet_parse_ipv4 <- mkPulseWireOR();
  PulseWire w_parse_tcp_options_parse_nop <- mkPulseWireOR();
  PulseWire w_parse_sack_parse_tcp_options <- mkPulseWireOR();
  PulseWire w_parse_nop_parse_tcp_options <- mkPulseWireOR();
  PulseWire w_parse_ts_parse_tcp_options <- mkPulseWireOR();
  PulseWire w_parse_ethernet_start <- mkPulseWireOR();
  PulseWire w_parse_end_parse_tcp_options <- mkPulseWireOR();
  PulseWire w_parse_wscale_parse_tcp_options <- mkPulseWireOR();
  PulseWire w_parse_tcp_options_parse_wscale <- mkPulseWireOR();
  PulseWire w_parse_tcp_options_start <- mkPulseWireOR();
  PulseWire w_parse_tcp_start <- mkPulseWireOR();
  PulseWire w_parse_tcp_parse_tcp_options <- mkPulseWireOR();
  PulseWire w_parse_tcp_options_parse_ts <- mkPulseWireOR();
  PulseWire w_parse_tcp_options_parse_end <- mkPulseWireOR();
  PulseWire w_parse_ipv4_parse_tcp <- mkPulseWireOR();
  Reg#(Bit#(8)) my_metadata$parse_tcp_options_counter[2] <- mkCReg(2, 0);
  Wire#(Bit#(8)) w_parse_tcp_options <- mkDWire(0);
  Reg#(int) cr_verbosity[2] <- mkCRegU(2);
  FIFOF#(int) cr_verbosity_ff <- mkFIFOF;
  rule set_verbosity;
    let x = cr_verbosity_ff.first;
    cr_verbosity_ff.deq;
    cr_verbosity[1] <= x;
  endrule

  FIFOF#(EtherData) data_in_ff <- mkFIFOF;
  FIFOF#(MetadataT) meta_in_ff <- mkFIFOF;
  PulseWire parse_done <- mkPulseWire();
  PulseWire w_parse_header_done <- mkPulseWireOR();
  PulseWire w_load_header <- mkPulseWireOR();
  Reg#(ParserState) rg_parse_state[3] <- mkCReg(3, StateStart);
  Reg#(Bit#(32)) rg_next_header_len[3] <- mkCReg(3, 0);
  Reg#(Bit#(32)) rg_buffered[3] <- mkCReg(3, 0);
  Reg#(Bit#(32)) rg_shift_amt[3] <- mkCReg(3, 0);
  //Reg#(Bit#(512)) rg_tmp <- mkReg(0);
  Reg#(Bit#(512)) rg_tmp[2] <- mkCReg(2, 0);
  Reg#(Bool) rg_dequeue_data[3] <- mkCReg(3, False);
  function Action dbg3(Fmt msg);
    action
      if (cr_verbosity[0] > 3) begin
        $display("(%0d) ", $time, msg);
      end
    endaction
  endfunction
  function Action succeed_and_next(Bit#(32) offset);
    action
      rg_buffered[0] <= rg_buffered[0] - offset;
      rg_shift_amt[0] <= rg_buffered[0] - offset;
      dbg3($format("succeed_and_next subtract offset = %d shift_amt/buffered = %d", offset, rg_buffered[0] - offset));
    endaction
  endfunction
  function Action fetch_next_header(Bit#(32) len);
    action
      rg_next_header_len[0] <= len;
      w_parse_header_done.send();
    endaction
  endfunction
  function Action fetch_next_header1(Bit#(32) len);
    action
      rg_next_header_len[1] <= len;
      w_parse_header_done.send();
    endaction
  endfunction
  function Action move_shift_amt(Bit#(32) len);
    action
      rg_shift_amt[0] <= rg_shift_amt[0] + len;
      w_load_header.send();
    endaction
  endfunction
  function Action failed_and_trap(Bit#(32) offset);
    action
      rg_buffered[0] <= 0;
    endaction
  endfunction
  function Action report_parse_action(ParserState state, Bit#(32) offset, Bit#(128) data, Bit#(512) buff);
    action
      if (cr_verbosity[0] > 3) begin
        $display("(%0d) Parser State %h buffered %d, %h, %h", $time, state, offset, data, buff);
      end
    endaction
  endfunction
  let sop_this_cycle = data_in_ff.first.sop;
  let eop_this_cycle = data_in_ff.first.eop;
  let data_this_cycle = data_in_ff.first.data;
  function Action compute_next_state_parse_ethernet(Bit#(16) etherType);
    action
      let v = {etherType};
      if (v == 'h0800) begin
        dbg3($format("transit to parse_ipv4"));
        w_parse_ethernet_parse_ipv4.send();
      end
      else begin
        dbg3($format("transit to start"));
        w_parse_ethernet_start.send();
      end
    endaction
  endfunction
  function Action compute_next_state_parse_ipv4(Bit#(8) protocol);
    action
      let v = {protocol};
      if (v == 'h06) begin
        dbg3($format("transit to parse_tcp"));
        w_parse_ipv4_parse_tcp.send();
      end
      else begin
        dbg3($format("transit to start"));
        w_parse_ipv4_start.send();
      end
    endaction
  endfunction
  function Action compute_next_state_parse_tcp(Bit#(1) syn);
    action
      let v = {syn};
      if (v == 'h01) begin
        dbg3($format("transit to parse_tcp_options"));
        w_parse_tcp_parse_tcp_options.send();
      end
      else begin
        dbg3($format("transit to start"));
        w_parse_tcp_start.send();
      end
    endaction
  endfunction
  function Action compute_next_state_parse_tcp_options(Bit#(8) parse_tcp_options_counter, Bit#(8) current);
    action
      let v = {parse_tcp_options_counter, current};
      dbg3($format("%h", v));
      if ((v & 'hff00) == 'h0000) begin
        dbg3($format("transit to start"));
        w_parse_tcp_options_start.send();
      end
      else if ((v & 'h00ff) == 'h0000) begin
        dbg3($format("transit to parse_end"));
        w_parse_tcp_options_parse_end.send();
      end
      else if ((v & 'h00ff) == 'h0001) begin
        dbg3($format("transit to parse_nop"));
        w_parse_tcp_options_parse_nop.send();
      end
      else if ((v & 'h00ff) == 'h0002) begin
        dbg3($format("transit to parse_mss"));
        w_parse_tcp_options_parse_mss.send();
      end
      else if ((v & 'h00ff) == 'h0003) begin
        dbg3($format("transit to parse_wscale"));
        w_parse_tcp_options_parse_wscale.send();
      end
      else if ((v & 'h00ff) == 'h0004) begin
        dbg3($format("transit to parse_sack"));
        w_parse_tcp_options_parse_sack.send();
      end
      else if ((v & 'h00ff) == 'h0008) begin
        dbg3($format("transit to parse_ts"));
        w_parse_tcp_options_parse_ts.send();
      end
    endaction
  endfunction
  function Action compute_next_state_parse_end();
    action
      dbg3($format("transit to parse_tcp_options"));
      w_parse_end_parse_tcp_options.send();
    endaction
  endfunction
  function Action compute_next_state_parse_nop();
    action
      dbg3($format("transit to parse_tcp_options"));
      w_parse_nop_parse_tcp_options.send();
    endaction
  endfunction
  function Action compute_next_state_parse_mss();
    action
      dbg3($format("transit to parse_tcp_options"));
      w_parse_mss_parse_tcp_options.send();
    endaction
  endfunction
  function Action compute_next_state_parse_wscale();
    action
      dbg3($format("transit to parse_tcp_options"));
      w_parse_wscale_parse_tcp_options.send();
    endaction
  endfunction
  function Action compute_next_state_parse_sack();
    action
      dbg3($format("transit to parse_tcp_options"));
      w_parse_sack_parse_tcp_options.send();
    endaction
  endfunction
  function Action compute_next_state_parse_ts();
    action
      dbg3($format("transit to parse_tcp_options"));
      w_parse_ts_parse_tcp_options.send();
    endaction
  endfunction
  rule rl_data_ff_load if ((rg_buffered[2] < rg_next_header_len[2] + 8) && (rg_parse_state[2] != StateStart) && (w_parse_header_done || w_load_header));
    rg_buffered[2] <= rg_buffered[2] + 128;
    data_in_ff.deq;
    rg_dequeue_data[2] <= True;
    dbg3($format("dequeue data %d %d", rg_buffered[2], rg_next_header_len[2]));
  endrule

  rule rl_data_ff_idle if ((rg_buffered[2] > rg_next_header_len[2]) && (rg_parse_state[2] != StateStart) && (w_parse_header_done || w_load_header));
    rg_dequeue_data[2] <= False;
  endrule

  rule rl_start_state_deq if (rg_parse_state[2] == StateStart && sop_this_cycle && !w_parse_header_done);
    let v = data_in_ff.first;
    rg_parse_state[2] <= StateParseEthernet;
    rg_buffered[2] <= 128;
    rg_shift_amt[2] <= 0;
    rg_dequeue_data[2] <= True;
  endrule

  rule rl_start_state_idle if (rg_parse_state[2] == StateStart && (!sop_this_cycle || w_parse_header_done));
    data_in_ff.deq;
  endrule

  (* fire_when_enabled *)
  rule rl_parse_ethernet_load if ((rg_parse_state[0] == StateParseEthernet) && (rg_buffered[0] < 112));
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, rg_tmp[0]);
    let data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    rg_tmp[0] <= zeroExtend(data);
    move_shift_amt(128);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_ethernet_extract if ((rg_parse_state[0] == StateParseEthernet) && (rg_buffered[0] >= 112));
    let data = rg_tmp[0];
    if (rg_dequeue_data[0] == True) begin
      data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    end
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, data);
    let ethernet_t = extract_ethernet_t(truncate(data));
    compute_next_state_parse_ethernet(ethernet_t.etherType);
    rg_tmp[0] <= zeroExtend(data >> 112);
    succeed_and_next(112);
    dbg3($format("extract %s %h", "parse_ethernet", rg_dequeue_data[0]));
  endrule

  (* mutually_exclusive="rl_parse_ethernet_parse_ipv4, rl_parse_ethernet_start" *)
  rule rl_parse_ethernet_parse_ipv4 if ((rg_parse_state[0] == StateParseEthernet) && (w_parse_ethernet_parse_ipv4));
    rg_parse_state[0] <= StateParseIpv4;
    dbg3($format("%s -> %s", "parse_ethernet", "parse_ipv4"));
    fetch_next_header(160);
  endrule

  rule rl_parse_ethernet_start if ((rg_parse_state[0] == StateParseEthernet) && (w_parse_ethernet_start));
    rg_parse_state[0] <= StateStart;
    dbg3($format("%s -> %s", "parse_ethernet", "start"));
    fetch_next_header(0);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_ipv4_load if ((rg_parse_state[0] == StateParseIpv4) && (rg_buffered[0] < 160));
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, rg_tmp[0]);
    let data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    rg_tmp[0] <= zeroExtend(data);
    move_shift_amt(128);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_ipv4_extract if ((rg_parse_state[0] == StateParseIpv4) && (rg_buffered[0] >= 160));
    let data = rg_tmp[0];
    if (rg_dequeue_data[0] == True) begin
      data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    end
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, data);
    let ipv4_t = extract_ipv4_t(truncate(data));
    compute_next_state_parse_ipv4(ipv4_t.protocol);
    rg_tmp[0] <= zeroExtend(data >> 160);
    succeed_and_next(160);
    dbg3($format("extract %s %h", "parse_ipv4", rg_dequeue_data[0]));
  endrule

  (* mutually_exclusive="rl_parse_ipv4_parse_tcp, rl_parse_ipv4_start" *)
  rule rl_parse_ipv4_parse_tcp if ((rg_parse_state[0] == StateParseIpv4) && (w_parse_ipv4_parse_tcp));
    rg_parse_state[0] <= StateParseTcp;
    dbg3($format("%s -> %s", "parse_ipv4", "parse_tcp"));
    fetch_next_header(160);
  endrule

  rule rl_parse_ipv4_start if ((rg_parse_state[0] == StateParseIpv4) && (w_parse_ipv4_start));
    rg_parse_state[0] <= StateStart;
    dbg3($format("%s -> %s", "parse_ipv4", "start"));
    fetch_next_header(0);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_tcp_load if ((rg_parse_state[0] == StateParseTcp) && (rg_buffered[0] < 160));
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, rg_tmp[0]);
    let data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    rg_tmp[0] <= zeroExtend(data);
    move_shift_amt(128);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_tcp_extract if ((rg_parse_state[0] == StateParseTcp) && (rg_buffered[0] >= 160));
    let data = rg_tmp[0];
    if (rg_dequeue_data[0] == True) begin
      data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    end
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, data);
    let tcp_t = extract_tcp_t(truncate(data));
    Bit#(8) tcp$dataOffset = zeroExtend(tcp_t.dataOffset);
    let v = ( ( tcp$dataOffset * 'h4 ) - 20 );
    my_metadata$parse_tcp_options_counter[0] <= zeroExtend(v);
    compute_next_state_parse_tcp(tcp_t.syn);
    rg_tmp[0] <= zeroExtend(data >> 160);
    succeed_and_next(160);
    dbg3($format("extract %s %h", "parse_tcp", rg_dequeue_data[0]));
  endrule

  //(* mutually_exclusive="rl_parse_tcp_parse_tcp_options, rl_parse_tcp_start" *)
  rule rl_parse_tcp_parse_tcp_options if ((w_parse_tcp_parse_tcp_options));
    Vector#(512, Bit#(1)) buffer = unpack(rg_tmp[1]);
    Bit#(8) lookahead = pack(takeAt(0, buffer));
    dbg3($format("look ahead %h, %h", lookahead, rg_tmp[1]));
    compute_next_state_parse_tcp_options(my_metadata$parse_tcp_options_counter[1], lookahead);
    rg_parse_state[0] <= StateParseTcpOptions;
    dbg3($format("metadata counter %h", my_metadata$parse_tcp_options_counter[1]));
    dbg3($format("%s -> %s", "parse_tcp", "parse_tcp_options"));
    fetch_next_header(0);
  endrule

  //rule rl_parse_tcp_start if ((w_parse_tcp_start));
  //  rg_parse_state[0] <= StateStart;
  //  dbg3($format("%s -> %s", "parse_tcp", "start"));
  //  fetch_next_header(0);
  //endrule

  (* mutually_exclusive="rl_parse_tcp_options_start, rl_parse_tcp_options_parse_end, rl_parse_tcp_options_parse_nop, rl_parse_tcp_options_parse_mss, rl_parse_tcp_options_parse_wscale, rl_parse_tcp_options_parse_sack, rl_parse_tcp_options_parse_ts" *)
  rule rl_parse_tcp_options_start if ((rg_parse_state[1] == StateParseTcpOptions) && (w_parse_tcp_options_start));
    rg_parse_state[1] <= StateStart;
    dbg3($format("%s -> %s", "parse_tcp_options", "start"));
    fetch_next_header1(0);
  endrule

  rule rl_parse_tcp_options_parse_end if ((rg_parse_state[1] == StateParseTcpOptions) && (w_parse_tcp_options_parse_end));
    rg_parse_state[1] <= StateParseEnd;
    dbg3($format("%s -> %s", "parse_tcp_options", "parse_end"));
    fetch_next_header1(8);
  endrule

  rule rl_parse_tcp_options_parse_nop if ((rg_parse_state[1] == StateParseTcpOptions) && (w_parse_tcp_options_parse_nop));
    rg_parse_state[1] <= StateParseNop;
    dbg3($format("%s -> %s", "parse_tcp_options", "parse_nop"));
    fetch_next_header1(8);
  endrule

  rule rl_parse_tcp_options_parse_mss if ((rg_parse_state[1] == StateParseTcpOptions) && (w_parse_tcp_options_parse_mss));
    rg_parse_state[1] <= StateParseMss;
    dbg3($format("%s -> %s", "parse_tcp_options", "parse_mss"));
    fetch_next_header1(32);
  endrule

  rule rl_parse_tcp_options_parse_wscale if ((rg_parse_state[1] == StateParseTcpOptions) && (w_parse_tcp_options_parse_wscale));
    rg_parse_state[1] <= StateParseWscale;
    dbg3($format("%s -> %s", "parse_tcp_options", "parse_wscale"));
    fetch_next_header1(24);
  endrule

  rule rl_parse_tcp_options_parse_sack if ((rg_parse_state[1] == StateParseTcpOptions) && (w_parse_tcp_options_parse_sack));
    rg_parse_state[1] <= StateParseSack;
    dbg3($format("%s -> %s", "parse_tcp_options", "parse_sack"));
    fetch_next_header1(16);
  endrule

  rule rl_parse_tcp_options_parse_ts if ((rg_parse_state[1] == StateParseTcpOptions) && (w_parse_tcp_options_parse_ts));
    rg_parse_state[1] <= StateParseTs;
    dbg3($format("%s -> %s", "parse_tcp_options", "parse_ts"));
    fetch_next_header1(80);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_end_load if ((rg_parse_state[0] == StateParseEnd) && (rg_buffered[0] < 8 + 8));
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, rg_tmp[0]);
    let data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    rg_tmp[0] <= zeroExtend(data);
    move_shift_amt(128);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_end_extract if ((rg_parse_state[0] == StateParseEnd) && (rg_buffered[0] >= 8 + 8));
    let data = rg_tmp[0];
    if (rg_dequeue_data[0] == True) begin
      data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    end
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, data);
    compute_next_state_parse_end();
    rg_tmp[0] <= zeroExtend(data >> 8);
    succeed_and_next(8);
    my_metadata$parse_tcp_options_counter[0] <= my_metadata$parse_tcp_options_counter[0] - 1;
    dbg3($format("extract %s %h", "parse_end", rg_dequeue_data[0]));
  endrule

  (* mutually_exclusive="rl_parse_end_parse_tcp_options" *)
  rule rl_parse_end_parse_tcp_options if ((rg_parse_state[0] == StateParseEnd) && (w_parse_end_parse_tcp_options));
    w_parse_tcp_parse_tcp_options.send();
    dbg3($format("%s -> %s", "parse_end", "parse_tcp_options"));
    //fetch_next_header(8);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_nop_load if ((rg_parse_state[0] == StateParseNop) && (rg_buffered[0] < 8 + 8));
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, rg_tmp[0]);
    let data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    rg_tmp[0] <= zeroExtend(data);
    move_shift_amt(128);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_nop_extract if ((rg_parse_state[0] == StateParseNop) && (rg_buffered[0] >= 8 + 8));
    let data = rg_tmp[0];
    if (rg_dequeue_data[0] == True) begin
      data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    end
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, data);
    compute_next_state_parse_nop();
    rg_tmp[0] <= zeroExtend(data >> 8);
    succeed_and_next(8);
    my_metadata$parse_tcp_options_counter[0] <= my_metadata$parse_tcp_options_counter[0] - 1;
    dbg3($format("extract %s %h", "parse_nop", rg_dequeue_data[0]));
  endrule

  (* mutually_exclusive="rl_parse_nop_parse_tcp_options" *)
  rule rl_parse_nop_parse_tcp_options if ((rg_parse_state[0] == StateParseNop) && (w_parse_nop_parse_tcp_options));
    w_parse_tcp_parse_tcp_options.send();
    dbg3($format("%s -> %s", "parse_nop", "parse_tcp_options"));
    //fetch_next_header(8);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_mss_load if ((rg_parse_state[0] == StateParseMss) && (rg_buffered[0] < 32 + 8));
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, rg_tmp[0]);
    let data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    rg_tmp[0] <= zeroExtend(data);
    move_shift_amt(128);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_mss_extract if ((rg_parse_state[0] == StateParseMss) && (rg_buffered[0] >= 32 + 8));
    let data = rg_tmp[0];
    if (rg_dequeue_data[0] == True) begin
      data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    end
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, data);
    compute_next_state_parse_mss();
    rg_tmp[0] <= zeroExtend(data >> 32);
    succeed_and_next(32);
    my_metadata$parse_tcp_options_counter[0] <= my_metadata$parse_tcp_options_counter[0] - 4;
    dbg3($format("extract %s %h", "parse_mss", rg_dequeue_data[0]));
  endrule

  (* mutually_exclusive="rl_parse_mss_parse_tcp_options" *)
  rule rl_parse_mss_parse_tcp_options if ((rg_parse_state[0] == StateParseMss) && (w_parse_mss_parse_tcp_options));
    w_parse_tcp_parse_tcp_options.send();
    dbg3($format("%s -> %s", "parse_mss", "parse_tcp_options"));
    //fetch_next_header(8);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_wscale_load if ((rg_parse_state[0] == StateParseWscale) && (rg_buffered[0] < 24 + 8));
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, rg_tmp[0]);
    let data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    rg_tmp[0] <= zeroExtend(data);
    move_shift_amt(128);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_wscale_extract if ((rg_parse_state[0] == StateParseWscale) && (rg_buffered[0] >= 24 + 8));
    let data = rg_tmp[0];
    if (rg_dequeue_data[0] == True) begin
      data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    end
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, data);
    compute_next_state_parse_wscale();
    rg_tmp[0] <= zeroExtend(data >> 24);
    succeed_and_next(24);
    my_metadata$parse_tcp_options_counter[0] <= my_metadata$parse_tcp_options_counter[0] - 3;
    dbg3($format("extract %s %h", "parse_wscale", rg_dequeue_data[0]));
  endrule

  (* mutually_exclusive="rl_parse_wscale_parse_tcp_options" *)
  rule rl_parse_wscale_parse_tcp_options if ((rg_parse_state[0] == StateParseWscale) && (w_parse_wscale_parse_tcp_options));
    w_parse_tcp_parse_tcp_options.send();
    dbg3($format("%s -> %s", "parse_wscale", "parse_tcp_options"));
    //fetch_next_header(8);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_sack_load if ((rg_parse_state[0] == StateParseSack) && (rg_buffered[0] < 16 + 8));
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, rg_tmp[0]);
    let data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    rg_tmp[0] <= zeroExtend(data);
    move_shift_amt(128);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_sack_extract if ((rg_parse_state[0] == StateParseSack) && (rg_buffered[0] >= 16 + 8));
    let data = rg_tmp[0];
    if (rg_dequeue_data[0] == True) begin
      data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    end
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, data);
    compute_next_state_parse_sack();
    rg_tmp[0] <= zeroExtend(data >> 16);
    succeed_and_next(16);
    my_metadata$parse_tcp_options_counter[0] <= my_metadata$parse_tcp_options_counter[0] - 2;
    dbg3($format("extract %s %h", "parse_sack", rg_dequeue_data[0]));
  endrule

  (* mutually_exclusive="rl_parse_sack_parse_tcp_options" *)
  rule rl_parse_sack_parse_tcp_options if ((rg_parse_state[0] == StateParseSack) && (w_parse_sack_parse_tcp_options));
    w_parse_tcp_parse_tcp_options.send();
    dbg3($format("%s -> %s", "parse_sack", "parse_tcp_options"));
    //fetch_next_header(8);
  endrule

  (* fire_when_enabled *)
  rule rl_parse_ts_load if ((rg_parse_state[0] == StateParseTs) && (rg_buffered[0] < 80 + 8));
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, rg_tmp[0]);
    let data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    rg_tmp[0] <= zeroExtend(data);
    move_shift_amt(128);
    dbg3($format("load tcp option ts %h", data));
  endrule

  (* fire_when_enabled *)
  rule rl_parse_ts_extract if ((rg_parse_state[0] == StateParseTs) && (rg_buffered[0] >= 80 + 8));
    let data = rg_tmp[0];
    if (rg_dequeue_data[0] == True) begin
      data = zeroExtend(data_this_cycle) << rg_shift_amt[0] | rg_tmp[0];
    end
    report_parse_action(rg_parse_state[0], rg_buffered[0], data_this_cycle, data);
    compute_next_state_parse_ts();
    rg_tmp[0] <= zeroExtend(data >> 80);
    succeed_and_next(80);
    my_metadata$parse_tcp_options_counter[0] <= my_metadata$parse_tcp_options_counter[0] - 10;
    dbg3($format("extract %s %h", "parse_ts", rg_dequeue_data[0]));
  endrule

  (* mutually_exclusive="rl_parse_ts_parse_tcp_options" *)
  rule rl_parse_ts_parse_tcp_options if ((rg_parse_state[0] == StateParseTs) && (w_parse_ts_parse_tcp_options));
    w_parse_tcp_parse_tcp_options.send();
    dbg3($format("%s -> %s", "parse_ts", "parse_tcp_options"));
    //fetch_next_header(8);
  endrule

  interface frameIn = toPut(data_in_ff);
  interface meta = toGet(meta_in_ff);
  interface verbosity = toPut(cr_verbosity_ff);
endmodule

// ====== DEPARSER ======

typedef enum {
  StateDeparseStart,
  StateEthernet,
  StateIpv4,
  StateTcp,
  StateOptionsMss,
  StateOptionsSack,
  StateOptionsTs,
  StateOptionsNop0,
  StateOptionsNop1,
  StateOptionsNop2,
  StateOptionsWscale,
  StateOptionsEnd
} DeparserState deriving (Bits, Eq);
interface Deparser;
  interface PipeIn#(MetadataT) metadata;
  interface PktWriteServer writeServer;
  interface PktWriteClient writeClient;
  interface Put#(int) verbosity;
  method DeparserPerfRec read_perf_info ();
endinterface
module mkDeparser  (Deparser);
  Reg#(int) cr_verbosity[2] <- mkCRegU(2);
  FIFOF#(int) cr_verbosity_ff <- mkFIFOF;
  rule set_verbosity;
    let x = cr_verbosity_ff.first;
    cr_verbosity_ff.deq;
    cr_verbosity[1] <= x;
  endrule

  FIFOF#(EtherData) data_in_ff <- mkFIFOF;
  FIFOF#(EtherData) data_out_ff <- mkFIFOF;
  FIFOF#(MetadataT) meta_in_ff <- mkFIFOF;
  Reg#(Bit#(32)) rg_offset <- mkReg(0);
  Reg#(Bit#(128)) rg_buff <- mkReg(0);
  Reg#(DeparserState) rg_deparse_state <- mkReg(StateDeparseStart);
  let din = data_in_ff.first;
  let meta = meta_in_ff.first;
  function Action report_deparse_action(DeparserState state, Bit#(32) offset);
    action
      if (cr_verbosity[0] > 0) begin
        $display("(%d) Deparse State %h offset %h", $time, state, offset);
      end
    endaction
  endfunction
  function Action succeed_and_next(Bit#(32) offset);
    action
      data_in_ff.deq;
      rg_offset <= offset;
    endaction
  endfunction
  function Action failed_and_trap(Bit#(32) offset);
    action
      data_in_ff.deq;
      rg_offset <= 0;
    endaction
  endfunction
  function DeparserState compute_next_state(DeparserState state);
    DeparserState nextState = StateDeparseStart;
    return nextState;
  endfunction
  function Bit#(l) read_data(UInt#(8) lhs, UInt#(8) rhs)
   provisos (Add#(a__, l, 128));
    Bit#(l) ldata = truncate(din.data) << (fromInteger(valueOf(l))-lhs);
    Bit#(l) rdata = truncate(rg_buff) >> (fromInteger(valueOf(l))-rhs);
    Bit#(l) cdata = ldata | rdata;
    return cdata;
  endfunction
  function Bit#(max) create_mask(UInt#(max) count);
    Bit#(max) v = 1 << count - 1;
    return v;
  endfunction
  rule rl_start_state if (rg_deparse_state == StateDeparseStart);
    let v = data_in_ff.first;
    if (v.sop) begin
      rg_deparse_state <= StateEthernet;
    end
    else begin
      data_in_ff.deq;
      data_out_ff.enq(v);
    end
  endrule

  function Rules build_deparse_rule_no_opt(DeparserState state, int offset, Tuple2#(Bit#(n), Bit#(n)) m, UInt#(8) clen, UInt#(8) plen)
   provisos (Mul#(TDiv#(n, 8), 8, n), Add#(a__, n, 128));
    Rules d =
    rules
      rule rl_deparse if ((rg_deparse_state == state) && (rg_offset == unpack(pack(offset))));
        report_deparse_action(rg_deparse_state, rg_offset);
        match {.meta, .mask} = m;
        Vector#(n, Bit#(1)) curr_meta = takeAt(0, unpack(byteSwap(meta)));
        Vector#(n, Bit#(1)) curr_mask = takeAt(0, unpack(byteSwap(mask)));
        Bit#(n) curr_data = read_data (clen, plen);
        $display ("read_data %h", curr_data);
        let data = apply_changes (curr_data, pack(curr_meta), pack(curr_mask));
        let data_this_cycle = EtherData { sop: din.sop, eop: din.eop, data: zeroExtend(data), mask: create_mask(cExtend(fromInteger(valueOf(n)))) };
        data_out_ff.enq (data_this_cycle);
        DeparserState next_state = compute_next_state(state);
        $display ("next_state %h", next_state);
        rg_deparse_state <= next_state;
        rg_buff <= din.data;
        // apply header removal by marking mask zero
        // apply added header by setting field at offset.
        succeed_and_next (rg_offset + cExtend(clen) + cExtend(plen));
      endrule

    endrules;
    return d;
  endfunction
  interface metadata = toPipeIn(meta_in_ff);
  interface PktWriteServer writeServer;
    interface writeData = toPut(data_in_ff);
  endinterface
  interface PktWriteClient writeClient;
    interface writeData = toGet(data_out_ff);
  endinterface
  interface verbosity = toPut(cr_verbosity_ff);
endmodule
typedef union tagged {
  struct {
    PacketInstance pkt;
  } DropReqT;
  struct {
    PacketInstance pkt;
    Bit#(9) runtime_port;
  } ForwardReqT;
} BBRequest deriving (Bits, Eq);
typedef union tagged {
  struct {
    PacketInstance pkt;
  } DropRspT;
  struct {
    PacketInstance pkt;
    Bit#(9) standard_metadata$egress_spec;
  } ForwardRspT;
} BBResponse deriving (Bits, Eq);

// ====== _DROP ======

interface Drop;
  interface Server#(BBRequest, BBResponse) prev_control_state;
endinterface
module mkDrop  (Drop);
  RX #(BBRequest) rx_prev_control_state <- mkRX;
  TX #(BBResponse) tx_prev_control_state <- mkTX;
  let rx_info_prev_control_state = rx_prev_control_state.u;
  let tx_info_prev_control_state = tx_prev_control_state.u;
  FIFOF#(PacketInstance) curr_packet_ff <- mkFIFOF;
  rule _drop_request;
    let v = rx_info_prev_control_state.first;
    rx_info_prev_control_state.deq;
    case (v) matches
      tagged DropReqT {pkt: .pkt}: begin
        curr_packet_ff.enq(pkt);
      end
    endcase
  endrule

  rule _drop_response;
    let pkt <- toGet(curr_packet_ff).get;
    BBResponse rsp = tagged DropRspT {pkt: pkt};
    tx_info_prev_control_state.enq(rsp);
  endrule

  interface prev_control_state = toServer(rx_prev_control_state.e, tx_prev_control_state.e);
endmodule

// ====== FORWARD ======

interface Forward;
  interface Server#(BBRequest, BBResponse) prev_control_state;
endinterface
module mkForward  (Forward);
  RX #(BBRequest) rx_prev_control_state <- mkRX;
  TX #(BBResponse) tx_prev_control_state <- mkTX;
  let rx_info_prev_control_state = rx_prev_control_state.u;
  let tx_info_prev_control_state = tx_prev_control_state.u;
  FIFOF#(PacketInstance) curr_packet_ff <- mkFIFOF;
  Reg#(Bit#(9)) standard_metadata$egress_spec <- mkReg(0);
  rule forward_request;
    let v = rx_info_prev_control_state.first;
    rx_info_prev_control_state.deq;
    case (v) matches
      tagged ForwardReqT {pkt: .pkt, runtime_port: .runtime_port}: begin
        standard_metadata$egress_spec <= runtime_port;
        curr_packet_ff.enq(pkt);
      end
    endcase
  endrule

  rule forward_response;
    let pkt <- toGet(curr_packet_ff).get;
    BBResponse rsp = tagged ForwardRspT {pkt: pkt, standard_metadata$egress_spec: standard_metadata$egress_spec};
    tx_info_prev_control_state.enq(rsp);
  endrule

  interface prev_control_state = toServer(rx_prev_control_state.e, tx_prev_control_state.e);
endmodule

// ====== FORWARD_TBL ======

typedef struct {
  Bit#(48) ethernet$dstAddr;
  Bit#(6) padding;
} ForwardTblReqT deriving (Bits, Eq);
typedef enum {
  DEFAULT_FORWARD_TBL,
  FORWARD,
  DROP
} ForwardTblActionT deriving (Bits, Eq);
typedef struct {
  ForwardTblActionT _action;
  Bit#(9) runtime_port;
} ForwardTblRspT deriving (Bits, Eq);
import "BDPI" function ActionValue#(Bit#(11)) matchtable_read_forward_tbl(Bit#(54) msgtype);
import "BDPI" function Action matchtable_write_forward_tbl(Bit#(54) msgtype, Bit#(11) data);
instance MatchTableSim#(0, 54, 11);
  function ActionValue#(Bit#(11)) matchtable_read(Bit#(0) id, Bit#(54) key);
    actionvalue
      let v <- matchtable_read_forward_tbl(key);
      return v;
    endactionvalue
  endfunction
  function Action matchtable_write(Bit#(0) id, Bit#(54) key, Bit#(11) data);
    action
      matchtable_write_forward_tbl(key, data);
    endaction
  endfunction
endinstance
interface ForwardTbl;
  interface Server #(MetadataRequest, MetadataResponse) prev_control_state_0;
  interface Client #(BBRequest, BBResponse) next_control_state_0;
  interface Client #(BBRequest, BBResponse) next_control_state_1;
endinterface
module mkForwardTbl  (ForwardTbl);
  RX #(MetadataRequest) rx_metadata <- mkRX;
  let rx_info_metadata = rx_metadata.u;
  TX #(MetadataResponse) tx_metadata <- mkTX;
  let tx_info_metadata = tx_metadata.u;
  Vector#(2, FIFOF#(BBRequest)) bbReqFifo <- replicateM(mkFIFOF);
  Vector#(2, FIFOF#(BBResponse)) bbRspFifo <- replicateM(mkFIFOF);
  FIFOF#(PacketInstance) packet_ff <- mkFIFOF;
  MatchTable#(0, 1024, SizeOf#(ForwardTblReqT), SizeOf#(ForwardTblRspT)) matchTable <- mkMatchTable();
  Vector#(2, Bool) readyBits = map(fifoNotEmpty, bbRspFifo);
  Bool interruptStatus = False;
  Bit#(2) readyChannel = -1;
  for (Integer i=1; i>=0; i=i-1) begin
      if (readyBits[i]) begin
          interruptStatus = True;
          readyChannel = fromInteger(i);
      end
  end

  Vector#(2, FIFOF#(MetadataT)) metadata_ff <- replicateM(mkFIFOF);
  rule rl_handle_request;
    let data = rx_info_metadata.first;
    rx_info_metadata.deq;
    let meta = data.meta;
    let pkt = data.pkt;
    let ethernet$dstAddr = fromMaybe(?, meta.ethernet$dstAddr);
    ForwardTblReqT req = ForwardTblReqT {ethernet$dstAddr: ethernet$dstAddr};
    matchTable.lookupPort.request.put(pack(req));
    packet_ff.enq(pkt);
    metadata_ff[0].enq(meta);
  endrule

  rule rl_handle_execute;
    let rsp <- matchTable.lookupPort.response.get;
    let pkt <- toGet(packet_ff).get;
    let meta <- toGet(metadata_ff[0]).get;
    if (rsp matches tagged Valid .data) begin
      ForwardTblRspT resp = unpack(data);
      case (resp._action) matches
        FORWARD: begin
          BBRequest req = tagged ForwardReqT {pkt: pkt, runtime_port: resp.runtime_port};
          bbReqFifo[0].enq(req); //FIXME: replace with RXTX.
        end
        DROP: begin
          BBRequest req = tagged DropReqT {pkt: pkt};
          bbReqFifo[1].enq(req); //FIXME: replace with RXTX.
        end
      endcase
      // forward metadata to next stage.
      metadata_ff[1].enq(meta);
    end
  endrule

  rule rl_handle_response if (interruptStatus);
    let v <- toGet(bbRspFifo[readyChannel]).get;
    let meta <- toGet(metadata_ff[1]).get;
    case (v) matches
      tagged ForwardRspT {pkt: .pkt, standard_metadata$egress_spec: .standard_metadata$egress_spec}: begin
        meta.standard_metadata$egress_spec = tagged Valid standard_metadata$egress_spec;
        MetadataResponse rsp = tagged ForwardTblForwardRspT {pkt: pkt, meta: meta};
        tx_info_metadata.enq(rsp);
      end
      tagged DropRspT {pkt: .pkt}: begin
        MetadataResponse rsp = tagged ForwardTblDropRspT {pkt: pkt, meta: meta};
        tx_info_metadata.enq(rsp);
      end
    endcase
  endrule

  interface prev_control_state_0 = toServer(rx_metadata.e, tx_metadata.e);
  interface next_control_state_0 = toClient(bbReqFifo[0], bbRspFifo[0]);
  interface next_control_state_1 = toClient(bbReqFifo[1], bbRspFifo[1]);
endmodule

// ====== INGRESS ======

interface Ingress;
  interface Client#(MetadataRequest, MetadataResponse) next;
endinterface
module mkIngress #(Vector#(numClients, Client#(MetadataRequest, MetadataResponse)) mdc) (Ingress);
  FIFOF#(MetadataRequest) default_req_ff <- mkFIFOF;
  FIFOF#(MetadataResponse) default_rsp_ff <- mkFIFOF;
  FIFOF#(MetadataRequest) forward_tbl_req_ff <- mkFIFOF;
  FIFOF#(MetadataResponse) forward_tbl_rsp_ff <- mkFIFOF;
  FIFOF#(MetadataRequest) next_req_ff <- mkFIFOF;
  FIFOF#(MetadataResponse) next_rsp_ff <- mkFIFOF;
  Vector#(numClients, Server#(MetadataRequest, MetadataResponse)) mds = replicate(toServer(default_req_ff, default_rsp_ff));
  mkConnection(mds, mdc);
  ForwardTbl forward_tbl <- mkForwardTbl();
  mkConnection(toClient(forward_tbl_req_ff, forward_tbl_rsp_ff), forward_tbl.prev_control_state_0);
  // Basic Blocks
  Forward forward_0 <- mkForward();
  Drop _drop_0 <- mkDrop();
  mkChan(mkFIFOF, mkFIFOF, forward_tbl.next_control_state_0, forward_0.prev_control_state);
  mkChan(mkFIFOF, mkFIFOF, forward_tbl.next_control_state_1, _drop_0.prev_control_state);
  rule default_next_state if (default_req_ff.notEmpty);
    default_req_ff.deq;
    let _req = default_req_ff.first;
    let meta = _req.meta;
    let pkt = _req.pkt;
    MetadataRequest req = MetadataRequest {pkt: pkt, meta: meta};
    forward_tbl_req_ff.enq(req);
  endrule

  rule forward_tbl_next_state if (forward_tbl_rsp_ff.notEmpty);
    forward_tbl_rsp_ff.deq;
    let _rsp = forward_tbl_rsp_ff.first;
    case (_rsp) matches
      tagged ForwardTblForwardRspT {meta: .meta, pkt: .pkt}: begin
        MetadataRequest req = MetadataRequest {pkt: pkt, meta: meta};
        next_req_ff.enq(req);
      end
      tagged ForwardTblDropRspT {meta: .meta, pkt: .pkt}: begin
        MetadataRequest req = MetadataRequest {pkt: pkt, meta: meta};
        next_req_ff.enq(req);
      end
    endcase
  endrule

  interface next = (interface Client#(MetadataRequest, MetadataResponse);
    interface request = toGet(next_req_ff);
    interface response = toPut(next_rsp_ff);
  endinterface);
endmodule

// ====== EGRESS ======

interface Egress;
  interface Client#(MetadataRequest, MetadataResponse) next;
endinterface
module mkEgress #(Vector#(numClients, Client#(MetadataRequest, MetadataResponse)) mdc) (Egress);
  FIFOF#(MetadataRequest) default_req_ff <- mkFIFOF;
  FIFOF#(MetadataResponse) default_rsp_ff <- mkFIFOF;
  FIFOF#(MetadataRequest) next_req_ff <- mkFIFOF;
  FIFOF#(MetadataResponse) next_rsp_ff <- mkFIFOF;
  Vector#(numClients, Server#(MetadataRequest, MetadataResponse)) mds = replicate(toServer(default_req_ff, default_rsp_ff));
  mkConnection(mds, mdc);
  // Basic Blocks
  rule default_next_state if (default_req_ff.notEmpty);
    default_req_ff.deq;
    let _req = default_req_ff.first;
    let meta = _req.meta;
    let pkt = _req.pkt;
    MetadataRequest req = MetadataRequest {pkt: pkt, meta: meta};
    next_req_ff.enq(req);
  endrule

  interface next = (interface Client#(MetadataRequest, MetadataResponse);
    interface request = toGet(next_req_ff);
    interface response = toPut(next_rsp_ff);
  endinterface);
endmodule
// Copyright (c) 2016 P4FPGA Project

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

error: pathspec 'examples/tcp_options_parser/sample-outputs/main.bsv' did not match any file(s) known to git


move Ifc names back to Top

move Ifc names back to Top

// Copyright (c) 2013 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

/* rfreqDataWrite data is FixedPoint(2,14) */
/* setCoeff data is FixedPoint(2, 23) */
interface ChannelSelectTestRequest;
   method Action rfreqDataWrite(Bit#(32) dataRe, Bit#(32) dataIm);
   method Action setCoeff(Bit#(11) addr, Bit#(32) valueRe, Bit#(32) valueIm);
endinterface

/* rfreqDataWrite data is FixedPoint(2,14) */
interface ChannelSelectTestIndication;
   method Action ifreqData(Bit#(32) dataRe, Bit#(32) dataIm);
   method Action setDataResp();
   method Action setCoeffResp();
endinterface

error: pathspec 'examples/channelselect/ChannelSelectTestInterfaces.bsv' did not match any file(s) known to git


compiles

compiles

// Copyright (c) 2014 Quanta Research Cambridge, Inc.
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import Gearbox :: *;

interface SerialFIFOIn#(type a);
   method Action enq(a din);
   method Bool notFull();
endinterface

interface SerialFIFOOut#(type a);
   method a first();
   method Action deq();
   method Bool notEmpty();
endinterface

interface SerialFIFO#(type a);
   interface SerialFIFOIn#(a) in;
   interface SerialFIFOOut#(a) out;
endinterface

module mkSerialFIFO(SerialFIFO#(a))
   provisos(Bits#(a, asize),
	    Add#(1,a__,TMul#(2,asize)),
	    Add#(asize,b__,TMul#(2,asize)),
	    Add#(1, c__, asize));

   Clock clk <- exposeCurrentClock;
   Reset rst <- exposeCurrentReset;

   Gearbox#(asize, 1, Bit#(1)) gin <- mkNto1Gearbox(clk,rst,clk,rst);
   Gearbox#(1, asize, Bit#(1)) gout <- mk1toNGearbox(clk,rst,clk,rst);

   rule movebits;
      gout.enq(gin.first);
      gin.deq();
   endrule

   interface SerialFIFOIn in;

   method Action enq(a din);
      gin.enq(unpack(pack(din)));
   endmethod

   method Bool notFull() = gin.notFull;

   endinterface

   interface SerialFIFOOut out;

   method a first();
      return(unpack(pack(gout.first)));
   endmethod

   method Action deq() = gout.deq;

   method Bool notEmpty() = gout.notEmpty;

   endinterface

endmodule

error: pathspec 'examples/noc/SerialFIFO.bsv' did not match any file(s) known to git


added avalon-st traffic controller wrapper

/*
   /home/hwang/dev/sonic-lite/scripts/../../connectal//generated/scripts/importbvi.py
   -o
   ALTERA_TRAFFIC_CONTROLLER_WRAPPER.bsv
   -I
   TrafficCtrlWrap
   -P
   TrafficCtrlWrap
   -r
   reset_n
   -c
   clk
   -f
   avl_mm
   -f
   avl_st_tx
   -f
   avl_st_rx
   -f
   mac_rx
   -f
   stop
   -f
   mon
   ../verilog/traffic_controller/avalon_st_traffic_controller.v
*/

import Clocks::*;
import DefaultValue::*;
import XilinxCells::*;
import GetPut::*;

(* always_ready, always_enabled *)
interface TrafficctrlwrapAvl_mm;
    method Action      baddress(Bit#(24) v);
    method Action      read(Bit#(1) v);
    method Bit#(32)     readdata();
    method Bit#(1)     waitrequest();
    method Action      write(Bit#(1) v);
    method Action      writedata(Bit#(32) v);
endinterface
(* always_ready, always_enabled *)
interface TrafficctrlwrapAvl_st_rx;
    method Action      data(Bit#(64) v);
    method Action      empty(Bit#(3) v);
    method Action      eop(Bit#(1) v);
    method Action      error(Bit#(6) v);
    method Bit#(1)     ready();
    method Action      sop(Bit#(1) v);
    method Action      val)(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface TrafficctrlwrapAvl_st_tx;
    method Bit#(64)     data();
    method Bit#(3)     empty();
    method Bit#(1)     eop();
    method Bit#(1)     error();
    method Action      ready(Bit#(1) v);
    method Bit#(1)     sop();
    method Bit#(1)     val();
endinterface
(* always_ready, always_enabled *)
interface TrafficctrlwrapMac_rx;
    method Action      status_data(Bit#(40) v);
    method Action      status_error(Bit#(1) v);
    method Action      status_valid(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface TrafficctrlwrapMon;
    method Bit#(1)     active();
    method Bit#(1)     done();
    method Bit#(1)     error();
endinterface
(* always_ready, always_enabled *)
(* always_ready, always_enabled *)
interface TrafficctrlwrapStop;
    method Action      mon(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface TrafficCtrlWrap;
    interface TrafficctrlwrapAvl_mm     avl_mm;
    interface TrafficctrlwrapAvl_st_rx     avl_st_rx;
    interface TrafficctrlwrapAvl_st_tx     avl_st_tx;
    interface TrafficctrlwrapMac_rx     mac_rx;
    interface TrafficctrlwrapMon     mon;
    interface TrafficctrlwrapStop     stop;
endinterface
import "BVI" avalon_st_traffic_controller =
module mkTrafficCtrlWrap#(Clock clk, Reset clk_reset, Reset reset_n)(TrafficCtrlWrap);
    default_clock clk();
    default_reset rst();
    input_clock clk(clk) = clk;
    input_reset clk_reset() = clk_reset; /* from clock*/
        input_reset reset_n(reset_n) = reset_n;
    interface TrafficctrlwrapAvl_mm     avl_mm;
        method baddress(avl_mm_baddress) enable((*inhigh*) EN_avl_mm_baddress);
        method read(avl_mm_read) enable((*inhigh*) EN_avl_mm_read);
        method avl_mm_readdata readdata();
        method avl_mm_waitrequest waitrequest();
        method write(avl_mm_write) enable((*inhigh*) EN_avl_mm_write);
        method writedata(avl_mm_writedata) enable((*inhigh*) EN_avl_mm_writedata);
    endinterface
    interface TrafficctrlwrapAvl_st_rx     avl_st_rx;
        method data(avl_st_rx_data) enable((*inhigh*) EN_avl_st_rx_data);
        method empty(avl_st_rx_empty) enable((*inhigh*) EN_avl_st_rx_empty);
        method eop(avl_st_rx_eop) enable((*inhigh*) EN_avl_st_rx_eop);
        method error(avl_st_rx_error) enable((*inhigh*) EN_avl_st_rx_error);
        method avl_st_rx_ready ready();
        method sop(avl_st_rx_sop) enable((*inhigh*) EN_avl_st_rx_sop);
        method val)(avl_st_rx_val)) enable((*inhigh*) EN_avl_st_rx_val));
    endinterface
    interface TrafficctrlwrapAvl_st_tx     avl_st_tx;
        method avl_st_tx_data data();
        method avl_st_tx_empty empty();
        method avl_st_tx_eop eop();
        method avl_st_tx_error error();
        method ready(avl_st_tx_ready) enable((*inhigh*) EN_avl_st_tx_ready);
        method avl_st_tx_sop sop();
        method avl_st_tx_val val();
    endinterface
    interface TrafficctrlwrapMac_rx     mac_rx;
        method status_data(mac_rx_status_data) enable((*inhigh*) EN_mac_rx_status_data);
        method status_error(mac_rx_status_error) enable((*inhigh*) EN_mac_rx_status_error);
        method status_valid(mac_rx_status_valid) enable((*inhigh*) EN_mac_rx_status_valid);
    endinterface
    interface TrafficctrlwrapMon     mon;
        method mon_active active();
        method mon_done done();
        method mon_error error();
    endinterface
    interface TrafficctrlwrapStop     stop;
        method mon(stop_mon) enable((*inhigh*) EN_stop_mon);
    endinterface
    schedule (avl_mm.baddress, avl_mm.read, avl_mm.readdata, avl_mm.waitrequest, avl_mm.write, avl_mm.writedata, avl_st_rx.data, avl_st_rx.empty, avl_st_rx.eop, avl_st_rx.error, avl_st_rx.ready, avl_st_rx.sop, avl_st_rx.val), avl_st_tx.data, avl_st_tx.empty, avl_st_tx.eop, avl_st_tx.error, avl_st_tx.ready, avl_st_tx.sop, avl_st_tx.val, mac_rx.status_data, mac_rx.status_error, mac_rx.status_valid, mon.active, mon.done, mon.error, stop.mon) CF (avl_mm.baddress, avl_mm.read, avl_mm.readdata, avl_mm.waitrequest, avl_mm.write, avl_mm.writedata, avl_st_rx.data, avl_st_rx.empty, avl_st_rx.eop, avl_st_rx.error, avl_st_rx.ready, avl_st_rx.sop, avl_st_rx.val), avl_st_tx.data, avl_st_tx.empty, avl_st_tx.eop, avl_st_tx.error, avl_st_tx.ready, avl_st_tx.sop, avl_st_tx.val, mac_rx.status_data, mac_rx.status_error, mac_rx.status_valid, mon.active, mon.done, mon.error, stop.mon);
endmodule

error: pathspec 'bsv/ALTERA_TRAFFIC_CONTROLLER_WRAPPER.bsv' did not match any file(s) known to git


provides fifo interface to spiregs

provides fifo interface to spiregs

// Copyright (c) 2014 Quanta Research Cambridge, Inc.
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import FIFO::*;
import SpiTap::*;

typedef struct {
   Bit#(32) a;
   Bit#(32) d;
   } SpiItem deriving(Bits);

module mkSpiRoot#(SpiTap root)(FIFO#(SpiItem));
   FIFO#(Item) request <- mkSizedFIFO(8);
   FIFO#(Item) response <- mkSizedFIFO(8);

   Reg#(Bit#(6)) countin <- mkReg(0);   /* overflow at 63 -> 0 */
   Reg#(Bit#(6)) countout <- mkReg(0);
   Reg#(Bit#(64)) shifter <- mkReg(0);
   DWire#(bit) framedrive <- mkDWire();

   /* implicit dependence on request fifo not empty */
   rule send_item
      if (countin < 32)
	 begin
	    root.datain(request.first.a[count&31]);
	    framedrive <= 1;
	    countin <= countin + 1;
	 end
      else
	 begin
	    root.datain(request.first.d[count&31]);
	    framedrive <- 1;
	    countin <= countin + 1;
	 end
      if (countin == 63)
	 request.deq();
      endrule

   rule genframe
      root.framein(framedrive);
   endrule

   rule handleFrame;
      Bit#(64) tmp;
      if (root.frameout() == 0)
	 countout <= 0;
      else
	 begin
	    countout <= countout + 1;
	    tmp = shifter;
	    tmp = tmp >> 1;
	    tmp[63] = root.dataout();
	    shifter <= tmp;
	 end
      if (countout == 63)
	 begin
	    response.put(SpiItem(a: tmp[31:0], d: tmp[63:32]});
	 end
   endrule
   // method Action enq = request.enq;

   method Action enq(SpiType x);
      request.enq(x);
   endmethod

   method Action deq();
      response.deq();
   endmethod

   method SpiType first();
      return response.first();
   endmethod

   method Action clear();
      request.clear();
      response.clear();
      countoutin <= 0;
   endmethod

endmodule

error: pathspec 'examples/serialconfig/SpiRoot.bsv' did not match any file(s) known to git


group the Ethernet MAC and PCS together

group the Ethernet MAC and PCS together

import GetPut::*;
import Clocks::*;
import Connectable::*;
import AxiBits::*;
import AxiStream::*;
import AxiEthBufferBvi::*;
import TriModeEthMacBvi::*;
import GigEthPcsPmaBvi::*;
import AxiEth1000BaseX::*;

interface AxiEthSubsystem;
   interface AxiStreamMaster#(32) m_axis_rxd;
   interface AxiStreamMaster#(32) m_axis_rxs;
   interface AxiStreamSlave#(32)  s_axis_txd;
   interface AxiStreamSlave#(32)  s_axis_txc;
   interface TrimodeethbviS_axi s_axi;
   interface TrimodeethbviMac mac;
   interface AxiethbviSfp sfp;
   interface AxiethbviMgt mgt;
   interface GigethpcspmabviSignal signal;
   interface GigethpcspmabviMmcm mmcm;
endinterface

module mkAxiEthBvi#(Clock axis_clk, Clock ref_clk)(AxiEthSubsystem);
   let reset <- exposeCurrentReset;

  // connect_bd_net -net eth_buf_RESET2PCSPMA [get_bd_pins eth_buf/RESET2PCSPMA] [get_bd_pins pcs_pma/reset] //FIXME
//   let resetToPcsPma <- mkReset(10, True, ref_clk);

   let pcs <- mkGigEthPcsPmaBvi(ref_clk, reset);
  // connect_bd_net -net pcs_pma_userclk2_out [get_bd_ports userclk2_out] [get_bd_pins eth_buf/GTX_CLK] [get_bd_pins eth_mac/gtx_clk] [get_bd_pins pcs_pma/userclk2_out]
   Clock gtx_clk = pcs.userclk2.out;

   let trimodemac <- mkTriModeMacBvi(gtx_clk, axis_clk, reset, reset, reset);

  // connect_bd_intf_net -intf_net eth_mac_gmii [get_bd_intf_pins eth_mac/gmii] [get_bd_intf_pins pcs_pma/gmii_pcs_pma]
   let gmiiConnection <- mkConnection(trimodemac.gmii, pcs.gmii);

  // connect_bd_net -net eth_mac_mdc [get_bd_pins eth_mac/mdc] [get_bd_pins pcs_pma/mdc]
   rule rl_misc;
      pcs.mdc(trimodemac.mdc()); // actually a clock
   endrule
  // connect_bd_net -net eth_mac_mdio_o [get_bd_pins eth_mac/mdio_o] [get_bd_pins pcs_pma/mdio_i]
  // connect_bd_net -net pcs_pma_mdio_o [get_bd_pins eth_mac/mdio_i] [get_bd_pins pcs_pma/mdio_o]
  let mdioConnection <- mkConnection(trimodemac.mdio, pcs.mdio);

  // connect_bd_net -net reset_inv_Res [get_bd_pins eth_mac/glbl_rstn] [get_bd_pins eth_mac/rx_axi_rstn] [get_bd_pins eth_mac/tx_axi_rstn] [get_bd_pins reset_inv/Res]

   // ports:
   // connect_bd_intf_net -intf_net eth_mac_rx_statistics [get_bd_intf_ports rx_statistics] [get_bd_intf_pins eth_mac/rx_statistics]
   // connect_bd_intf_net -intf_net eth_mac_tx_statistics [get_bd_intf_ports tx_statistics] [get_bd_intf_pins eth_mac/tx_statistics]
   // connect_bd_intf_net -intf_net mgt_clk_1 [get_bd_intf_ports mgt_clk] [get_bd_intf_pins pcs_pma/gtrefclk_in]
   // connect_bd_intf_net -intf_net pcs_pma_sfp [get_bd_intf_ports sfp] [get_bd_intf_pins pcs_pma/sfp]
   // connect_bd_intf_net -intf_net s_axi_1 [get_bd_intf_ports s_axi] [get_bd_intf_pins eth_mac/s_axi]
   // connect_bd_intf_net -intf_net s_axis_pause_1 [get_bd_intf_ports s_axis_pause] [get_bd_intf_pins eth_mac/s_axis_pause]
   // connect_bd_intf_net -intf_net s_axis_tx_1 [get_bd_intf_ports s_axis_tx] [get_bd_intf_pins eth_mac/s_axis_tx]
   // connect_bd_net -net eth_mac_mac_irq [get_bd_ports mac_irq] [get_bd_pins eth_mac/mac_irq]
   // connect_bd_net -net eth_mac_rx_axis_filter_tuser [get_bd_ports rx_axis_filter_tuser] [get_bd_pins eth_mac/rx_axis_filter_tuser]
   // connect_bd_net -net eth_mac_rx_mac_aclk [get_bd_ports rx_mac_aclk] [get_bd_pins eth_mac/rx_mac_aclk]
   // connect_bd_net -net eth_mac_rx_reset [get_bd_ports rx_reset] [get_bd_pins eth_mac/rx_reset]
   // connect_bd_net -net eth_mac_tx_mac_aclk [get_bd_ports tx_mac_aclk] [get_bd_pins eth_mac/tx_mac_aclk]
   // connect_bd_net -net eth_mac_tx_reset [get_bd_ports tx_reset] [get_bd_pins eth_mac/tx_reset]
   // connect_bd_net -net glbl_rst_1 [get_bd_ports glbl_rst] [get_bd_pins pcs_pma/reset] [get_bd_pins reset_inv/Op1]
   // connect_bd_net -net pcs_pma_gt0_qplloutclk_out [get_bd_ports gt0_qplloutclk_out] [get_bd_pins pcs_pma/gt0_qplloutclk_out]
   // connect_bd_net -net pcs_pma_gt0_qplloutrefclk_out [get_bd_ports gt0_qplloutrefclk_out] [get_bd_pins pcs_pma/gt0_qplloutrefclk_out]
   // connect_bd_net -net pcs_pma_gtrefclk_bufg_out [get_bd_ports gtref_clk_buf_out] [get_bd_pins pcs_pma/gtrefclk_bufg_out]
   // connect_bd_net -net pcs_pma_gtrefclk_out [get_bd_ports gtref_clk_out] [get_bd_pins pcs_pma/gtrefclk_out]
   // connect_bd_net -net pcs_pma_mmcm_locked_out [get_bd_ports mmcm_locked_out] [get_bd_pins pcs_pma/mmcm_locked_out]
   // connect_bd_net -net pcs_pma_pma_reset_out [get_bd_ports pma_reset_out] [get_bd_pins pcs_pma/pma_reset_out]
   // connect_bd_net -net pcs_pma_rxuserclk2_out [get_bd_ports rxuserclk2_out] [get_bd_pins pcs_pma/rxuserclk2_out]
   // connect_bd_net -net pcs_pma_rxuserclk_out [get_bd_ports rxuserclk_out] [get_bd_pins pcs_pma/rxuserclk_out]
   // connect_bd_net -net pcs_pma_status_vector [get_bd_ports status_vector] [get_bd_pins pcs_pma/status_vector]
   // connect_bd_net -net pcs_pma_userclk2_out [get_bd_ports userclk2_out] [get_bd_pins eth_mac/gtx_clk] [get_bd_pins pcs_pma/userclk2_out]
   // connect_bd_net -net pcs_pma_userclk_out [get_bd_ports userclk_out] [get_bd_pins pcs_pma/userclk_out]
   // connect_bd_net -net ref_clk_1 [get_bd_ports ref_clk] [get_bd_pins pcs_pma/independent_clock_bufg]
   // connect_bd_intf_net -intf_net eth_mac_m_axis_rx [get_bd_intf_ports m_axis_rx] [get_bd_intf_pins eth_mac/m_axis_rx]
   // connect_bd_net -net s_axi_lite_clk_1 [get_bd_ports s_axi_lite_clk] [get_bd_pins eth_mac/s_axi_aclk]
   // connect_bd_net -net s_axi_lite_resetn_1 [get_bd_ports s_axi_lite_resetn] [get_bd_pins eth_mac/s_axi_resetn]
   // connect_bd_net -net signal_detect_1 [get_bd_ports signal_detect] [get_bd_pins pcs_pma/signal_detect]
   // connect_bd_net -net tx_ifg_delay_1 [get_bd_ports tx_ifg_delay] [get_bd_pins eth_mac/tx_ifg_delay]

   interface m_axis_rxd = buffer.axi_str_rxd;
   //interface m_axis_rxs = buffer.axi_str_rxs;
   interface s_axis_txd = buffer.axi_str_txd;
   //interface s_axis_txc = buffer.axi_str_txc;
   interface s_axi = trimodemac.s_axi;
   interface mac   = trimodemac.mac;

   interface signal = pcs.signal;
   interface mmcm = pcs.mmcm;
   interface AxiethbviMgt mgt;
      method clk_clk_p = pcs.gtrefclk.p;
      method clk_clk_n = pcs.gtrefclk.n;
   endinterface
   interface AxiethbviSfp sfp;
      method txp = pcs.txp;
      method txn = pcs.txn;
      method rxp = pcs.rxp;
      method rxn = pcs.rxn;
   endinterface
endmodule

error: pathspec 'tests/spikehw/AxiEthSubsystem.bsv' did not match any file(s) known to git


wrapper for xilinx fifo

wrapper for xilinx fifo

/*
   ../../generated/scripts/importbvi.py
   -I
   SyncAxisFifo32x8
   -P
   SyncAxisFifo32x8
   -c
   m_aclk
   -c
   s_aclk
   -r
   s_aresetn
   -o
   SyncAxisFifo32x8.bsv
   cores/nfsume/dual_clock_axis_fifo_32x8/dual_clock_axis_fifo_32x8_stub.v
*/

import Clocks::*;
import CFFIFO::*;
import DefaultValue::*;
import FIFOF::*;
import XilinxCells::*;
import GetPut::*;
import AxiBits::*;
import AxiStream::*;

(* always_ready, always_enabled *)
(* always_ready, always_enabled *)
interface Syncaxisfifo32x8M_axis;
    method Bit#(32)     tdata();
    method Bit#(4)     tkeep();
    method Bit#(1)     tlast();
    method Action      tready(Bit#(1) v);
    method Bit#(1)     tvalid();
endinterface
(* always_ready, always_enabled *)
(* always_ready, always_enabled *)
interface Syncaxisfifo32x8S_axis;
    method Action      tdata(Bit#(32) v);
    method Action      tkeep(Bit#(4) v);
    method Action      tlast(Bit#(1) v);
    method Bit#(1)     tready();
    method Action      tvalid(Bit#(1) v);
endinterface
(* always_ready, always_enabled *)
interface SyncAxisFifo32x8;
    interface AxiStreamMaster#(32) m_axis;
    interface AxiStreamSlave#(32)  s_axis;
endinterface
import "BVI" dual_clock_axis_fifo_32x8 =
module mkSyncAxisFifo32x8#(Clock s_aclk, Reset s_aresetn, Clock m_aclk, Reset m_aresetn)(SyncAxisFifo32x8);
    default_clock clk();
    default_reset rst();
        input_clock m_aclk(m_aclk) = m_aclk;
        input_clock s_aclk(s_aclk) = s_aclk;
        input_reset s_aresetn(s_aresetn) clocked_by (s_aclk) = s_aresetn;
        input_reset m_aresetn_foo() clocked_by (m_aclk) = m_aresetn;
    interface AxiStreamMaster     m_axis;
        method m_axis_tdata tdata() clocked_by (m_aclk) reset_by (m_aresetn_foo);
        method m_axis_tkeep tkeep() clocked_by (m_aclk) reset_by (m_aresetn_foo);
        method m_axis_tlast tlast() clocked_by (m_aclk) reset_by (m_aresetn_foo);
        method tready(m_axis_tready) enable((*inhigh*) EN_m_axis_tready) clocked_by (m_aclk) reset_by (m_aresetn_foo);
        method m_axis_tvalid tvalid() clocked_by (m_aclk) reset_by (m_aresetn_foo);
    endinterface
    interface AxiStreamSlave     s_axis;
        method tdata(s_axis_tdata) enable((*inhigh*) EN_s_axis_tdata) clocked_by (s_aclk) reset_by (s_aresetn);
        method tkeep(s_axis_tkeep) enable((*inhigh*) EN_s_axis_tkeep) clocked_by (s_aclk) reset_by (s_aresetn);
        method tlast(s_axis_tlast) enable((*inhigh*) EN_s_axis_tlast) clocked_by (s_aclk) reset_by (s_aresetn);
        method s_axis_tready tready() clocked_by (s_aclk) reset_by (s_aresetn);
        method tvalid(s_axis_tvalid) enable((*inhigh*) EN_s_axis_tvalid) clocked_by (s_aclk) reset_by (s_aresetn);
    endinterface
    schedule (m_axis.tdata, m_axis.tkeep, m_axis.tlast, m_axis.tready, m_axis.tvalid, s_axis.tdata, s_axis.tkeep, s_axis.tlast, s_axis.tready, s_axis.tvalid) CF (m_axis.tdata, m_axis.tkeep, m_axis.tlast, m_axis.tready, m_axis.tvalid, s_axis.tdata, s_axis.tkeep, s_axis.tlast, s_axis.tready, s_axis.tvalid);
endmodule

module mkSyncAxisFifo32x8FIFOF#(Clock fromClock, Reset fromReset, Clock toClock, Reset toReset)(FIFOF#(a)) provisos (Bits#(a, asz), Add#(asz, a__, 32));
   let fromFIFOF <- mkCFFIFOF(clocked_by fromClock, reset_by fromReset);
   let syncFIFOF <- mkSyncAxisFifo32x8(fromClock, fromReset, toClock, toReset);
   let   toFIFOF <- mkCFFIFOF(clocked_by toClock, reset_by toReset);

   rule rl_from if (syncFIFOF.s_axis.tready() == 1);
      syncFIFOF.s_axis.tdata(extend(pack(fromFIFOF.first())));
      fromFIFOF.deq();
   endrule
   rule rl_from_handshake;
      syncFIFOF.s_axis.tvalid(pack(fromFIFOF.notEmpty()));
      syncFIFOF.s_axis.tkeep(maxBound);
      syncFIFOF.s_axis.tlast(1);
   endrule

   rule rl_to if (syncFIFOF.m_axis.tvalid() == 1);
      toFIFOF.enq(unpack(truncate(syncFIFOF.m_axis.tdata)));
   endrule
   rule rl_to_handshake;
      syncFIFOF.m_axis.tready(pack(toFIFOF.notFull()));
   endrule

   method notEmpty = toFIFOF.notEmpty;
   method first    = toFIFOF.first;
   method deq      = toFIFOF.deq;
   method enq      = fromFIFOF.enq;
   method notFull  = fromFIFOF.notFull;
endmodule

error: pathspec 'bsv/SyncAxisFifo32x8.bsv' did not match any file(s) known to git


conflict free fifof

conflict free fifof

// Copyright (C) 2012

// Arvind <arvind@csail.mit.edu>
// Muralidaran Vijayaraghavan <vmurali@csail.mit.edu>
// Jamey Hicks <jamey@csail.mit.edu> changed interface to FIFOF

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import FIFOF::*;
import EHRM::*;

// This Fifo2 <- mkCFFifo generates a two element FIFO where enq and deq are conflict free
// {notEmpty, first} < deq < clear < canon
// notFull < enq < clear < canon
// deq conflict free with enq

module mkCFFIFOF(FIFOF#(t)) provisos(Bits#(t, tSz));
  Ehr#(3, t) da <- mkEhr(?);
  Ehr#(3, Bool) va <- mkEhr(False);
  Ehr#(3, t) db <- mkEhr(?);
  Ehr#(3, Bool) vb <- mkEhr(False);

  rule canon if(vb[2] && !va[2]);
    da[2] <= db[2];
    va[2] <= True;
    vb[2] <= False;
  endrule

  method Bool notFull = !vb[0];

  method Action enq(t x) if(!vb[0]);
    db[0] <= x;
    vb[0] <= True;
  endmethod

  method Bool notEmpty = va[0];

  method Action deq if (va[0]);
    va[0] <= False;
  endmethod

  method t first if(va[0]);
    return da[0];
  endmethod

  method Action clear;
    vb[1] <= False;
    va[1] <= False;
  endmethod
endmodule

error: pathspec 'bsv/CFFIFO.bsv' did not match any file(s) known to git


to be removed

to be removed

// Copyright (c) 2014 Cornell University.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

package Gearbox_40_66;

import FIFO::*;
import FIFOF::*;
import Vector::*;
import GetPut::*;
import ClientServer::*;

import Pipe::*;

interface Gearbox_40_66;
   interface PipeOut#(Bit#(66)) gbOut;
endinterface

module mkGearbox40to66#(PipeOut#(Bit#(40)) pmaOut) (Gearbox_40_66);

   let verbose = False;

   FIFOF#(Bit#(40)) cf <- mkSizedFIFOF(1);
   Vector#(66, Reg#(Bit#(1))) sr0        <- replicateM(mkReg(0));
   Vector#(66, Reg#(Bit#(1))) sr1        <- replicateM(mkReg(0));

   FIFOF#(Bit#(66)) fifo_out <- mkFIFOF;
   PipeOut#(Bit#(66)) pipe_out = toPipeOut(fifo_out);

   Reg#(Bit#(6)) state <- mkReg(0);
   Reg#(Int#(8)) sh_offset <- mkReg(0);
   Reg#(Int#(8)) sh_len <- mkReg(0);

   function ActionValue#(Vector#(66, Bit#(1))) updateSR1(Bit#(66) reg0, Bit#(66) reg1, Bit#(40) din, Int#(8) offset, Int#(8) len, Bool use0) = actionvalue
      Vector#(66, Bit#(1)) sr = unpack(0);

      if (use0) begin
         sr = unpack(reg0);
      end
      else begin
         sr = unpack(reg1);
      end

      for (Int#(8) idx = offset; idx < offset + len; idx = idx+1) begin
         sr[idx] = din[idx - offset];
      end
      if (verbose) $display("SR1: %h, %h, %h, %h", sr, din, offset, len);
      return sr;
   endactionvalue;

   function ActionValue#(Vector#(66, Bit#(1))) updateSR0(Bit#(40) din, Int#(8) len, Bool update) = actionvalue
      Vector#(66, Bit#(1)) sr = unpack(0);

      if (update) begin
         for (Int#(8) idx = 0; idx < len; idx = idx + 1) begin
            Int#(8) d_start = 40 - len;
            sr[idx] = din[d_start + idx];
         end
      end
      if (verbose) $display("SR0: %h, %h, %h", sr, din, len);
      return sr;
   endactionvalue;

   function ActionValue#(Vector#(66, Bit#(1))) updateSR(Bit#(66) sr0_packed, Bit#(66) sr1_packed, Bit#(40) din, Int#(8) offset, Int#(8) len, Bool use0, Bool update) = actionvalue
      let sr1_next <- updateSR1(sr0_packed, sr1_packed, din, offset, len, use0);
      writeVReg(take(sr1), sr1_next);
      let sr0_next <- updateSR0(din, 40-len, update);
      writeVReg(take(sr0), sr0_next);
      return sr1_next;
   endactionvalue;

   function ActionValue#(Bit#(66)) updateSR1Test(Bit#(40) din, Int#(8) offset, Int#(8) len, Bool use0) = actionvalue
      Vector#(66, Bit#(1)) sr = unpack(0);

      if (use0) begin
         sr = readVReg(sr0);
      end
      else begin
         sr = readVReg(sr1);
      end

      for (Int#(8) idx = offset; idx < offset + len; idx = idx+1) begin
         sr[idx] = din[idx - offset];
      end
      if (verbose) $display("SR1: %h, %h, %h, %h", sr, din, offset, len);
      return pack(sr);
   endactionvalue;

   function ActionValue#(Bit#(66)) updateSR0Test(Bit#(40) din, Int#(8) len, Bool update) = actionvalue
      Vector#(66, Bit#(1)) sr = unpack(0);

      if (update) begin
         for (Int#(8) idx = 0; idx < len; idx = idx + 1) begin
            Int#(8) d_start = 40 - len;
            sr[idx] = din[d_start + idx];
         end
      end
      if (verbose) $display("SR0: %h, %h, %h", sr, din, len);
      return pack(sr);
   endactionvalue;

   function Action updateTest(Bit#(40) din, Int#(8) offset, Int#(8) len, Bool use0, Bool update);
      return action
      Vector#(66, Bit#(1)) sr1_next = unpack(0);

      if (use0) begin
         sr1_next = readVReg(sr0);
      end
      else begin
         sr1_next = readVReg(sr1);
      end

      for (Int#(8) idx = offset; idx < offset + len; idx = idx+1) begin
         sr1_next[idx] = din[idx - offset];
      end
      writeVReg(take(sr1), sr1_next);

      Vector#(66, Bit#(1)) sr0_next = unpack(0);
      if (update) begin
         for (Int#(8) idx = 0; idx < len; idx = idx + 1) begin
            Int#(8) d_start = 40 - len;
            sr0_next[idx] = din[d_start + idx];
         end
      end
      writeVReg(take(sr0), sr0_next);
      endaction;
   endfunction
//   function Integer getOffset (Integer curr_state);
//      let offset;
//      case (curr_state)
//          0: offset = 0;   len = 40;  useSr0 = False; updateSr = False;
//          1: offset = 40;  len = 26;  useSr0 = False; updateSr = True;
//          2: offset = 14;  len = 40;  useSr0 = True;  updateSr = False;
//          3: offset = 54;  len = 12;  useSr0 = False; updateSr = False;
//          4: offset = 28;  len = 38;  useSr0 = True;  updateSr = True;
//          5: offset = 2;   len = 40;  useSr0 = True;  updateSr = False;
//          6: offset = 42;  len = 24;  useSr0 = False; updateSr = True;
//          7: offset = 16;  len = 40;  useSr0 = True;  updateSr = False;
//          8: offset = 56;  len = 10;  useSr0 = False; updateSr = True;
//          9: offset = 30;  len = 36;  useSr0 = True;  updateSr = True;
//         10: offset = 4;   len = 40;  useSr0 = True;  updateSr = False;
//         11: offset = 44;  len = 22;  useSr0 = False; updateSr = True;
//         12: offset = 18;  len = 40;  useSr0 = True;  updateSr = False;
//         13: offset = 58;  len = 8;   useSr0 = False; updateSr = True;
//         14: offset = 32;  len = 34;  useSr0 = False; updateSr = True;
//         15: offset = 6;   len = 40;  useSr0 = True;  updateSr = False;
//         16: offset = 46;  len = 20;  useSr0 = False; updateSr = True;
//         17: offset = 20;  len = 40;  useSr0 = True;  updateSr = False;
//         18: offset = 60;  len = 6;   useSr0 = False; updateSr = True;
//         19: offset = 34;  len = 32;  useSr0 = True;  updateSr = True;
//         20: offset = 8;   len = 40;  useSr0 = True;  updateSr = False;
//         21: offset = 48;  len = 18;  useSr0 = False; updateSr = True;
//         22: offset = 22;  len = 40;  useSr0 = True;  updateSr = False;
//         23: offset = 62;  len = 4;   useSr0 = False; updateSr = True;
//         24: offset = 36;  len = 30;  useSr0 = True;  updateSr = True;
//         25: offset = 10;  len = 40;  useSr0 = True;  updateSr = False;
//         26: offset = 50;  len = 16;  useSr0 = False; updateSr = True;
//         27: offset = 24;  len = 40;  useSr0 = True;  updateSr = False;
//         28: offset = 64;  len = 2;   useSr0 = False; updateSr = True;
//         29: offset = 38;  len = 28;  useSr0 = True;  updateSr = True;
//         30: offset = 12;  len = 40;  useSr0 = True;  updateSr = False;
//         31: offset = 52;  len = 14;  useSr0 = False; updateSr = True;
//         32: offset = 26;  len = 40;  useSr0 = True;  updateSr = False;
//         default: offset = 0;
//      endcase
//      return offset;
//   endfunction
//
//   function Integer getLen (Integer curr_state);
//      let len;
//      case (curr_state)
//          0: len = 40;
//          1: len = 26;
//          2: len = 40;
//          3: len = 12;
//          4: len = 38;
//          5: len = 40;
//          6: len = 24;
//          7: len = 40;
//          8: len = 10;
//          9: len = 36;
//         10: len = 40;
//         11: len = 22;
//         12: len = 40;
//         13: len = 8;
//         14: len = 34;
//         15: len = 40;
//         16: len = 20;
//         17: len = 40;
//         18: len = 6;
//         19: len = 32;
//         20: len = 40;
//         21: len = 18;
//         22: len = 40;
//         23: len = 4;
//         24: len = 30;
//         25: len = 40;
//         26: len = 16;
//         27: len = 40;
//         28: len = 2;
//         29: len = 28;
//         30: len = 40;
//         31: len = 14;
//         32: len = 40;
//         default: len = 0;
//      endcase
//      return len;
//   endfunction
//
//   function Bool getUseSr0 (Integer curr_state);
//      let useSr0;
//      case (curr_state)
//          0: useSr0 = False;
//          1: useSr0 = False;
//          2: useSr0 = True;
//          3: useSr0 = False;
//          4: useSr0 = True;
//          5: useSr0 = True;
//          6: useSr0 = False;
//          7: useSr0 = True;
//          8: useSr0 = False;
//          9: useSr0 = True;
//         10: useSr0 = True;
//         11: useSr0 = False;
//         12: useSr0 = True;
//         13: useSr0 = False;
//         14: useSr0 = False;
//         15: useSr0 = True;
//         16: useSr0 = False;
//         17: useSr0 = True;
//         18: useSr0 = False;
//         19: useSr0 = True;
//         20: useSr0 = True;
//         21: useSr0 = False;
//         22: useSr0 = True;
//         23: useSr0 = False;
//         24: useSr0 = True;
//         25: useSr0 = True;
//         26: useSr0 = False;
//         27: useSr0 = True;
//         28: useSr0 = False;
//         29: useSr0 = True;
//         30: useSr0 = True;
//         31: useSr0 = False;
//         32: useSr0 = True;
//         default: useSr0= False;
//      endcase
//      return useSr0;
//   endfunction
//
//   function Bool getUpdateSr (Integer curr_state);
//      let updateSr;
//      case (curr_state)
//          0: updateSr = False;
//          1: updateSr = True;
//          2: updateSr = False;
//          3: updateSr = False;
//          4: updateSr = True;
//          5: updateSr = False;
//          6: updateSr = True;
//          7: updateSr = False;
//          8: updateSr = True;
//          9: updateSr = True;
//         10: updateSr = False;
//         11: updateSr = True;
//         12: updateSr = False;
//         13: updateSr = True;
//         14: updateSr = True;
//         15: updateSr = False;
//         16: updateSr = True;
//         17: updateSr = False;
//         18: updateSr = True;
//         19: updateSr = True;
//         20: updateSr = False;
//         21: updateSr = True;
//         22: updateSr = False;
//         23: updateSr = True;
//         24: updateSr = True;
//         25: updateSr = False;
//         26: updateSr = True;
//         27: updateSr = False;
//         28: updateSr = True;
//         29: updateSr = True;
//         30: updateSr = False;
//         31: updateSr = True;
//         32: updateSr = False;
//         default: updateSr= False;
//      endcase
//      return updateSr;
//   endfunction
//
   rule state_machine (cf.notEmpty);
      let value = cf.first;
      cf.deq;
      let next_state = state;
      let offset = sh_offset;
      let len = sh_len;
      let useSr0 = False;
      let updateSr = False;

      case (state)
          32: next_state = 0;
          default: next_state = next_state + 1;
      endcase

      if (offset + 40 > 66) begin
         len = 66 - offset;
         useSr0 = True;
      end
      else begin
         len = 40;
         useSr0 = False;
      end

      offset = offset + 40;
      if (offset > 66) begin
         offset = offset - 66;
      end

      if (len + offset == 66) begin
         updateSr = True;
      end
      else begin
         updateSr = False;
      end

      state     <= next_state;
      sh_offset <= offset;
      sh_len    <= len;

      //let sr <- updateSR(pack(readVReg(sr0)), pack(readVReg(sr1)), value, offset, len, useSr0, updateSr);
      //updateTest(value, offset, len, useSr0, updateSr);

      Vector#(66, Bit#(1)) sr1_next = unpack(0);

      if (useSr0) begin
         sr1_next = readVReg(sr0);
      end
      else begin
         sr1_next = readVReg(sr1);
      end

      for (Int#(8) idx = offset; idx < offset + len; idx = idx+1) begin
         sr1_next[idx] = value[idx - offset];
      end
      writeVReg(take(sr1), sr1_next);
//
//      Vector#(66, Bit#(1)) sr0_next = unpack(0);
//      if (updateSr) begin
//         for (Int#(8) idx = 0; idx < len; idx = idx + 1) begin
//            Int#(8) d_start = 40 - len;
//            sr0_next[idx] = value[d_start + idx];
//         end
//      end
//      writeVReg(take(sr0), sr0_next);

      //if (verbose) $display("state %h: %h", state, pack(sr));
   endrule

   rule pma_out;
      let v <- toGet(pmaOut).get;
      //if(verbose) $display("Rx Pma Out: %h", v);
      cf.enq(v);
   endrule

   interface gbOut = pipe_out;
endmodule

endpackage

//|State |     SR0 (66 bits)           |         SR1 (66 bits)         | Valid | Shift |
//    0    -----------------------------------------[39               0]    0       0
//    1    -------------------[13     0] [65     40][39               0]    1       1
//    2    -------------------------------------[53           14][13  0]    0       0
//    3    ----------------[27        0] [65:54][53           14][13  0]    1       1
//    4    ------------------------[1:0] [65          28][27          0]    1       1
//    5    ----------------------------------------[41           2][1:0]    0       0
//    6    ------------------[15      0] [65    42][41           2][1:0]    1       1
//    7    -------------------------------------[55          16][15   0]    0       0
//    8    -----------------[29       0] [65:56][55          16][15   0]    1       1
//    9    ------------------------[3:0] [65            30][29        0]    1       1
//   10    -------------------------------------[43          4][3     0]    0       0
//   11    --------------    [17      0] [65 44][43          4][3     0]    1       1
//   12    -------------------------------------[58       18][17      0]    0       0
//   13    ----------------[31        0] [65 58][57       18][17      0]    1       1
//   14    ----------------------- [5:0] [65            32][31        0]    1       1
//   15    --------------------------------------[45          6][5    0]    0       0
//   16    ------------------[19      0] [65  46][45          6][5    0]    1       1
//   17    -------------------------------------[59       20][19      0]    0       0
//   18    ----------------[33        0] [65  60][59      20][19      0]    1       1
//   19    ------------------------[7:0] [65        34][33            0]    1       1
//   20    -------------------------------------[47         8][7      0]    0       0
//   21    ------------------[21      0] [65   48][47       8][7      0]    1       1
//   22    ---------------------------------[61      22][21           0]    0       0
//   23    ------------[35            0] [65:62][61  22][21           0]    1       1
//   24    --------------------[9     0] [65      36][35              0]    1       1
//   25    -----------------------------------[49           10][9     0]    0       0
//   26    ------------------[23      0] [65   50][49       10][9     0]    1       1
//   27    ---------------------------------[63         24][23        0]    0       0
//   28    -----------[37             0] [65:64][63     24][23        0]    1       1
//   29    ---------------------[11   0] [65          38][37          0]    1       1
//   30    -----------------------------------[51         12][11      0]    0       0
//   31    ---------------[25         0] [65  52][51      12][11      0]    1       1
//   32    ------------------------------[65           26][25         0]    1       1

error: pathspec 'hw/lib/Gearbox_40_66.bsv' did not match any file(s) known to git


added hostchannel to paxos

added hostchannel to paxos

// Copyright (c) 2016 Cornell University.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

import Connectable::*;
import ClientServer::*;
import DbgTypes::*;
import Ethernet::*;
import GetPut::*;
import FIFO::*;
import MemMgmt::*;
import MemTypes::*;
import PacketBuffer::*;
import StoreAndForward::*;
import SharedBuff::*;
import Tap::*;

import PaxosTypes::*;
import Paxos::*;

interface HostChannel;
   interface PktWriteServer writeServer;
   interface MemWriteClient#(`DataBusWidth) writeClient;
   interface Client#(MetadataRequest, MetadataResponse) next;
   interface MemAllocClient mallocClient;
   method PktBuffDbgRec dbg;
endinterface

module mkHostChannel(HostChannel);
   let verbose = True;
   FIFO#(MetadataRequest) outReqFifo <- mkFIFO;
   FIFO#(MetadataResponse) inRespFifo <- mkFIFO;

   PacketBuffer pktBuff <- mkPacketBuffer();
   TapPktRead tap <- mkTapPktRead();
   Parser parser <- mkParser();
   StoreAndFwdFromRingToMem ingress <- mkStoreAndFwdFromRingToMem();

   mkConnection(tap.readClient, pktBuff.readServer);
   mkConnection(ingress.readClient, tap.readServer);
   mkConnection(tap.tap_out, toPut(parser.frameIn));

   rule handle_packet_process;
      let v <- ingress.eventPktCommitted.get;
      //let ipv4 <- toGet(parser.parsedOut_ipv4_dstAddr).get;
      //if (verbose) $display("HostChannel: ipv4=%h, size=%d", ipv4, v.size);
      //MetadataRequest nextReq = tagged RouteLookupRequest {pkt: v, dstip: ipv4};
      //outReqFifo.enq(nextReq);
   endrule

   interface writeServer = pktBuff.writeServer;
   interface writeClient = ingress.writeClient;
   interface next = (interface Client#(MetadataRequest, MetadataResponse);
      interface request = toGet(outReqFifo);
      interface response = toPut(inRespFifo);
   endinterface);
   interface mallocClient = ingress.malloc;
   method dbg = pktBuff.dbg;
endmodule

error: pathspec 'p4/examples/paxos/HostChannel.bsv' did not match any file(s) known to git


Forgot to add BSV side of JtagGetPut example

import JtagGetPut::*;
import GetPut::*;
import FIFOF::*;
import SpecialFIFOs::*;
import Connectable::*;

typedef Bit#(8) Byte;

(* synthesize, clock_prefix="CLOCK_50", reset_prefix="RST_N" *)
module mkExample(Empty);
    Get#(Byte) byteIn <- mkJtagGet("IN", mkSizedFIFOF(10));
    Put#(Byte) byteOut <- mkJtagPut("OUT", mkPipelineFIFOF);
    mkConnection(byteIn, byteOut);
endmodule

error: pathspec 'ExampleFIFOs.bsv' did not match any file(s) known to git