start a2l2wb
							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
												
											
										
									
								@ -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…
					
					
				
		Reference in New Issue