start a2l2wb

pd
openpowerwtf 2 years ago
parent bc0e3204b7
commit 0dcb681aad

@ -0,0 +1,33 @@
# a2o tb-node

SIM_BUILD ?= build_node
SIM ?= icarus

# icarus
VERILOG_ROOT = ../../verilog

COMPILE_ARGS = -I$(VERILOG_ROOT)/trilib -I$(VERILOG_ROOT)/work -y$(VERILOG_ROOT)/unisims -y$(VERILOG_ROOT)/trilib_clk1x -y$(VERILOG_ROOT)/trilib -y$(VERILOG_ROOT)/work -y$(VERILOG_ROOT)/a2node

# other options

# rtl
TOPLEVEL_LANG = verilog
# top-level to enable trace, etc.
VERILOG_SOURCES = ./cocotb_icarus_node.v
TOPLEVEL = cocotb_icarus_node

# python test
MODULE = tb_node

# cocotb make rules
include $(shell cocotb-config --makefiles)/Makefile.sim

build: clean sim fst

run: sim fst

vcd: sim

fst:
vcd2fst a2onode.vcd a2onode.fst
rm a2onode.vcd

@ -0,0 +1,231 @@

`include "tri_a2o.vh"

`timescale 1ns/1ps

// might add some sim-only lines to enable clks, etc.

module cocotb_icarus_node (

input[0:`NCLK_WIDTH-1] nclk,
input scan_in,
output scan_out,

// Pervasive clock control
input an_ac_rtim_sl_thold_8,
input an_ac_func_sl_thold_8,
input an_ac_func_nsl_thold_8,
input an_ac_ary_nsl_thold_8,
input an_ac_sg_8,
input an_ac_fce_8,
input [0:7] an_ac_abst_scan_in,

//SCOM Satellite
input [0:3] an_ac_scom_sat_id,
input an_ac_scom_dch,
input an_ac_scom_cch,
output ac_an_scom_dch,
output ac_an_scom_cch,

// FIR and Error Signals
output [0:`THREADS-1] ac_an_special_attn,
output [0:2] ac_an_checkstop,
output [0:2] ac_an_local_checkstop,
output [0:2] ac_an_recov_err,
output ac_an_trace_error,
output ac_an_livelock_active,
input [0:`THREADS-1] an_ac_external_mchk,
output an_ac_checkstop,

// Perfmon Event Bus
output [0:4*`THREADS-1] ac_an_event_bus0,
output [0:4*`THREADS-1] ac_an_event_bus1,

// Reset related
input an_ac_reset_1_complete,
input an_ac_reset_2_complete,
input an_ac_reset_3_complete,
input an_ac_reset_wd_complete,

// Power Management
output [0:`THREADS-1] ac_an_pm_thread_running,
input [0:`THREADS-1] an_ac_pm_thread_stop,
input [0:`THREADS-1] an_ac_pm_fetch_halt,
output ac_an_power_managed,
output ac_an_rvwinkle_mode,
input an_ac_flh2l2_gate,

// Clock, Test, and LCB Controls
input an_ac_gsd_test_enable_dc,
input an_ac_gsd_test_acmode_dc,
input an_ac_ccflush_dc,
input an_ac_ccenable_dc,
input an_ac_lbist_en_dc,
input an_ac_lbist_ip_dc,
input an_ac_lbist_ac_mode_dc,
input an_ac_scan_diag_dc,
input an_ac_scan_dis_dc_b,

//Thold input to clock control macro
input [0:8] an_ac_scan_type_dc,

// Pervasive
output ac_an_reset_1_request,
output ac_an_reset_2_request,
output ac_an_reset_3_request,
output ac_an_reset_wd_request,
input an_ac_lbist_ary_wrt_thru_dc,
input [0:`THREADS-1] an_ac_sleep_en,
input [0:`THREADS-1] an_ac_ext_interrupt,
input [0:`THREADS-1] an_ac_crit_interrupt,
input [0:`THREADS-1] an_ac_perf_interrupt,
input [0:`THREADS-1] an_ac_hang_pulse,
input an_ac_tb_update_enable,
input an_ac_tb_update_pulse,
input [0:3] an_ac_chipid_dc,
input [0:7] an_ac_coreid,
output [0:`THREADS-1] ac_an_machine_check,
input an_ac_debug_stop,
output [0:`THREADS-1] ac_an_debug_trigger,
input [0:`THREADS-1] an_ac_uncond_dbg_event,
output [0:31] ac_an_debug_bus,
output ac_an_coretrace_first_valid,
output ac_an_coretrace_valid,
output [0:1] ac_an_coretrace_type,

output [0:31] mem_adr,
input [0:127] mem_dat,
output mem_wr_val,
output [0:15] mem_wr_be,
output [0:127] mem_wr_dat,

output wb_stb,
output wb_cyc,
output [31:0] wb_adr,
output wb_we,
output [3:0] wb_sel,
output [31:0] wb_datw,
input wb_ack,
input [31:0] wb_datr

);

a2owb c0 (
.nclk(nclk),
.scan_in(scan_in),
.scan_out(scan_out),

// Pervasive clock control
.an_ac_rtim_sl_thold_8(an_ac_rtim_sl_thold_8),
.an_ac_func_sl_thold_8(an_ac_func_sl_thold_8),
.an_ac_func_nsl_thold_8(an_ac_func_nsl_thold_8),
.an_ac_ary_nsl_thold_8(an_ac_ary_nsl_thold_8),
.an_ac_sg_8(an_ac_sg_8),
.an_ac_fce_8(an_ac_fce_8),
.an_ac_abst_scan_in(an_ac_abst_scan_in),

//SCOM Satellite
.an_ac_scom_sat_id(an_ac_scom_sat_id),
.an_ac_scom_dch(an_ac_scom_dch),
.an_ac_scom_cch(an_ac_scom_cch),
.ac_an_scom_dch(ac_an_scom_dch),
.ac_an_scom_cch(ac_an_scom_cch),

// FIR and Error Signals
.ac_an_special_attn(ac_an_special_attn),
.ac_an_checkstop(ac_an_checkstop),
.ac_an_local_checkstop(ac_an_local_checkstop),
.ac_an_recov_err(ac_an_recov_err),
.ac_an_trace_error(ac_an_trace_error),
.ac_an_livelock_active(ac_an_livelock_active),
.an_ac_checkstop(an_ac_checkstop),
.an_ac_external_mchk(an_ac_external_mchk),

// Perfmon Event Bus
.ac_an_event_bus0(ac_an_event_bus0),
.ac_an_event_bus1(ac_an_event_bus1),

// Reset related
.an_ac_reset_1_complete(an_ac_reset_1_complete),
.an_ac_reset_2_complete(an_ac_reset_2_complete),
.an_ac_reset_3_complete(an_ac_reset_3_complete),
.an_ac_reset_wd_complete(an_ac_reset_wd_complete),

// Power Management
.ac_an_pm_thread_running(ac_an_pm_thread_running),
.an_ac_pm_thread_stop(an_ac_pm_thread_stop),
.ac_an_power_managed(ac_an_power_managed),
.ac_an_rvwinkle_mode(ac_an_rvwinkle_mode),
.an_ac_pm_fetch_halt(an_ac_pm_fetch_halt),

// Clock, Test, and LCB Controls
.an_ac_gsd_test_enable_dc(an_ac_gsd_test_enable_dc),
.an_ac_gsd_test_acmode_dc(an_ac_gsd_test_acmode_dc),
.an_ac_ccflush_dc(an_ac_ccflush_dc),
.an_ac_ccenable_dc(an_ac_ccenable_dc),
.an_ac_lbist_en_dc(an_ac_lbist_en_dc),
.an_ac_lbist_ip_dc(an_ac_lbist_ip_dc),
.an_ac_lbist_ac_mode_dc(an_ac_lbist_ac_mode_dc),
.an_ac_scan_diag_dc(an_ac_scan_diag_dc),
.an_ac_scan_dis_dc_b(an_ac_scan_dis_dc_b),

//Thold input to clock control macro
.an_ac_scan_type_dc(an_ac_scan_type_dc),

// Pervasive
.ac_an_reset_1_request(ac_an_reset_1_request),
.ac_an_reset_2_request(ac_an_reset_2_request),
.ac_an_reset_3_request(ac_an_reset_3_request),
.ac_an_reset_wd_request(ac_an_reset_wd_request),
.an_ac_lbist_ary_wrt_thru_dc(an_ac_lbist_ary_wrt_thru_dc),
.an_ac_sleep_en(an_ac_sleep_en),
.an_ac_ext_interrupt(an_ac_ext_interrupt),
.an_ac_crit_interrupt(an_ac_crit_interrupt),
.an_ac_perf_interrupt(an_ac_perf_interrupt),
.an_ac_hang_pulse(an_ac_hang_pulse),
.an_ac_tb_update_enable(an_ac_tb_update_enable),
.an_ac_tb_update_pulse(an_ac_tb_update_pulse),
.an_ac_chipid_dc(an_ac_chipid_dc),
.an_ac_coreid(an_ac_coreid),
.ac_an_machine_check(ac_an_machine_check),
.an_ac_debug_stop(an_ac_debug_stop),
.ac_an_debug_trigger(ac_an_debug_trigger),
.an_ac_uncond_dbg_event(an_ac_uncond_dbg_event),

// direct-attach mem
.mem_adr(mem_adr),
.mem_dat(mem_dat),
.mem_wr_val(mem_wr_val),
.mem_wr_be(mem_wr_be),
.mem_wr_dat(mem_wr_dat),

// wishbone
.wb_stb(wb_stb),
.wb_cyc(wb_cyc),
.wb_adr(wb_adr),
.wb_we(wb_we),
.wb_ack(wb_ack),
.wb_sel(wb_sel),
.wb_datr(wb_datr),
.wb_datw(wb_datw)
);

