#
#   trace_gen.py
#

import numpy as np

class TraceGen:

  # constructor
  def __init__(self, vaddr_width_p, ptag_width_p, instr_width_p):
    self.vaddr_width_p = vaddr_width_p
    self.ptag_width_p = ptag_width_p
    self.instr_width_p = instr_width_p
    self.packet_len = vaddr_width_p + ptag_width_p + 1 # A bit is added to denote cached/uncached accesses

  # print header
  def print_header(self):
    header = "// generated by trace_gen.py \n"
    header += "// packet_len = " + str(self.packet_len) + "\n" 
    return header

  # send load
  def send_load(self, vaddr, ptag, uncached):
    packet = "0001_"
    
    if(uncached):
      packet += "1_"
    else:
      packet += "0_"

    packet += format(vaddr, "0"+str(self.vaddr_width_p)+"b") + "_"
    packet += format(ptag, "0"+str(self.ptag_width_p)+"b") + "\n"
    return packet

  # receive data
  # data: expected data
  def recv_data(self, data):
    packet = "0010_"
    packet += "0"*(self.packet_len - self.instr_width_p) + "_" + format(data, "0"+str(self.instr_width_p)+"b") + "\n"
    return packet

  # wait for a number of cycles
  # num_cycles: number of cycles to wait.
  def wait(self, num_cycles):
    command = "0110_" + format(num_cycles, "0" + str(self.packet_len) + "b") + "\n"
    command += "0101_" + (self.packet_len)*"0" + "\n"
    return command

  # finish trace
  def test_finish(self):
    command = "// FINISH \n"
    command += self.wait(8)
    command += "0100_" + (self.packet_len)*"0" + "\n"
    return command

  def test_done(self):
    command = "// DONE \n"
    command += self.wait(8)
    command += "0011_" + (self.packet_len)*"0" + "\n"
    return command

  # wait for a single cycle
  def nop(self):
    return "0000_" + "0"*(self.packet_len) + "\n"

  def print_comment(self, comment):
    return "// " + comment + "\n"
