diff --git a/dev/sim/coco/tb-node.py b/dev/sim/coco/tb-node.py new file mode 100644 index 0000000..1fb0310 --- /dev/null +++ b/dev/sim/coco/tb-node.py @@ -0,0 +1,331 @@ +# a2o test tb +# uses a2owb with 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_checkstop.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 core, etc. """ + + #wtf make A2 module to do core-specific stuff + # A2L2 load/store credits + creditsLd = dut.c0.lq0.lsq.arb.load_cred_cnt_d # 8 max + creditsLdMax = dut.c0.lq0.lsq.arb.ld_cred_max # hdw check + creditsSt = dut.c0.lq0.lsq.arb.store_cred_cnt_d # 32 max + creditsStMax = dut.c0.lq0.lsq.arb.st_cred_max # hdw check + creditsLdStSingle = dut.c0.lq0.lsq.arb.spr_xucr0_cred_d # 1 total credit + #wtf this affects A2L2 - default=1 + # dut.c0.lq0.lsq.arb.spr_lsucr0_b2b_q # 0=crit first, every other 1=crit first, b2b **the a2l2 spec does not say crit must be first** + lsucr0_d = dut.c0.lq0.ctl.spr.lq_spr_cspr.lsucr0_d + lsucr0_q = dut.c0.lq0.ctl.spr.lq_spr_cspr.lsucr0_q + cpcr2_d = dut.c0.iuq0.iuq_ifetch0.iuq_spr0.cpcr2_d + cpcr2_q = dut.c0.iuq0.iuq_ifetch0.iuq_spr0.cpcr2_l2 + cpcr2_act = dut.c0.iuq0.iuq_ifetch0.iuq_spr0.cpcr2_wren + cpcr4_d = dut.c0.iuq0.iuq_ifetch0.iuq_spr0.cpcr4_d + cpcr4_q = dut.c0.iuq0.iuq_ifetch0.iuq_spr0.cpcr4_l2 + cpcr4_act = dut.c0.iuq0.iuq_ifetch0.iuq_spr0.cpcr4_wren + + await RisingEdge(dut.clk_1x) + + if sim.config.core.creditsLd is not None: + creditsLd.value = Force(sim.config.core.creditsLd) + creditsLdMax.value = Force(sim.config.core.creditsLd) + sim.msg(f'A2L2: load credits changed from {creditsLd.value.integer} to {sim.config.core.creditsLd}.') + await RisingEdge(dut.clk_1x) + creditsLd.value = Release() + + if sim.config.core.creditsSt is not None: + creditsSt.value = Force(sim.config.core.creditsSt) + creditsStMax.value = Force(sim.config.core.creditsSt) + sim.msg(f'A2L2: store credits changed from {creditsSt.value.integer} to {sim.config.core.creditsSt}.') + await RisingEdge(dut.clk_1x) + creditsSt.value = Release() + + if sim.config.core.creditsLdStSingle is not None: + v = 1 if sim.config.core.creditsLdStSingle else 0 + creditsLdStSingle.value = Force(v) + sim.msg(f'A2L2: only one load OR store allowed when credits=1/1.') + await RisingEdge(dut.clk_1x) + creditsLdStSingle.value = Release() + + #wtf make a function - needs mask,thread + if sim.config.core.lsDataForward is not None: + v = 1 if sim.config.core.lsDataForward else 0 + sim.msg(f'LSUCR0 = {hex(lsucr0_q.value), 8}') + sim.msg(f'Setting LSUCR0[DFWD] = {v}.') + v = v << 2 + v = (lsucr0_q.value.integer & ~0x4) | v + lsucr0_d.value = Force(v) + await RisingEdge(dut.clk_1x) + lsucr0_d.value = Release() + sim.msg(f'LSUCR0 = {hex(lsucr0_q.value), 8}') + + if sim.config.core.cpcr4_sq_cnt is not None: + v = sim.config.core.cpcr4_sq_cnt + sim.msg(f'CPCR4 = {hex(cpcr4_q[0], 8)}') + sim.msg(f'Setting CPCR4[SQ_CNT] = {v}.') + v = v << 0 + v = (cpcr4_q[0].value.integer & ~0x1F) | v + await RisingEdge(dut.clk_1x) # need cuz of act? + cpcr4_d[0].value = Force(v) + cpcr4_act.value = Force(1) + await RisingEdge(dut.clk_1x) + await RisingEdge(dut.clk_1x) # need cuz of act? + cpcr4_d[0].value = Release() + cpcr4_act.value = Release() + sim.msg(f'CPCR4 = {hex(cpcr4_q[0], 8)}') + + 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.' + +# ------------------------------------------------------------------------------------------------ +# 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(dut): + """A Vulgar Display of OpenPower""" + + sim = Sim(dut) + sim.mem = Memory(sim) + sim.maxCycles = 9000 + # original fpga design needed 4 cred, no fwd (set in logic currently) + #sim.config.core.creditsSt = 32 + #sim.config.core.lsDataForward = 0 # disable=1 + #sim.config.core.cpcr4_sq_cnt = 0 # default=6 + + ''' + # 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) + sim.a2o.traceFacUpdates = True + await cocotb.start(A2O.driver(dut, sim)) + await cocotb.start(A2O.checker(dut, sim)) + await cocotb.start(A2O.monitor(dut, sim)) + + await cocotb.start(A2L2.driver(dut, sim)) + await cocotb.start(A2L2.checker(dut, sim)) + await cocotb.start(A2L2.monitor(dut, sim)) + + 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 + await config(dut, sim) + + # monitor stuff + #await cocotb.start(coreMonitor(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 diff --git a/dev/sim/verilator/tb-node.cpp b/dev/sim/verilator/tb-node.cpp new file mode 100644 index 0000000..d65b7c7 --- /dev/null +++ b/dev/sim/verilator/tb-node.cpp @@ -0,0 +1,173 @@ +// simple verilator top +// uses a2owb with sim mem interface + +#define TRACING + +#include +#include +#include + +#include "verilated.h" +#include "Vc.h" + +#ifdef TRACING +#include "verilated_vcd_c.h" +VerilatedVcdC *t; +#else +unsigned int t = 0; +#endif + +/* +#include "uart/uartsim.h" +*/ + +Vc* m; + +vluint64_t main_time = 0; // in units of timeprecision used in verilog or --timescale-override +// what is it? it changed to 941621251 after calling loadmem() + +double sc_time_stamp() { // $time in verilog + return main_time; +} + +const int resetCycle = 10; +const int threadRunCycle = 200; +const int runCycles = 1000; +const int hbCycles = 500; +const int threads = 1; // needs a more realistic a2l2 data return to work in smt + +int mem[16384][4]; // 16K QW + +void loadmem(void) { + int adr; + mem[0x0000/4] = 0x48000400; + adr = 0x400/4; + + mem[adr++] = threads == 1 ? 0x38200001 : 0x38200003; + mem[adr++] = 0x7C366BA6; + mem[adr++] = 0x7C366BA6; + mem[adr++] = 0x7C3E6AA6; + mem[adr++] = 0x4C00012C; + mem[adr++] = 0x2C010000; + mem[adr++] = 0x38200660; + mem[adr++] = 0x41820008; + mem[adr++] = 0x38210100; + mem[adr++] = 0x7C2903A6; + mem[adr++] = 0x4E800420; + +} + +// nclk = (clk,reset,clk2x,clk4x,-,-) + +int main(int argc, char **argv) { + using namespace std; + + loadmem(); + + cout << setfill('0'); + + Verilated::commandArgs(argc, argv); + m = new Vc; + +#ifdef TRACING + Verilated::traceEverOn(true); + t = new VerilatedVcdC; + m->trace(t, 99); + t->open("wtf.vcd"); + cout << "Tracing enabled." << endl; +#endif + + bool resetDone = false; + unsigned int threadStop = 0x3; + + unsigned int tick = 0; + unsigned int cycle = 1; + unsigned int readPending = 0; + unsigned int readAddr = 0; + unsigned int readTag = 0; + unsigned int readTID = 0; + unsigned int countReads = 0; + + m->nclk = 0x3C; // run 2x,4x = 1x + cout << setw(8) << cycle << "Resetting..." << endl; + + m->an_ac_pm_thread_stop = threadStop; + cout << setw(8) << cycle << "Thread stop=" << threadStop << endl; + + // can skip 4x with new gpr array + // 1x=4/4 2x=2/2 4x=1/1 + // 1 1 1 7 + // 1 1 0 6 + // 1 0 1 5 + // 1 0 0 4 + // 0 1 1 3 + // 0 1 0 2 + // 0 0 1 1 + // 0 0 0 0 + // (insert reset) + //const int clocks[8] = {11, 0, 11, 0, 11, 0, 11, 0}; // 2x,4x == 1x + //const int clocks[8] = {11, 10, 9, 8, 3, 2, 1, 0}; // 1x, 2x, 4x + //const int ticks1x = 8; + const int clocks[4] = {10, 8, 2, 0}; // 1x, 2x + const int ticks1x = 4; + + while (!Verilated::gotFinish()) { + + if (!resetDone && (cycle > resetCycle)) { + m->nclk &= 0x2F; + cout << setw(8) << cycle << "Releasing reset." << endl; + resetDone = true; + } + + if (threadStop && (cycle > threadRunCycle)) { + threadStop = 0x0; + m->an_ac_pm_thread_stop = threadStop; + cout << setw(8) << cycle << "Thread stop=" << threadStop << endl; + } + + m->nclk = (m->nclk & 0x10) | (clocks[tick % 8] << 2); + tick++; + m->eval(); + + // bus is 1x clock + if ((tick % ticks1x) == 0) { + + /* + cout << setw(8) << cycle << " an_ac_rsp: data="<< hex << uppercase << setw(8) << m->an_ac_reld_data[3] + << hex << uppercase << setw(8) << m->an_ac_reld_data[2] + << hex << uppercase << setw(8) << m->an_ac_reld_data[1] + << hex << uppercase << setw(8) << m->an_ac_reld_data[0] + << dec << nouppercase << endl; + */ + + } + + // finish clock stuff + if ((tick % ticks1x) == 0) { + cycle++; + if ((cycle % hbCycles) == 0) { + cout << setw(8) << cycle << " ...tick..." << endl; + } + } + #ifdef TRACING + t->dump(tick); + t->flush(); + #endif + + // check for fails + + // hit limit + if (cycle > runCycles) { + break; + } + + } + +#ifdef TRACING + t->close(); +#endif + m->final(); + + exit(EXIT_SUCCESS); + +} \ No newline at end of file diff --git a/dev/sim/coco/tb.cpp b/dev/sim/verilator/tb.cpp old mode 100755 new mode 100644 similarity index 100% rename from dev/sim/coco/tb.cpp rename to dev/sim/verilator/tb.cpp diff --git a/dev/verilog/a2node/a2l2wb.v b/dev/verilog/a2node/a2l2wb.v new file mode 100644 index 0000000..e8a1610 --- /dev/null +++ b/dev/verilog/a2node/a2l2wb.v @@ -0,0 +1,337 @@ +// © IBM Corp. 2022 +// Licensed under the Apache License, Version 2.0 (the "License"), as modified by +// the terms below; you may not use the files in this repository except in +// compliance with the License as modified. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// +// Modified Terms: +// +// 1) For the purpose of the patent license granted to you in Section 3 of the +// License, the "Work" hereby includes implementations of the work of authorship +// in physical form. +// +// 2) Notwithstanding any terms to the contrary in the License, any licenses +// necessary for implementation of the Work that are available from OpenPOWER +// via the Power ISA End User License Agreement (EULA) are explicitly excluded +// hereunder, and may be obtained from OpenPOWER under the terms and conditions +// of the EULA. +// +// Unless required by applicable law or agreed to in writing, the reference design +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License +// for the specific language governing permissions and limitations under the License. +// +// Additional rights, including the ability to physically implement a softcore that +// is compliant with the required sections of the Power ISA Specification, are +// available at no cost under the terms of the OpenPOWER Power ISA EULA, which can be +// obtained (along with the Power ISA) here: https://openpowerfoundation.org. + +// A2L2 bridge +// 1. interface to a sim mem[] +// 2. interface to wb (could use mem for l2 also) + +a2l2wb n0( + parameter MEM_QW = 16384; +) +( + input clk, + input rst, + + 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, + + output an_ac_reld_data_vld, + output [0:4] an_ac_reld_core_tag, + output [0:127] an_ac_reld_data, + output [58:59] an_ac_reld_qw, + output an_ac_reld_ecc_err, + output an_ac_reld_ecc_err_ue, + output an_ac_reld_data_coming, + output an_ac_reld_ditc, + output an_ac_reld_crit_qw, + output an_ac_reld_l1_dump, + output [0:3] an_ac_req_spare_ctrl_a1, + output [0:`THREADS-1] an_ac_sync_ack, + + output an_ac_req_ld_pop, + output an_ac_req_st_pop, + output an_ac_req_st_gather, + + output [0:`THREADS-1] an_ac_stcx_complete, + output [0:`THREADS-1] an_ac_stcx_pass, + output [0:`THREADS-1] an_ac_reservation_vld, + + output an_ac_icbi_ack, + output [0:1] an_ac_icbi_ack_thread, + output an_ac_back_inv, + output [64-`REAL_IFAR_WIDTH:63] an_ac_back_inv_addr, + output [0:4] an_ac_back_inv_target, + output an_ac_back_inv_local, + output an_ac_back_inv_lbit, + output an_ac_back_inv_gs, + output an_ac_back_inv_ind, + output [0:7] an_ac_back_inv_lpar_id, + input ac_an_back_inv_reject, + input [0:7] ac_an_lpar_id, + + output [0:31] mem_adr, + input [0:127] mem_dat, + output mem_wr_val, + output [0:127] mem_wr_dat, + + output wb_i_stb, + output wb_i_cyc, + output [31:0] wb_i_adr, + input wb_i_ack, + input [31:0] wb_i_datr, + output wb_d_stb, + output wb_d_cyc, + output [31:0] wb_d_adr, + output wb_d_we, + 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 + + assign an_ac_sync_ack = 0; + assign an_ac_stcx_complete = 0; + assign an_ac_stcx_pass = 0; + assign an_ac_reservation_vld = 0; + + assign an_ac_icbi_ack = 0; + assign an_ac_icbi_ack_thread = 0; + assign an_ac_back_inv = 0; + assign an_ac_back_inv_addr = 0; + assign an_ac_back_inv_target = 0; + assign an_ac_back_inv_local = 0; + assign an_ac_back_inv_lbit = 0; + assign an_ac_back_inv_gs = 0; + assign an_ac_back_inv_ind = 0; + assign an_ac_back_inv_lpar_id = 0; + + assign an_ac_req_st_gather = 0; + assign an_ac_req_spare_ctrl_a1 = 0; + assign an_ac_reld_l1_dump = 0; + + wire [0:4] cmdseq_d; + reg [0:4] cmdseq_q; + wire [0:31+`REAL_IFAR_WIDTH] req_d; + reg [0:31+`REAL_IFAR_WIDTH] req_q; + wire [0:31+256] std_d; + reg [0:31+256] std_q; + reg std_q + reg req_tkn_q; + reg std_tkn_q; + wire [0:255] rld_d; + reg [0:255] rld_q; + + wire req_ld_val; + wire req_st_val; + wire [64-`REAL_IFAR_WIDTH:63] req_adr; + wire [0:127] st_alg_data; + wire [0:127] st_mask; + wire rld_coming; + wire rld_valid; + wire rld_done; + wire [0:1] rld_qw; + wire idle; + + //reg [0:127] mem[MEM_QW]; + + // todo + /* + + + 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 + always @(posedge clk) begin + + if (rst) begin + + cmdseq_q = 'b11111; + req_q = 0; + std_q = 0; + req_tkn_q = 0; + std_tkn_q = 0; + + end else begin + + cmdseq_q = cmdseq_d; + req_q = req_d; + std_q = std_d; + req_tkn_q = ac_an_req_pwr_token; + std_tkn_q = ac_an_st_data_pwr_token; + + end + end + + // Mem + +/* + always @(posedge clk) begin + + if (do_store) begin + mem[req_adr] = st_rmw_data; + end + end + assign mem_dat = mem[mem_adr]; + +*/ + assign mem_adr = req_adr >> 4; + + // clkgate + assign req_d = req_tkn_q ? {ac_an_req, + ac_an_req_thread, // 0:2 + ac_an_req_ttype, // 0:5 + ac_an_req_ld_core_tag, // 0:2 + ac_an_req_ra, // + ac_an_req_ld_xfr_len, // 0:2 + ac_an_req_wimg_w, + ac_an_req_wimg_i, + ac_an_req_wimg_m, + ac_an_req_wimg_g, + ac_an_req_wimg_endian, + ac_an_req_user_defined, // 0:3 + ac_an_req_spare_ctrl_a0 // 0:3 + } : 0; + assign std_d = std_tkn_q ? {ac_an_st_byte_enbl, // 0:31 + ac_an_st_data // 0:255 + } : 0; + + // request + assign req_ld_val = req_q[0] & ( + (req_q[4:9] == 'b000000) | // if + (req_q[4:9] == 'b001000) | // ld + (req_q[4:9] == 'b100010) | // ditc + (req_q[4:9] == 'b001001) | // larx + (req_q[4:9] == 'b001011); // larx hint + ); + + assign req_st_val = req_q[0] & ( + (req_q[4:9] == 'b100000) | // st + (req_q[4:9] == 'b101001) // stcx + ); + + assign req_tag = req_q[10:12]; + assign req_adr = req_q[14+64-`REAL_IFAR_WIDTH:14+63]; + + // coming --- --- + // valid --- --- --- --- (and qw, crit) + // data --- --- --- --- + + //tbl cmdseq + //n cmdseq_q cmdseq_d + //n | | rld_coming + //n | ld_req_val | |rld_valid + //n | |st_req_val | ||do_store + //n | ||ld_ready | |||rld_done + //n | |||st_ready | |||| + //n | ||||ld_ieq1 | |||| idle + //n | ||||| | |||| | + //n | ||||| | |||| | + //b 01234 ||||| 01234 |||| | + //t iiiii iiiii ooooo oooo o + //*---------------------------------------------------------------------- + //* Idle **************************************************************** + //s 11111 ----- ----- 0000 1 + //s 11111 00--- 11111 0000 - * ...zzz... + //s 11111 1---- 00001 0000 - + //s 11111 -1--- 10000 0000 - + //* Load **************************************************************** + //* 00001 --0-- 00001 0000 0 + //* 00001 --1-- 00010 1000 0 + //* Reload V0 *********************************************************** * val 0 + //* 00010 ----1 00011 0100 0 + //* 00011 ----0 00100 0100 0 + //* Reload D0 (I=1) ****************************************************** * dat 0 + //* 00011 ----- 11111 0001 0 + //* Reload D0 ************************************************************ * val 1, dat 0 + //* 00100 ----- 00101 1100 0 + //* Reload D1 ************************************************************ * val 2, dat 1 + //* 00101 ----- 00110 0100 0 + //* Reload D2 ************************************************************ * val 3, dat 2 + //* 00110 ----- 00111 0100 0 + //* Reload D3 ************************************************************ * dat 3 + //* 00111 ----- 11111 0001 0 + //* Store *************************************************************** + //* 10000 ---0- 10000 0000 0 + //* 10000 ---1- 11111 0010 0 + //*---------------------------------------------------------------------- + //tbl cmdseq + + assign reld_qw = cmdseq_q[3:4]; + + // response + assign an_ac_reld_ecc_err = 0; + assign an_ac_reld_ecc_err_ue = 0; + assign an_ac_reld_ditc = 0; + + // loads + assign an_ac_reld_data_coming = rld_coming; + assign an_ac_reld_data_vld = rld_valid; + assign an_ac_reld_core_tag = req_tag; + assign an_ac_reld_qw = reld_qw; + assign an_ac_reld_crit_qw = req_ieq1 | (req_adr[58:59] == reld_qw); + assign an_ac_reld_data = mem[{req_adr[64-`REAL_IFAR_WIDTH:59], reld_qw}]; + assign an_ac_req_ld_pop = rld_done; + + // stores + assign st_ready = 1; // random delay, or future functional stuff + 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 + assign st_alg_data = req_q[32:32+127]; // no shift needed? + + assign mem_wr_val = do_store; + assign mem_wr_dat = (mem_dat & st_mask) | (st_alg_data & ~st_mask); + + +//vtable cmdseq +//vtable cmdseq \ No newline at end of file diff --git a/dev/verilog/a2node/a2owb.v b/dev/verilog/a2node/a2owb.v new file mode 100644 index 0000000..fb8169a --- /dev/null +++ b/dev/verilog/a2node/a2owb.v @@ -0,0 +1,380 @@ +// © IBM Corp. 2022 +// Licensed under the Apache License, Version 2.0 (the "License"), as modified by +// the terms below; you may not use the files in this repository except in +// compliance with the License as modified. +// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +// +// Modified Terms: +// +// 1) For the purpose of the patent license granted to you in Section 3 of the +// License, the "Work" hereby includes implementations of the work of authorship +// in physical form. +// +// 2) Notwithstanding any terms to the contrary in the License, any licenses +// necessary for implementation of the Work that are available from OpenPOWER +// via the Power ISA End User License Agreement (EULA) are explicitly excluded +// hereunder, and may be obtained from OpenPOWER under the terms and conditions +// of the EULA. +// +// Unless required by applicable law or agreed to in writing, the reference design +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License +// for the specific language governing permissions and limitations under the License. +// +// Additional rights, including the ability to physically implement a softcore that +// is compliant with the required sections of the Power ISA Specification, are +// available at no cost under the terms of the OpenPOWER Power ISA EULA, which can be +// obtained (along with the Power ISA) here: https://openpowerfoundation.org. + +`include "tri_a2o.vh" + +`timescale 1ns/1ps + +module a2owb ( + + 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, + + // Perfmon Event Bus + output [0:4*`THREADS-1] ac_an_event_bus0, + output [0:4*`THREADS-1] ac_an_event_bus1, + + // 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, + + // 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 wb_i_stb, + output wb_i_cyc, + output [31:0] wb_i_adr, + input wb_i_ack, + input [31:0] wb_i_datr, + output wb_d_stb, + output wb_d_cyc, + output [31:0] wb_d_adr, + output wb_d_we, + output [3:0] wb_d_sel, + output [31:0] wb_d_datw, + input wb_d_ack, + input [31:0] wb_d_datr +); + +c c0( + .nclk(nclk), + .scan_in(scan_in), + .scan_out(scan_out), + + .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), + + .an_ac_stcx_complete(an_ac_stcx_complete[0]), + .an_ac_stcx_pass(an_ac_stcx_pass[0]), + .an_ac_reservation_vld(an_ac_reservation_vld[0]), + + .an_ac_icbi_ack(an_ac_icbi_ack), + .an_ac_icbi_ack_thread(an_ac_icbi_ack_thread), + .an_ac_sync_ack(an_ac_sync_ack[0]), + + .an_ac_back_inv(an_ac_back_inv), + .an_ac_back_inv_addr(an_ac_back_inv_addr), + .an_ac_back_inv_target(an_ac_back_inv_target), + .an_ac_back_inv_local(an_ac_back_inv_local), + .an_ac_back_inv_lbit(an_ac_back_inv_lbit), + .an_ac_back_inv_gs(an_ac_back_inv_gs), + .an_ac_back_inv_ind(an_ac_back_inv_ind), + .an_ac_back_inv_lpar_id(an_ac_back_inv_lpar_id), + .ac_an_back_inv_reject(ac_an_back_inv_reject), + .ac_an_lpar_id(ac_an_lpar_id), + + .an_ac_reld_data_vld(an_ac_reld_data_vld), + .an_ac_reld_core_tag(an_ac_reld_core_tag), + .an_ac_reld_data(an_ac_reld_data), + .an_ac_reld_qw(an_ac_reld_qw), + .an_ac_reld_ecc_err(an_ac_reld_ecc_err), + .an_ac_reld_ecc_err_ue(an_ac_reld_ecc_err_ue), + .an_ac_reld_data_coming(an_ac_reld_data_coming), + .an_ac_reld_ditc(an_ac_reld_ditc), + .an_ac_reld_crit_qw(an_ac_reld_crit_qw), + .an_ac_reld_l1_dump(an_ac_reld_l1_dump), + .an_ac_req_spare_ctrl_a1(an_ac_req_spare_ctrl_a1), + + .an_ac_flh2l2_gate(an_ac_flh2l2_gate), + .an_ac_req_ld_pop(an_ac_req_ld_pop), + .an_ac_req_st_pop(an_ac_req_st_pop), + .an_ac_req_st_gather(an_ac_req_st_gather), + .an_ac_pm_fetch_halt(an_ac_pm_fetch_halt), + + .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), + + .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), + + .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_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), + + .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_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), + .an_ac_scan_type_dc(an_ac_scan_type_dc), + .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), + + .ac_an_req_pwr_token(ac_an_req_pwr_token), + .ac_an_req(ac_an_req), + .ac_an_req_ra(ac_an_req_ra), + .ac_an_req_ttype(ac_an_req_ttype), + .ac_an_req_thread(ac_an_req_thread), + .ac_an_req_wimg_w(ac_an_req_wimg_w), + .ac_an_req_wimg_i(ac_an_req_wimg_i), + .ac_an_req_wimg_m(ac_an_req_wimg_m), + .ac_an_req_wimg_g(ac_an_req_wimg_g), + .ac_an_req_user_defined(ac_an_req_user_defined), + .ac_an_req_spare_ctrl_a0(ac_an_req_spare_ctrl_a0), + .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_st_byte_enbl(ac_an_st_byte_enbl), + .ac_an_st_data(ac_an_st_data), + .ac_an_req_endian(ac_an_req_endian), + .ac_an_st_data_pwr_token(ac_an_st_data_pwr_token) + ); + +a2l2wb n0( + .clk(clk_1x), + .rst(rst), + + // request + .ac_an_req_pwr_token(ac_an_req_pwr_token), + .ac_an_req(ac_an_req), + .ac_an_req_ra(ac_an_req_ra), + .ac_an_req_ttype(ac_an_req_ttype), + .ac_an_req_thread(ac_an_req_thread), + .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_st_data_pwr_token(ac_an_st_data_pwr_token) + .ac_an_st_byte_enbl(ac_an_st_byte_enbl), + .ac_an_st_data(ac_an_st_data), + .ac_an_req_wimg_w(ac_an_req_wimg_w), + .ac_an_req_wimg_i(ac_an_req_wimg_i), + .ac_an_req_wimg_m(ac_an_req_wimg_m), + .ac_an_req_wimg_g(ac_an_req_wimg_g), + .ac_an_req_endian(ac_an_req_endian), + .ac_an_req_user_defined(ac_an_req_user_defined), + .ac_an_req_spare_ctrl_a0(ac_an_req_spare_ctrl_a0), + + // reload + .an_ac_reld_data_vld(an_ac_reld_data_vld), + .an_ac_reld_core_tag(an_ac_reld_core_tag), + .an_ac_reld_data(an_ac_reld_data), + .an_ac_reld_qw(an_ac_reld_qw), + .an_ac_reld_ecc_err(an_ac_reld_ecc_err), + .an_ac_reld_ecc_err_ue(an_ac_reld_ecc_err_ue), + .an_ac_reld_data_coming(an_ac_reld_data_coming), + .an_ac_reld_ditc(an_ac_reld_ditc), + .an_ac_reld_crit_qw(an_ac_reld_crit_qw), + .an_ac_reld_l1_dump(an_ac_reld_l1_dump), + .an_ac_req_spare_ctrl_a1(an_ac_req_spare_ctrl_a1), + + // larx/stcx + .an_ac_stcx_complete(an_ac_stcx_complete), + .an_ac_stcx_pass(an_ac_stcx_pass), + .an_ac_reservation_vld(an_ac_reservation_vld), + + // icbi + .an_ac_icbi_ack(an_ac_icbi_ack), + .an_ac_icbi_ack_thread(an_ac_icbi_ack_thread), + + // back invalidate + .an_ac_back_inv(an_ac_back_inv), + .an_ac_back_inv_addr(an_ac_back_inv_addr), + .an_ac_back_inv_target(an_ac_back_inv_target), + .an_ac_back_inv_local(an_ac_back_inv_local), + .an_ac_back_inv_lbit(an_ac_back_inv_lbit), + .an_ac_back_inv_gs(an_ac_back_inv_gs), + .an_ac_back_inv_ind(an_ac_back_inv_ind), + .an_ac_back_inv_lpar_id(an_ac_back_inv_lpar_id), + .ac_an_back_inv_reject(ac_an_back_inv_reject), + .ac_an_lpar_id(ac_an_lpar_id), + + // credits + .an_ac_req_ld_pop(an_ac_req_ld_pop), + .an_ac_req_st_pop(an_ac_req_st_pop), + .an_ac_req_st_gather(an_ac_req_st_gather), + .an_ac_sync_ack(an_ac_sync_ack), + .an_ac_pm_fetch_halt(an_ac_pm_fetch_halt), + + // misc + .an_ac_flh2l2_gate(an_ac_flh2l2_gate), + .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), + .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), + .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), + + // scom + .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), + + // errors + .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), + .ac_an_machine_check(ac_an_machine_check), + + // perfmon + .ac_an_event_bus0(ac_an_event_bus0), + .ac_an_event_bus1(ac_an_event_bus1), + + // power + .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), + ); + +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; + +assign clk_1x = nclk[0]; +assign clk_2x = nclk[2]; +assign clk_4x = nclk[3]; +assign rst = nclk[1]; + +endmodule \ No newline at end of file