initial begin
$dumpfile ("a2onode.vcd");
// you can do it by levels and also by module so could prune down
$dumpvars;
// need to explicitly specify arrays for icarus
// guess not: $dumpvars cannot dump a vpiMemory
//$dumpvars(0, c0.iuq0.iuq_slice_top0.slice0.iuq_ibuf0.buffer_data_q);
#1;
end

// see if coco lets me risingedge() these
wire clk_1x, clk_2x, clk_4x, rst;

assign clk_1x = nclk[0];
assign clk_2x = nclk[2];
assign clk_4x = nclk[3];
assign rst = nclk[1];

endmodule

@ -0,0 +1,5 @@
# Cocotb Sim

```
make -f Makefile.node build |& grep -v Anac
```

@ -0,0 +1,326 @@
# a2o test tb
# a2owb with external sim mem interface

import cocotb
from cocotb.clock import Clock
from cocotb.triggers import Timer
from cocotb.triggers import FallingEdge
from cocotb.handle import Force
from cocotb.handle import Release

import itertools
from dotmap import DotMap

from OPEnv import *
from A2O import *
from A2L2 import *

# ------------------------------------------------------------------------------------------------
# Tasks

# get rid of z on anything that will be sampled here
# is there a func to get all inputs?
async def init(dut, sim):
"""Initialize inputs. """

dut.nclk.value = 0
dut.scan_in.value = 0
dut.an_ac_scan_type_dc.value = 0x0
dut.an_ac_chipid_dc.value = 0x0
dut.an_ac_coreid.value = 0x0
dut.an_ac_scom_sat_id.value = 0x0

dut.an_ac_lbist_ary_wrt_thru_dc.value = 0
dut.an_ac_gsd_test_enable_dc.value = 0
dut.an_ac_gsd_test_acmode_dc.value = 0
dut.an_ac_ccflush_dc.value = 0
dut.an_ac_ccenable_dc.value = 0
dut.an_ac_lbist_en_dc.value = 0
dut.an_ac_lbist_ip_dc.value = 0
dut.an_ac_lbist_ac_mode_dc.value = 0
dut.an_ac_scan_diag_dc.value = 0
dut.an_ac_scan_dis_dc_b.value = 0

dut.an_ac_rtim_sl_thold_8.value = 0
dut.an_ac_func_sl_thold_8.value = 0
dut.an_ac_func_nsl_thold_8.value = 0
dut.an_ac_ary_nsl_thold_8.value = 0
dut.an_ac_sg_8.value = 0
dut.an_ac_fce_8.value = 0
dut.an_ac_abst_scan_in.value = 0

dut.an_ac_reset_1_complete.value = 0
dut.an_ac_reset_2_complete.value = 0
dut.an_ac_reset_3_complete.value = 0
dut.an_ac_reset_wd_complete.value = 0

dut.an_ac_pm_fetch_halt.value = 0
dut.an_ac_debug_stop.value = 0

dut.an_ac_tb_update_enable.value = 1
dut.an_ac_tb_update_pulse.value = 0 # tb clock if xucr0[tcs]=1 (must be <1/2 proc clk; tb pulse is 2x this clock)

# why is coco turning [0] into non-vector??? or is that gpi/vpi/icarus/???
if sim.threads == 1:
dut.an_ac_pm_thread_stop.value = 0x1
dut.an_ac_external_mchk.value = 0
dut.an_ac_sleep_en.value = 0
dut.an_ac_ext_interrupt.value = 0
dut.an_ac_crit_interrupt.value = 0
dut.an_ac_perf_interrupt.value = 0
dut.an_ac_hang_pulse.value = 0
dut.an_ac_uncond_dbg_event.value = 0
else:
for i in range(sim.threads):
dut.an_ac_pm_thread_stop[i].value = 0x1
dut.an_ac_external_mchk[i].value = 0
dut.an_ac_sleep_en[i].value = 0
dut.an_ac_ext_interrupt[i].value = 0
dut.an_ac_crit_interrupt[i].value = 0
dut.an_ac_perf_interrupt[i].value = 0
dut.an_ac_hang_pulse[i].value = 0
dut.an_ac_uncond_dbg_event[i].value = 0

await Timer(9, units='ns')

async def config(dut, sim):
"""Configure node, etc. """

await RisingEdge(dut.clk_1x)

# trilib/tri.vh:`define NCLK_WIDTH 6 // 0 1xClk, 1 Reset, 2 2xClk, 3 4xClk, 4 Even .5xClk, 5 Odd .5xClk
async def genReset(dut, sim):
"""Generate reset. """

first = True
done = False

while not done:
await RisingEdge(dut.clk_1x)
if sim.cycle < sim.resetCycle:
if first:
dut._log.info(f'[{sim.cycle:08d}] Resetting...')
first = False
dut.nclk[1].value = 1
elif not done:
dut._log.info(f'[{sim.cycle:08d}] Releasing reset.')
dut.nclk[1].value = 0
done = True
sim.resetDone = True

async def genClocks(dut, sim):
"""Generate 1x, 2x, 4x clock pulses, depending on parms. """

if sim.clk2x and sim.clk4x:
sim.clk1x = Clock(dut.nclk[0], 8, 'ns')
await cocotb.start(sim.clk1x.start())
sim.clk2x = Clock(dut.nclk[2], 4, 'ns')
await cocotb.start(sim.clk2x.start())
sim.clk4x = Clock(dut.nclk[3], 2, 'ns')
await cocotb.start(sim.clk4x.start())
elif sim.clk2x:
sim.clk1x = Clock(dut.nclk[0], 8, 'ns')
await cocotb.start(sim.clk1x.start())
sim.clk2x = Clock(dut.nclk[2], 4, 'ns')
await cocotb.start(sim.clk2x.start())
else:
sim.clk1x = Clock(dut.nclk[0], 8, 'ns')
await cocotb.start(sim.clk1x.start())


for cycle in range(sim.maxCycles):

sim.cycle = cycle

if cycle % sim.hbCycles == 0:
dut._log.info(f'[{cycle:08d}] ...tick...')

await RisingEdge(dut.clk_1x)

dut._log.info(f'[{sim.cycle:08d}] Reached max cycle. Clocks stopped.')
sim.ok = False
sim.fail = 'Max cycle reached.'

# 16B interface
async def memory(dut, sim):
"""Handle external memory interface (BE)"""

me = 'Memory'
ok = True
sim.msg(f'{me}: started.')

while ok:
await RisingEdge(dut.clk_1x)

try:
addr = dut.mem_adr.value.integer
w0 = sim.mem.read(addr)
w1 = sim.mem.read(addr+4)
w2 = sim.mem.read(addr+8)
w3 = sim.mem.read(addr+12)
v = cocotb.binary.BinaryValue()
v.assign(f'{w0:0>32b}{w1:0>32b}{w2:0>32b}{w3:0>32b}')
dut.mem_dat.value = v.value
except Exception as e:
#print(e)
dut.mem_dat.value = 0

