๐Ÿ“ฆ danielfspencer / blizzard-4-hw

๐Ÿ“„ interface.js ยท 114 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114const segfault_hanlder = require('segfault-handler')
segfault_hanlder.registerHandler('crash.log')

const process = require('process')
const { ffi } = require("fastcall")
const { spawnSync } = require("child_process")

const Model = require('../model')
const TIMEOUT = 60 * 1000

class HardwareModel extends Model {
  constructor () {
    super()
    process.chdir(__dirname)

    this.instance = ffi.Library('obj_dir/blizzard_4.so', {
      init: ['void', []],
      destroy: ['void', []],
      reset: ['void', []],

      _step: ['void', ['int']],
      _read: ['int', ['int']],
      _write: ['void', ['int','int']],
      _copy: ['void', ['int','int']],

      get_read_bus: ['int', []],
      get_data_bus: ['int', []],
      get_write_bus: ['int', []]
    })

    this.instance.init()
  }

  toString () {
    return '[HardwareModel]'
  }

  destroy () {
    this.instance.destroy()
    this.instance = null
  }

  reset () {
    this.instance.reset()
  }

  step (cycles) {
    if (cycles === undefined) {
      cycles = 1
    }
    this.instance._step(cycles)
  }

  get read_bus () {
    return this.instance.get_read_bus()
  }

  get data_bus () {
    return this.instance.get_data_bus()
  }

  get write_bus () {
    return this.instance.get_write_bus()
  }

  read(value) {
    return this.instance._read(value)
  }

  write(value, addr) {
    this.instance._write(value, addr)
  }

  copy(source, dest) {
    this.instance._copy(source, dest)
  }
}

function run_step(name, cmd, cwd) {
  let val = spawnSync(cmd, { cwd: cwd, shell: true, timeout: TIMEOUT })

  if (val.error || (val.status != 0)) {
    console.error(`> Step '${name}' failed when running command:`)
    console.error(`'${cmd}'\n`)

    if (val.error) {
      console.error(`Node error:\n\n${val.error}`)
    } else {
      console.error(`> Process returned code ${val.status}, stderr:\n${val.stderr}`)
    }

    console.error("> Model build failed")
    process.exit(1)
  } else {
    // console.debug(val.stdout.toString())
  }
}

module.exports.HardwareModel = HardwareModel

module.exports.build = () => {
  const STEPS = [
    ['Verilog to C++',         `verilator blizzard_4.v -Imodules -Igeneric --trace --cc -Wno-fatal --exe main.cpp -CFLAGS "-fpic" -O3 --x-initial unique`],
    ['C++ compile',            `make -j OPT_FAST="-O3" -C obj_dir -f Vblizzard_4.mk`],
    ['Create dynamic library', `gcc -shared *.o -o blizzard_4.so`, 'obj_dir']
  ]
  process.chdir(__dirname)

  console.log("Building HardwareModel...")
  for (let [name, cmd, cwd] of STEPS) {
    run_step(name, cmd, cwd)
  }
}