if dut.mem_wr_val.value:
addr = dut.mem_adr.value.integer
dat = hex(dut.mem_wr_dat, 32)
be = f'{dut.mem_wr_be.value.integer:016b}'
for i in range(4):
sim.mem.write(addr, dat[i*8:i*8+8], be[i*4:i*4+4])
addr += 4

sim.msg(f'{me}: ended.')

async def checker(dut, sim):
"""Watch for error indicators"""

me = 'Node Checker'
ok = True
sim.msg(f'{me}: started.')

# errors
nodeCheckstop = dut.an_ac_checkstop
errors = [
{'name': 'A2Node Checkstop', 'sig': nodeCheckstop}
]

while ok:

await RisingEdge(dut.clk_1x)

if not sim.resetDone:
continue

for i in range(len(errors)):
assert errors[i]['sig'].value == 0, f'{me} Error: {errors[i]["name"]}'


# ------------------------------------------------------------------------------------------------
# Interfaces

# SCOM
async def scom(dut, sim):
"""scom interface"""

dut.an_ac_scom_dch.value = 0
dut.an_ac_scom_cch.value = 0


# ------------------------------------------------------------------------------------------------
# Do something

@cocotb.test()
async def tb_node(dut):
"""A Vulgar Display of OpenPower"""

sim = Sim(dut)
sim.mem = Memory(sim)
sim.maxCycles = 20000

'''
# rom
sim.memFiles = ['../mem/boot.bin.hex'] #wtf cmdline parm

for i in range(len(sim.memFiles)): #wtf el should be object with name, format, etc.
sim.mem.loadFile(sim.memFiles[i])
'''

'''
# rom+test; should end at 700
sim.memFiles = [
{
'addr': 0x00000000,
'file' : '../mem/test1/rom.init'
},
{
'addr': 0x10000000,
'file' : '../mem/test1/test.init'
}
]
'''
'''
# rom+bios; should end at 7FC
sim.memFiles = [
{
'addr': 0x00000000,
'file' : '../mem/test2/rom.init'
}
]
'''

# rom+bios+arcitst
sim.memFiles = [
{
'addr': 0x00000000,
'file' : '../mem/test3/rom.init'
}
]

for i in range(len(sim.memFiles)): #wtf el should be object with name, format, etc.
sim.mem.loadFile(sim.memFiles[i]['file'], addr=sim.memFiles[i]['addr'])

if sim.resetAddr is not None and sim.mem.read(sim.resetAddr) == sim.mem.default:
sim.mem.write(sim.resetAddr, sim.resetOp)
sim.msg(f'Set reset fetch @{sim.resetAddr:08X} to {sim.resetOp:08X}.')

# init stuff
await init(dut, sim)

# start clocks,reset
await cocotb.start(genClocks(dut, sim))
await cocotb.start(genReset(dut, sim))

# start interfaces
await cocotb.start(scom(dut, sim))

sim.a2o = A2OCore(sim, dut.c0.c0)
sim.a2o.traceFacUpdates = True
sim.a2o.stopOnLoop = 50
sim.a2o.iarPass = 0x7F0
sim.a2o.iarFail = 0x7F4

await cocotb.start(A2O.driver(dut, sim))

await cocotb.start(memory(dut, sim))
#await cocotb.start(A2L2.driver(dut, sim))
await cocotb.start(A2L2.checker(dut, sim))
await cocotb.start(A2L2.monitor(dut, sim, watchTrans=True))

await Timer((sim.resetCycle + 5)*8, units='ns')
if dut.nclk[1].value != 0:
sim.ok = False
sim.fail = 'Reset active too long!'

# config stuff
# original fpga design needed 4 cred, no fwd (set in logic currently)
sim.a2o.config.creditsLd = 1
sim.a2o.config.creditsSt = 1
sim.a2o.config.creditsLdStSingle = True # need for node right now
#sim.a2o.lsDataForward = 0 # disable=1
#sim.a2o.cpcr4_sq_cnt = 0 # default=6

await A2O.config(dut, sim)

await cocotb.start(A2O.checker(dut, sim))
await cocotb.start(A2O.monitor(dut, sim))

await cocotb.start(checker(dut, sim))

# release thread(s)
dut.an_ac_pm_thread_stop.value = 0
await RisingEdge(dut.clk_1x)
dut._log.info(f'[{sim.cycle:08d}] Threads enabled.')

# should await sim.done
await Timer((sim.maxCycles+100)*8, units='ns')

if sim.ok:
dut._log.info(f'[{sim.cycle:08d}] You has opulence.')
else:
dut._log.info(f'[{sim.cycle:08d}] You are worthless and weak!')
dut._log.info(f'[{sim.cycle:08d}] {sim.fail}')
assert False

@ -0,0 +1,683 @@
48000400
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
7CBE6AA6
2C250000
408200E0
3C608C00
3800001F
38400015
38800000
3900023F
7C7CFBA6
7C4011A6
7C8009A6
7D0001A6
4C00012C
39400000
654A0000
614A003F
3800001E
38800000
64840001
60840000
39000000
65080001
61080000
6108023F
7D4011A6
7C8009A6
7D0001A6
4C00012C
3C608800
3800000F
3840003F
38800000
3900023F
7C7CFBA6
7C4011A6
7C8009A6
7D0001A6
4C00012C
3800000D
38800000
64840001
60840000
39000000
65080001
61080000
6108023F
7D4011A6
7C8009A6
7D0001A6
4C00012C
48000004
39400000
654A8002
614AB000
7D400124
4C00012C
802008F0
48000020
39400000
654A8002
614AB000
7D400124
4C00012C
802008F4
48000004
3C600000
60630900
7C6903A6
7C7E6AA6
4E800421
480002E4
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
48000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
0001FFF8
0000FFF8
60000000
60000000
9421FFC0
90610038
3D200001
81290000
9121000C
81210038
2C090000
4182000C
3920FFFF
4800017C
3D200000
81290AAC
91210008
48000028
8121000C
39490004
9141000C
81410008
814A0000
91490000
81210008
39290004
91210008
3D200000
81290AAC
81410008
7C0A4840
4180FFCC
3D200001
81290000
91210008
48000020
3D200001
81290000
39400000
91490000
81210008
39290004
91210008
3D200001
81290000
81410008
7C0A4840
4180FFD4
3D200300
91210030
81210030
3C800000
60840009
7C934BA6
60000000
39200000
9121002C
8121002C
3C800000
60840009
7C9603A6
60000000
39200000
91210028
81210028
3C800000
60840009
7C9D43A6
60000000
39200000
91210024
81210024
3C800000
60840009
7C9C43A6
60000000
3D20FE00
91210020
81210020
3C800000
60840009
7C9053A6
60000000
7D36FAA6
9121001C
8121001C
552905AC
91210018
81210018
3C800000
60840009
7C96FBA6
60000000
39200000
91210014
81210014
3C800000
60840009
7C9053A6
60000000
39200000
91210010
81210010
3C800000
60840009
7C9453A6
60000000
39200000
7D234B78
38210040
4E800020

File diff suppressed because it is too large Load Diff

@ -27,11 +27,16 @@
// obtained (along with the Power ISA) here: https://openpowerfoundation.org. // obtained (along with the Power ISA) here: https://openpowerfoundation.org.


// A2L2 bridge // A2L2 bridge
// 1. interface to a sim mem[] // single req (shared L/S credit)
// 2. interface to wb (could use mem for l2 also) // interface to a sim mem[]


a2l2wb n0( `include "tri_a2o.vh"
parameter MEM_QW = 16384;
`timescale 1ns/1ps

module a2l2wb #(
parameter MEM_MODE = 0, // 0:ext 1:int 2:wb
parameter MEM_QW = 16384
) )
( (
input clk, input clk,
@ -88,26 +93,25 @@ a2l2wb n0(
output [0:7] an_ac_back_inv_lpar_id, output [0:7] an_ac_back_inv_lpar_id,
input ac_an_back_inv_reject, input ac_an_back_inv_reject,
input [0:7] ac_an_lpar_id, input [0:7] ac_an_lpar_id,
output an_ac_checkstop,


// direct-attach mem
output [0:31] mem_adr, output [0:31] mem_adr,
input [0:127] mem_dat, input [0:127] mem_dat,
output mem_wr_val, output mem_wr_val,
output [0:15] mem_wr_be,
output [0:127] mem_wr_dat, output [0:127] mem_wr_dat,


output wb_i_stb, // wishbone
output wb_i_cyc, output wb_stb,
output [31:0] wb_i_adr, output wb_cyc,
input wb_i_ack, output [31:0] wb_adr,
input [31:0] wb_i_datr, output wb_we,
output wb_d_stb, output [3:0] wb_sel,
output wb_d_cyc, output [31:0] wb_datw,
output [31:0] wb_d_adr, input wb_ack,
output wb_d_we, input [31:0] wb_datr
output [3:0] wb_d_sel, );
output [31:0] wb_d_datw,
input wb_d_ack,
input [31:0] wb_d_datr
);


// unsupported right now // unsupported right now


@ -131,53 +135,42 @@ a2l2wb n0(
assign an_ac_req_spare_ctrl_a1 = 0; assign an_ac_req_spare_ctrl_a1 = 0;
assign an_ac_reld_l1_dump = 0; assign an_ac_reld_l1_dump = 0;


wire [0:4] cmdseq_d; wire [0:4] cmdseq_d;
reg [0:4] cmdseq_q; reg [0:4] cmdseq_q;
wire [0:31+`REAL_IFAR_WIDTH] req_d; wire [0:30+`REAL_IFAR_WIDTH] req_d;
reg [0:31+`REAL_IFAR_WIDTH] req_q; reg [0:30+`REAL_IFAR_WIDTH] req_q;
wire [0:31+256] std_d; wire [0:31+256] std_d;
reg [0:31+256] std_q; reg [0:31+256] std_q;
reg std_q reg req_tkn_q;
reg req_tkn_q; reg std_tkn_q;
reg std_tkn_q; wire [0:255] rld_d;
wire [0:255] rld_d; reg [0:255] rld_q;
reg [0:255] rld_q; wire [0:1] qw_d;

reg [0:1] qw_q;
wire req_ld_val; wire [0:1] mem_qw_d;
wire req_st_val; reg [0:1] mem_qw_q;
wire [0:7] err_d;
reg [0:7] err_q;

wire new_req;
wire ld_req_val;
wire st_req_val;
wire req_ieq1;
wire req_le;
wire [64-`REAL_IFAR_WIDTH:63] req_adr; wire [64-`REAL_IFAR_WIDTH:63] req_adr;
wire [0:127] st_alg_data; wire [0:4] req_tag;
wire [0:127] st_mask; wire [0:2] req_len;
wire rld_coming; wire rld_coming;
wire rld_valid; wire rld_valid;
wire rld_done; wire rld_done;
wire [0:1] rld_qw; wire [0:1] rld_qw;
wire idle; wire idle;

wire ld_ready;
//reg [0:127] mem[MEM_QW]; wire st_ready;


// todo generate if (MEM_MODE == 1)
/* reg [0:127] mem[MEM_QW];

endgenerate

input ac_an_req_pwr_token,
input ac_an_req,
input [64-`REAL_IFAR_WIDTH:63] ac_an_req_ra,
input [0:5] ac_an_req_ttype,
input [0:2] ac_an_req_thread,
input [0:4] ac_an_req_ld_core_tag,
input [0:2] ac_an_req_ld_xfr_len,
input ac_an_req_wimg_w,
input ac_an_req_wimg_i,
input ac_an_req_wimg_m,
input ac_an_req_wimg_g,
input ac_an_req_endian,
input [0:3] ac_an_req_user_defined,
input [0:3] ac_an_req_spare_ctrl_a0,
input ac_an_st_data_pwr_token,
input [0:31] ac_an_st_byte_enbl,
input [0:255] ac_an_st_data
*/


// FF // FF
always @(posedge clk) begin always @(posedge clk) begin
@ -189,6 +182,9 @@ a2l2wb n0(
std_q = 0; std_q = 0;
req_tkn_q = 0; req_tkn_q = 0;
std_tkn_q = 0; std_tkn_q = 0;
qw_q = 0;
mem_qw_q = 0;
err_q = 0;


end else begin end else begin


@ -197,105 +193,144 @@ a2l2wb n0(
std_q = std_d; std_q = std_d;
req_tkn_q = ac_an_req_pwr_token; req_tkn_q = ac_an_req_pwr_token;
std_tkn_q = ac_an_st_data_pwr_token; std_tkn_q = ac_an_st_data_pwr_token;
qw_q = qw_d;
mem_qw_q = mem_qw_d;
err_q = err_d;


end end
end end


// Mem // adr needs to be created for cacheable!


/* // ext/int mem
always @(posedge clk) begin // mem_adr --- (qw-aligned byte address)
// mem_dat ---

// external memory
generate if (MEM_MODE == 0)
assign mem_adr = req_st_val ? {req_adr[64-`REAL_IFAR_WIDTH:59], 4'b0000} :
req_ieq1 ? req_adr :
{req_adr[64-`REAL_IFAR_WIDTH:57], mem_qw_q, 4'b0000};
endgenerate


if (do_store) begin // internal memory
mem[req_adr] = st_rmw_data; generate if (MEM_MODE == 1) begin
always @(posedge clk) begin
if (mem_wr_val) begin
mem[req_adr] = mem_wr_data;
end end
end end
assign mem_dat = mem[mem_adr]; assign mem_dat = mem[req_adr];
end
endgenerate


*/
assign mem_adr = req_adr >> 4;


// clkgate // clkgate
assign req_d = req_tkn_q ? {ac_an_req, // oflow if req_q[0]==1!
ac_an_req_thread, // 0:2 assign new_req = req_tkn_q & ac_an_req;
ac_an_req_ttype, // 0:5 assign req_d = new_req ?
ac_an_req_ld_core_tag, // 0:2 {1'b1, // 0
ac_an_req_ra, // ac_an_req_thread, // 1:3
ac_an_req_ld_xfr_len, // 0:2 ac_an_req_ttype, // 4:9
ac_an_req_wimg_w, ac_an_req_ld_core_tag, // 10:14
ac_an_req_wimg_i, ac_an_req_ra, // 15:56
ac_an_req_wimg_m, ac_an_req_ld_xfr_len, // 57:59
ac_an_req_wimg_g, ac_an_req_wimg_w, // 60
ac_an_req_wimg_endian, ac_an_req_wimg_i, // 61
ac_an_req_user_defined, // 0:3 ac_an_req_wimg_m, // 62
ac_an_req_spare_ctrl_a0 // 0:3 ac_an_req_wimg_g, // 63
} : 0; ac_an_req_endian, // 64
ac_an_req_user_defined, // 65:68
ac_an_req_spare_ctrl_a0 // 69:72
} :
(rld_done | do_store) ? 0 : req_q;

assign std_d = std_tkn_q ? {ac_an_st_byte_enbl, // 0:31 assign std_d = std_tkn_q ? {ac_an_st_byte_enbl, // 0:31
ac_an_st_data // 0:255 ac_an_st_data // 32:287
} : 0; } : do_store ? 0 : std_q;


// request // request
assign req_ld_val = req_q[0] & ( assign req_ld_val = req_q[0] & (
(req_q[4:9] == 'b000000) | // if (req_q[4:9] == 6'b000000) | // if
(req_q[4:9] == 'b001000) | // ld (req_q[4:9] == 6'b001000) | // ld
(req_q[4:9] == 'b100010) | // ditc (req_q[4:9] == 6'b100010) | // ditc
(req_q[4:9] == 'b001001) | // larx (req_q[4:9] == 6'b001001) | // larx
(req_q[4:9] == 'b001011); // larx hint (req_q[4:9] == 6'b001011) // larx hint
); );
assign req_ieq1 = req_q[61];
assign req_le = req_q[64];


assign req_st_val = req_q[0] & ( assign req_st_val = req_q[0] & (
(req_q[4:9] == 'b100000) | // st (req_q[4:9] == 6'b100000) | // st
(req_q[4:9] == 'b101001) // stcx (req_q[4:9] == 6'b101001) // stcx
); );


assign req_tag = req_q[10:12]; assign req_tag = req_q[10:14];
assign req_adr = req_q[14+64-`REAL_IFAR_WIDTH:14+63]; assign req_adr = req_q[15:15+`REAL_IFAR_WIDTH-1];
assign req_len = req_q[57:59];

// random delay, or future functional stuff
assign ld_ready = 1;
assign st_ready = 1;


// b2b
// coming --- --- // coming --- ---
// valid --- --- --- --- (and qw, crit) // valid --- --- --- --- (and qualifiers)
// data --- --- --- --- // data --- --- --- --- (only 1 beat for ieq1)


// vtable -V -b 0 a2l2wb.v
//tbl cmdseq //tbl cmdseq
//n cmdseq_q cmdseq_d //n cmdseq_q cmdseq_d
//n | | rld_coming //n | | rld_coming
//n | ld_req_val | |rld_valid //n | req_ld_val | |rld_valid
//n | |st_req_val | ||do_store //n | |req_st_val | ||do_store
//n | ||ld_ready | |||rld_done //n | ||ld_ready | |||rld_done
//n | |||st_ready | |||| //n | |||st_ready | ||||inc_qw
//n | ||||ld_ieq1 | |||| idle //n | ||||req_ieq1 | ||||| idle
//n | ||||| | |||| | //n | ||||| | ||||| |
//n | ||||| | |||| | //n | ||||| | ||||| |
//b 01234 ||||| 01234 |||| | //b 01234 ||||| 01234 ||||| |
//t iiiii iiiii ooooo oooo o //t iiiii iiiii ooooo ooooo o
//*---------------------------------------------------------------------- //*----------------------------------------------------------------------
//* Idle **************************************************************** //* Idle ****************************************************************
//s 11111 ----- ----- 0000 1 //s 11111 ----- ----- 00000 1
//s 11111 00--- 11111 0000 - * ...zzz... //s 11111 00--- 11111 00000 - * ...zzz...
//s 11111 1---- 00001 0000 - //s 11111 1---- 00001 00000 -
//s 11111 -1--- 10000 0000 - //s 11111 -1--- 10000 00000 -
//* Load **************************************************************** //* Load ****************************************************************
//* 00001 --0-- 00001 0000 0 //s 00001 --0-- 00001 00000 0
//* 00001 --1-- 00010 1000 0 //s 00001 --1-- 00010 10000 0
//* Reload V0 *********************************************************** * val 0 //* Reload V0 *********************************************************** * val 0
//* 00010 ----1 00011 0100 0 //s 00010 ----- 00011 01001 0
//* 00011 ----0 00100 0100 0 //* Reload Nop *********************************************************** * val 1 (not ieq1)
//* Reload D0 (I=1) ****************************************************** * dat 0 //s 00011 ----1 00100 00000 0
//* 00011 ----- 11111 0001 0 //s 00011 ----0 01000 11001 0
//* Reload D0 ************************************************************ * val 1, dat 0 //* Reload D0 (I=1) ****************************************************** * dat 0 (ieq1)
//* 00100 ----- 00101 1100 0 //s 00100 ----- 11111 00010 0
//* Reload D1 ************************************************************ * val 2, dat 1 //* Reload D0 ************************************************************ * val 2, dat 0
//* 00101 ----- 00110 0100 0 //s 01000 ----- 01001 01001 0
//* Reload D2 ************************************************************ * val 3, dat 2 //* Reload D1 ************************************************************ * val 3, dat 1
//* 00110 ----- 00111 0100 0 //s 01001 ----- 01010 01001 0
//* Reload D2 ************************************************************ * dat 2
//s 01010 ----- 01011 00000 0
//* Reload D3 ************************************************************ * dat 3 //* Reload D3 ************************************************************ * dat 3
//* 00111 ----- 11111 0001 0 //s 01011 ----- 11111 00010 0
//* Store *************************************************************** //* Store ***************************************************************
//* 10000 ---0- 10000 0000 0 //s 10000 ---0- 10000 00000 0
//* 10000 ---1- 11111 0010 0 //s 10000 ---1- 11111 00100 0
//*---------------------------------------------------------------------- //*----------------------------------------------------------------------
//tbl cmdseq //tbl cmdseq


assign reld_qw = cmdseq_q[3:4]; // crit first uses qw pattern instead of +1
// valid (d-2)
assign qw_d = new_req ? 0 :
inc_qw ? qw_q + 1 :
qw_q;

assign rld_qw = req_ieq1 ? 2'b00 : qw_q;

// mem address (d-1)
assign mem_qw_d = rld_qw;


// response // response
assign an_ac_reld_ecc_err = 0; assign an_ac_reld_ecc_err = 0;
@ -306,32 +341,86 @@ a2l2wb n0(
assign an_ac_reld_data_coming = rld_coming; assign an_ac_reld_data_coming = rld_coming;
assign an_ac_reld_data_vld = rld_valid; assign an_ac_reld_data_vld = rld_valid;
assign an_ac_reld_core_tag = req_tag; assign an_ac_reld_core_tag = req_tag;
assign an_ac_reld_qw = reld_qw; assign an_ac_reld_qw = rld_qw;
assign an_ac_reld_crit_qw = req_ieq1 | (req_adr[58:59] == reld_qw); assign an_ac_reld_crit_qw = req_ieq1 | (req_adr[58:59] == rld_qw);
assign an_ac_reld_data = mem[{req_adr[64-`REAL_IFAR_WIDTH:59], reld_qw}]; assign an_ac_reld_data = mem_dat;
assign an_ac_req_ld_pop = rld_done; assign an_ac_req_ld_pop = rld_done;


// stores // stores
assign st_ready = 1; // random delay, or future functional stuff assign an_ac_req_st_pop = do_store;
assign an_ac_req_st_pop = st_ready;

assign st_mask = {
{8{std_q[0]}}, {8{std_q[1]}}, {8{std_q[2]}}, {8{std_q[3]}},
{8{std_q[4]}}, {8{std_q[5]}}, {8{std_q[6]}}, {8{std_q[7]}},
{8{std_q[8]}}, {8{std_q[9]}}, {8{std_q[10]}}, {8{std_q[11]}},
{8{std_q[12]}}, {8{std_q[13]}}, {8{std_q[14]}}, {8{std_q[15]}},
{8{std_q[16]}}, {8{std_q[17]}}, {8{std_q[18]}}, {8{std_q[19]}},
{8{std_q[20]}}, {8{std_q[21]}}, {8{std_q[22]}}, {8{std_q[23]}},
{8{std_q[24]}}, {8{std_q[25]}}, {8{std_q[26]}}, {8{std_q[27]}},
{8{std_q[28]}}, {8{std_q[29]}}, {8{std_q[30]}}, {8{std_q[31]}}
};


// BE, 16B max store // BE, 16B max store
assign st_alg_data = req_q[32:32+127]; // no shift needed?

assign mem_wr_val = do_store; assign mem_wr_val = do_store;
assign mem_wr_dat = (mem_dat & st_mask) | (st_alg_data & ~st_mask); assign mem_wr_be = std_q[0:15];
assign mem_wr_dat = std_q[32:32+127];

// misc
assign err_d = {(new_req & ~idle), 7'b0};
assign an_ac_checkstop = err_q != 0;




//vtable cmdseq //vtable cmdseq
//vtable cmdseq assign cmdseq_d[0] =
(cmdseq_q[0] & cmdseq_q[1] & cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4] & ~req_ld_val & ~req_st_val) +
(cmdseq_q[0] & cmdseq_q[1] & cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4] & req_st_val) +
(~cmdseq_q[0] & ~cmdseq_q[1] & cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4]) +
(cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4] & ~st_ready) +
(cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4] & st_ready);
assign cmdseq_d[1] =
(cmdseq_q[0] & cmdseq_q[1] & cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4] & ~req_ld_val & ~req_st_val) +
(~cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4] & ~req_ieq1) +
(~cmdseq_q[0] & ~cmdseq_q[1] & cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4]) +
(cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4] & st_ready);
assign cmdseq_d[2] =
(cmdseq_q[0] & cmdseq_q[1] & cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4] & ~req_ld_val & ~req_st_val) +
(~cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4] & req_ieq1) +
(~cmdseq_q[0] & ~cmdseq_q[1] & cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4]) +
(cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4] & st_ready);
assign cmdseq_d[3] =
(cmdseq_q[0] & cmdseq_q[1] & cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4] & ~req_ld_val & ~req_st_val) +
(~cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & cmdseq_q[4] & ld_ready) +
(~cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & ~cmdseq_q[1] & cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4]) +
(cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4] & st_ready);
assign cmdseq_d[4] =
(cmdseq_q[0] & cmdseq_q[1] & cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4] & ~req_ld_val & ~req_st_val) +
(cmdseq_q[0] & cmdseq_q[1] & cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4] & req_ld_val) +
(~cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & cmdseq_q[4] & ~ld_ready) +
(~cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & ~cmdseq_q[1] & cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4]) +
(cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4] & st_ready);
assign rld_coming =
(~cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & cmdseq_q[4] & ld_ready) +
(~cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4] & ~req_ieq1);
assign rld_valid =
(~cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4] & ~req_ieq1) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & cmdseq_q[4]);
assign do_store =
(cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4] & st_ready);
assign rld_done =
(~cmdseq_q[0] & ~cmdseq_q[1] & cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4]);
assign inc_qw =
(~cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & ~cmdseq_q[1] & ~cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4] & ~req_ieq1) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & ~cmdseq_q[4]) +
(~cmdseq_q[0] & cmdseq_q[1] & ~cmdseq_q[2] & ~cmdseq_q[3] & cmdseq_q[4]);
assign idle =
(cmdseq_q[0] & cmdseq_q[1] & cmdseq_q[2] & cmdseq_q[3] & cmdseq_q[4]);
//vtable cmdseq

endmodule

@ -106,22 +106,57 @@ module a2owb (
output ac_an_coretrace_first_valid, output ac_an_coretrace_first_valid,
output ac_an_coretrace_valid, output ac_an_coretrace_valid,
output [0:1] ac_an_coretrace_type, output [0:1] ac_an_coretrace_type,

input an_ac_flh2l2_gate,
output wb_i_stb, input an_ac_reset_1_complete,
output wb_i_cyc, input an_ac_reset_2_complete,
output [31:0] wb_i_adr, input an_ac_reset_3_complete,
input wb_i_ack, input an_ac_reset_wd_complete,
input [31:0] wb_i_datr, output an_ac_checkstop,
output wb_d_stb, input [0:`THREADS-1] an_ac_external_mchk,
output wb_d_cyc, output ac_an_power_managed,
output [31:0] wb_d_adr, output ac_an_rvwinkle_mode,
output wb_d_we,
output [3:0] wb_d_sel, // direct-attach mem
output [31:0] wb_d_datw, output [0:31] mem_adr,
input wb_d_ack, input [0:127] mem_dat,
input [31:0] wb_d_datr output mem_wr_val,
output [0:15] mem_wr_be,
output [0:127] mem_wr_dat,

// wishbone
output wb_stb,
output wb_cyc,
output [31:0] wb_adr,
output wb_we,
output [3:0] wb_sel,
output [31:0] wb_datw,
input wb_ack,
input [31:0] wb_datr
); );


wire [0:`THREADS-1] an_ac_stcx_complete;
wire [0:`THREADS-1] an_ac_stcx_pass;
wire [0:1] an_ac_icbi_ack_thread;
wire [64-`REAL_IFAR_WIDTH:63] ac_an_req_ra;
wire [0:4] an_ac_back_inv_target;
wire [0:7] an_ac_back_inv_lpar_id;
wire [0:7] ac_an_lpar_id;
wire [0:4] an_ac_reld_core_tag;
wire [0:127] an_ac_reld_data;
wire [0:1] an_ac_reld_qw;
wire [64-`REAL_IFAR_WIDTH:63] an_ac_back_inv_addr;
wire [0:5] ac_an_req_ttype;
wire [0:2] ac_an_req_thread;
wire [0:3] ac_an_req_user_defined;
wire [0:3] ac_an_req_spare_ctrl_a0;
wire [0:4] ac_an_req_ld_core_tag;
wire [0:2] ac_an_req_ld_xfr_len;
wire [0:31] ac_an_st_byte_enbl;
wire [0:255] ac_an_st_data;
wire [0:3] an_ac_req_spare_ctrl_a1;
wire [0:`THREADS-1] an_ac_sync_ack;
wire [0:`THREADS-1] an_ac_reservation_vld;

c c0( c c0(
.nclk(nclk), .nclk(nclk),
.scan_in(scan_in), .scan_in(scan_in),
@ -188,7 +223,6 @@ c c0(
.an_ac_external_mchk(an_ac_external_mchk), .an_ac_external_mchk(an_ac_external_mchk),


.ac_an_event_bus0(ac_an_event_bus0), .ac_an_event_bus0(ac_an_event_bus0),
.ac_an_event_bus1(ac_an_event_bus1),


.an_ac_reset_1_complete(an_ac_reset_1_complete), .an_ac_reset_1_complete(an_ac_reset_1_complete),
.an_ac_reset_2_complete(an_ac_reset_2_complete), .an_ac_reset_2_complete(an_ac_reset_2_complete),
@ -260,7 +294,7 @@ a2l2wb n0(
.ac_an_req_thread(ac_an_req_thread), .ac_an_req_thread(ac_an_req_thread),
.ac_an_req_ld_core_tag(ac_an_req_ld_core_tag), .ac_an_req_ld_core_tag(ac_an_req_ld_core_tag),
.ac_an_req_ld_xfr_len(ac_an_req_ld_xfr_len), .ac_an_req_ld_xfr_len(ac_an_req_ld_xfr_len),
.ac_an_st_data_pwr_token(ac_an_st_data_pwr_token) .ac_an_st_data_pwr_token(ac_an_st_data_pwr_token),
.ac_an_st_byte_enbl(ac_an_st_byte_enbl), .ac_an_st_byte_enbl(ac_an_st_byte_enbl),
.ac_an_st_data(ac_an_st_data), .ac_an_st_data(ac_an_st_data),
.ac_an_req_wimg_w(ac_an_req_wimg_w), .ac_an_req_wimg_w(ac_an_req_wimg_w),
@ -310,65 +344,73 @@ a2l2wb n0(
.an_ac_req_st_pop(an_ac_req_st_pop), .an_ac_req_st_pop(an_ac_req_st_pop),
.an_ac_req_st_gather(an_ac_req_st_gather), .an_ac_req_st_gather(an_ac_req_st_gather),
.an_ac_sync_ack(an_ac_sync_ack), .an_ac_sync_ack(an_ac_sync_ack),
.an_ac_pm_fetch_halt(an_ac_pm_fetch_halt), //.an_ac_pm_fetch_halt(an_ac_pm_fetch_halt),


// misc // misc
.an_ac_flh2l2_gate(an_ac_flh2l2_gate), //.an_ac_flh2l2_gate(an_ac_flh2l2_gate),
.an_ac_reset_1_complete(an_ac_reset_1_complete), //.an_ac_reset_1_complete(an_ac_reset_1_complete),
.an_ac_reset_2_complete(an_ac_reset_2_complete), //.an_ac_reset_2_complete(an_ac_reset_2_complete),
.an_ac_reset_3_complete(an_ac_reset_3_complete), //.an_ac_reset_3_complete(an_ac_reset_3_complete),
.an_ac_reset_wd_complete(an_ac_reset_wd_complete), //.an_ac_reset_wd_complete(an_ac_reset_wd_complete),
.an_ac_sleep_en(an_ac_sleep_en), //.an_ac_sleep_en(an_ac_sleep_en),
.an_ac_ext_interrupt(an_ac_ext_interrupt), //.an_ac_ext_interrupt(an_ac_ext_interrupt),
.an_ac_crit_interrupt(an_ac_crit_interrupt), //.an_ac_crit_interrupt(an_ac_crit_interrupt),
.an_ac_perf_interrupt(an_ac_perf_interrupt), //.an_ac_perf_interrupt(an_ac_perf_interrupt),
.an_ac_hang_pulse(an_ac_hang_pulse), //.an_ac_hang_pulse(an_ac_hang_pulse),
.an_ac_tb_update_enable(an_ac_tb_update_enable), //.an_ac_tb_update_enable(an_ac_tb_update_enable),
.an_ac_tb_update_pulse(an_ac_tb_update_pulse), //.an_ac_tb_update_pulse(an_ac_tb_update_pulse),
.an_ac_chipid_dc(an_ac_chipid_dc), //.an_ac_chipid_dc(an_ac_chipid_dc),
.an_ac_coreid(an_ac_coreid), //.an_ac_coreid(an_ac_coreid),
.an_ac_debug_stop(an_ac_debug_stop), //.an_ac_debug_stop(an_ac_debug_stop),
.ac_an_debug_trigger(ac_an_debug_trigger), //.ac_an_debug_trigger(ac_an_debug_trigger),
.an_ac_uncond_dbg_event(an_ac_uncond_dbg_event), //.an_ac_uncond_dbg_event(an_ac_uncond_dbg_event),


// scom // scom
.an_ac_scom_sat_id(an_ac_scom_sat_id), //.an_ac_scom_sat_id(an_ac_scom_sat_id),
.an_ac_scom_dch(an_ac_scom_dch), //.an_ac_scom_dch(an_ac_scom_dch),
.an_ac_scom_cch(an_ac_scom_cch), //.an_ac_scom_cch(an_ac_scom_cch),
.ac_an_scom_dch(ac_an_scom_dch), //.ac_an_scom_dch(ac_an_scom_dch),
.ac_an_scom_cch(ac_an_scom_cch), //.ac_an_scom_cch(ac_an_scom_cch),


// errors // errors
.ac_an_special_attn(ac_an_special_attn), //.ac_an_special_attn(ac_an_special_attn),
.ac_an_checkstop(ac_an_checkstop), //.ac_an_checkstop(ac_an_checkstop),
.ac_an_local_checkstop(ac_an_local_checkstop), //.ac_an_local_checkstop(ac_an_local_checkstop),
.ac_an_recov_err(ac_an_recov_err), //.ac_an_recov_err(ac_an_recov_err),
.ac_an_trace_error(ac_an_trace_error), //.ac_an_trace_error(ac_an_trace_error),
.ac_an_livelock_active(ac_an_livelock_active), //.ac_an_livelock_active(ac_an_livelock_active),
.an_ac_checkstop(an_ac_checkstop), .an_ac_checkstop(an_ac_checkstop),
.an_ac_external_mchk(an_ac_external_mchk), //.an_ac_external_mchk(an_ac_external_mchk),
.ac_an_machine_check(ac_an_machine_check), //.ac_an_machine_check(ac_an_machine_check),


// perfmon // perfmon
.ac_an_event_bus0(ac_an_event_bus0), //.ac_an_event_bus0(ac_an_event_bus0),
.ac_an_event_bus1(ac_an_event_bus1), //.ac_an_event_bus1(ac_an_event_bus1),


// power // power
.ac_an_pm_thread_running(ac_an_pm_thread_running), //.ac_an_pm_thread_running(ac_an_pm_thread_running),
.an_ac_pm_thread_stop(an_ac_pm_thread_stop), //.an_ac_pm_thread_stop(an_ac_pm_thread_stop),
.ac_an_power_managed(ac_an_power_managed), //.ac_an_power_managed(ac_an_power_managed),
.ac_an_rvwinkle_mode(ac_an_rvwinkle_mode), //.ac_an_rvwinkle_mode(ac_an_rvwinkle_mode)
); // direct-attach mem
.mem_adr(mem_adr),
.mem_dat(mem_dat),
.mem_wr_be(mem_wr_be),
.mem_wr_val(mem_wr_val),

.mem_wr_dat(mem_wr_dat),

// wishbone
.wb_stb(wb_stb),
.wb_cyc(wb_cyc),
.wb_adr(wb_adr),
.wb_we(wb_we),
.wb_ack(wb_ack),
.wb_sel(wb_sel),
.wb_datr(wb_datr),
.wb_datw(wb_datw)


initial begin );
$dumpfile ("a2owb.vcd");
// you can do it by levels and also by module so could prune down
$dumpvars;
// need to explicitly specify arrays for icarus
// guess not: $dumpvars cannot dump a vpiMemory
//$dumpvars(0, c0.iuq0.iuq_slice_top0.slice0.iuq_ibuf0.buffer_data_q);
#1;
end


wire clk_1x, clk_2x, clk_4x, rst; wire clk_1x, clk_2x, clk_4x, rst;



@ -0,0 +1,427 @@
#!/usr/bin/python3
#
# Parse table comments and create equations.

from optparse import OptionParser
import re
from shutil import copyfile

#--------------------------------------------------------------------------------------------------
# Initialize

TYPE_INPUT = 0
TYPE_OUTPUT = 1
TYPE_SKIP = 99

lines = []
tableMatches = []
tableNames = []
tableLines = []
tables = {}

failOnError = True
inFile = 'test.vhdl'
outFileExt = 'vtable'
overwrite = True
backupExt = 'orig'
backup = True
noisy = False
quiet = False
verilog = False

#--------------------------------------------------------------------------------------------------
# Handle command line

usage = 'vtable [options] inFile'

parser = OptionParser(usage)
parser.add_option('-f', '--outfile', dest='outFile', help='output file, default=[inFile]' + outFileExt)
parser.add_option('-o', '--overwrite', dest='overwrite', help='overwrite inFile, default=' + str(overwrite))
parser.add_option('-b', '--backup', dest='backup', help='backup original file, default=' + str(backup))
parser.add_option('-q', '--quiet', dest='quiet', action='store_true', help='quiet messages, default=' + str(quiet))
parser.add_option('-n', '--noisy', dest='noisy', action='store_true', help='noisy messages, default=' + str(noisy))
parser.add_option('-V', '--verilog', dest='verilog', action='store_true', help='source is verilog, default=' + str(verilog))

options, args = parser.parse_args()

if len(args) != 1:
parser.error(usage)
quit(-1)
else:
inFile = args[0]

if options.overwrite == '0':
overwrite = False
elif options.overwrite == '1':
overwrite == True
if options.outFile is not None:
parser.error('Can\'t specify outfile and overrite!')
quit(-1)
elif options.overwrite is not None:
parser.error('overwrite: 0|1')
quit(-1)

if options.quiet is not None:
quiet = True

if options.noisy is not None:
noisy = True

if options.verilog is not None:
verilog = True

if options.backup == '0':
backup = False
elif options.backup == '1':
backup == True
elif options.backup is not None:
parser.error('backup: 0|1')
quit(-1)

if options.outFile is not None:
outFile = options.outFile
elif overwrite:
outFile = inFile
else:
outFile = inFile + '.' + outFileExt

backupFile = inFile + '.' + backupExt

#--------------------------------------------------------------------------------------------------
# Objects

class Signal:

def __init__(self, name, type):
self.name = name;
self.type = type;

class Table:

def __init__(self, name):
self.name = name
self.source = []
self.signals = {}
self.signalsByCol = {}
self.typesByCol = {}
self.specs = [] # list of specsByCol
self.equations = []
self.added = False

def validate(self):
# check that all signals have a good type
for col in self.signalsByCol:
if col not in self.typesByCol:
error('Table ' + self.name + ': no signal type for ' + self.signalsByCol[col])
elif self.typesByCol[col] == None:
error('Table ' + self.name + ': bad signal type (' + str(self.typesByCol[col]) + ') for ' + str(self.signalsByCol[col]))

def makeRTL(self, form=None):
outputsByCol = {}


#for col,type in self.typesByCol.items():
for col in sorted(self.typesByCol):
type = self.typesByCol[col]
if type == TYPE_OUTPUT:
if col in self.signalsByCol:
outputsByCol[col] = self.signalsByCol[col]
else:
print(self.signalsByCol)
print(self.typesByCol)
error('Table ' + self.name + ': output is specified in col ' + str(col) + ' but no signal exists')

#for sigCol,sig in outputsByCol.items():
for sigCol in sorted(outputsByCol):
sig = outputsByCol[sigCol]
if not verilog:
line = sig + ' <= '
else:
line = 'assign ' + sig + ' = '
nonzero = False
for specsByCol in self.specs:
terms = []
if sigCol not in specsByCol:
#error('* Output ' + sig + ' has no specified value for column ' + str(col))
1 # no error, can be dontcare
elif specsByCol[sigCol] == '1':
for col,val in specsByCol.items():
if col not in self.typesByCol:
if noisy:
error('Table ' + self.name +': unexpected value in spec column ' + str(col) + ' (' + str(val) + ') - no associated signal', False) #wtf UNTIL CAN HANDLE COMMENTS AT END!!!!!!!!!!!!!!!!!!!
elif self.typesByCol[col] == TYPE_INPUT:
if val == '0':
terms.append(opNot + self.signalsByCol[col])
if nonzero and len(terms) == 1:
line = line + ') ' + opOr + '\n (';
elif len(terms) == 1:
line = line + '\n ('
nonzero = True
elif val == '1':
terms.append(self.signalsByCol[col])
if nonzero and len(terms) == 1:
line = line + ') ' + opOr + '\n (';
elif len(terms) == 1:
line = line + '\n ('
nonzero = True
else:
error('Table ' + self.name +': unexpected value in spec column ' + str(col) + ' (' + str(val) + ')')
if len(terms) > 0:
line = line + (' ' + opAnd + ' ').join(terms)
if not nonzero:
line = line + zero + ";";
else:
line = line + ');'
self.equations.append(line)

return self.equations

def printv(self):
self.makeRTL()
print('\n'.join(self.equations))

def printinfo(self):
print('Table: ' + self.name)
print
for l in self.source:
print(l)
print
print('Signals by column:')
for col in sorted(self.signalsByCol):
print('{0:>3}. {1:} ({2:}) '.format(col, self.signalsByCol[col], 'in' if self.typesByCol[col] == TYPE_INPUT else 'out'))


#--------------------------------------------------------------------------------------------------
# Functions

def error(msg, quitOverride=None):
print('*** ' + msg)
if quitOverride == False:
1
elif (quitOverride == None) or failOnError:
quit(-10)
elif quitOverride:
quit(-10)

#--------------------------------------------------------------------------------------------------
# Do something

if not verilog:
openBracket = '('
closeBracket = ')'
opAnd = 'and'
opOr = 'or'
opNot = 'not '
zero = "'0'"
tablePattern = re.compile(r'^\s*?--tbl(?:\s+([^\s]+).*$|\s*$)')
tableGenPattern = re.compile(r'^\s*?--vtable(?:\s+([^\s]+).*$)')
commentPattern = re.compile(r'^\s*?(--.*$|\s*$)')
tableLinePattern = re.compile(r'^.*?--(.*)')
namePattern = re.compile(r'([a-zA-z\d_\(\)\.\[\]]+)')
else:
openBracket = '['
closeBracket = ']'
opAnd = '&'
opOr = '+'
opNot = '~'
zero = "'b0"
tablePattern = re.compile(r'^\s*?\/\/tbl(?:\s+([^\s]+).*$|\s*$)')
tableGenPattern = re.compile(r'^\s*?\/\/vtable(?:\s+([^\s]+).*$)')
commentPattern = re.compile(r'^\s*?(\/\/.*$|\s*$)')
tableLinePattern = re.compile(r'^.*?\/\/(.*)')
namePattern = re.compile(r'([a-zA-z\d_\(\)\.\[\]]+)')

# find the lines with table spec
try:
inf = open(inFile)
for i, line in enumerate(inf):
lines.append(line.strip('\n'))
for match in re.finditer(tablePattern, line):
tableMatches.append(i)
inf.close()
except Exception as e:
error('Error opening input file ' + inFile + '\n' + str(e), True)

# validate matches; should be paired, nothing but comments and empties; table may be named
# between them

for i in range(0, len(tableMatches), 2):

if i + 1 > len(tableMatches) - 1:
error('Mismatched table tags.\nFound so far: ' + ', '.join(tableNames), True)

tLines = lines[tableMatches[i]:tableMatches[i+1]+1]
tableLines.append(tLines)
tName = re.match(tablePattern, lines[tableMatches[i]]).groups()[0]
if tName is None:
tName = 'noname_' + str(tableMatches[i] + 1)
tableNames.append(tName)

for line in tLines:
if not re.match(commentPattern, line):
error('Found noncomment, nonempty line in table ' + tName + ':\n' + line, True)

print('Found tables: ' + ', '.join(tableNames))

# build table objects

for table, tName in zip(tableLines, tableNames):
print('Parsing ' + tName + '...')
namesByCol = {}
colsByName = {}
bitsByCol = {}
typesByCol = {}
specs = []

# parse the table - do by Table.parse()
tLines = table[1:-1] # exclude --tbl
for line in tLines:
if line.strip() == '':
continue
try:
spec = re.search(tableLinePattern, line).groups()[0]
except Exception as e:
error('Problem parsing table line:\n' + line, True)
if len(spec) > 0:
if spec[0] == 'n':
for match in re.finditer(namePattern, spec[1:]):
# col 0 is first col after n
namesByCol[match.start()] = match.groups()[0]
colsByName[match.groups()[0]] = match.start()
elif spec[0] == 'b':
for i, c in enumerate(spec[1:]):
if c == ' ' or c == '|':
continue
try:
bit = int(c)
except:
error('Unexpected char in bit line at position ' + str(i) + ' (' + c + ')\n' + line)
bit = None
if i in bitsByCol and bitsByCol[i] is not None:
bitsByCol[i] = bitsByCol[i]*10+bit
else:
bitsByCol[i] = bit
elif spec[0] == 't':
for i, c in enumerate(spec[1:]):
if c.lower() == 'i':
typesByCol[i] = TYPE_INPUT
elif c.lower() == 'o':
typesByCol[i] = TYPE_OUTPUT
elif c.lower() == '*':
typesByCol[i] = TYPE_SKIP
elif c != ' ':
error('Unexpected char in type line at position ' + str(i) + ' (' + c + ')\n' + line)
typesByCol[i] = None
else:
typesByCol[i] = None
elif spec[0] == 's':
specsByCol = {}
for i, c in enumerate(spec[1:]):
if c == '0' or c == '1':
specsByCol[i] = c
specs.append(specsByCol)
else:
#print('other:')
#print(line)
1

# create table object

# add strand to name where defined; don't combine for now into vector
# consecutive strands belong to the last defined name
lastName = None
lastCol = 0
signalsByCol = {}

for col,name in namesByCol.items(): # load with unstranded names
signalsByCol[col] = name

# sort by col so consecutive columns can be easily tracked
#for col,val in bitsByCol.items(): # update with stranded names
for col in sorted(bitsByCol):
val = bitsByCol[col]

if col > lastCol + 1:
lastName = None
if val is None:
lastName = None
if col in namesByCol:
if val is None:
signalsByCol[col] = namesByCol[col]
else:
lastName = namesByCol[col]
signalsByCol[col] = lastName + openBracket + str(val) + closeBracket
elif lastName is not None:
signalsByCol[col] = lastName + openBracket + str(val) + closeBracket
else:
error('Can\'t associate bit number ' + str(val) + ' in column ' + str(col) + ' with a signal name.')
lastCol = col

t = Table(tName)
t.source = table
t.signalsByCol = signalsByCol
t.typesByCol = typesByCol
t.specs = specs

tables[tName] = t

for name in tables:
t = tables[name]
t.validate()
t.makeRTL()

print()
print('Results:')

# find the lines with generate spec and replace them with new version
outLines = []
inTable = False
for i, line in enumerate(lines):
if not inTable:
match = re.search(tableGenPattern, line)
if match is not None:
tName = match.groups(1)[0]
if tName not in tables:
if tName == 1:
tName = '<blank>'
error('Found vtable start for \'' + tName + '\' but didn\'t generate that table: line ' + str(i+1) + '\n' + line, True)
else:
outLines.append(line)
outLines += tables[tName].equations
tables[tName].added = True
inTable = True
else:
outLines.append(line)
else:
match = re.search(tableGenPattern, line)
if match is not None:
if match.groups(1)[0] != tName:
error('Found vtable end for \'' + match.groups(1)[0] + '\' but started table \'' + tName + '\': line ' + str(i+1) + '\n' + line, True)
outLines.append(line)
inTable = False
else:
1#print('stripped: ' + line)

if backup:
try:
copyfile(inFile, backupFile)
except Exception as e:
error('Error creating backup file!\n' + str(e), True)

try:
of = open(outFile, 'w')
for line in outLines:
of.write("%s\n" % line)
except Exception as e:
error('Error writing output file ' + outFile + '!\n' + str(e), True)

print('Generated ' + str(len(tables)) + ' tables: ' + ', '.join(tableNames))
notAdded = {}
for table in tables:
if not tables[table].added:
notAdded[table] = True
print('Output file: ' + outFile)
if backup:
print('Backup file: ' + backupFile)
if len(notAdded) != 0:
error('Tables generated but not added to file! ' + ', '.join(notAdded))
Loading…
Cancel
Save