OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /zipcpu
    from Rev 204 to Rev 203
    Reverse comparison

Rev 204 → Rev 203

/trunk/sim/verilator/zipelf.cpp File deleted \ No newline at end of file
trunk/sim/verilator/zipelf.cpp Property changes : Deleted: svn:special ## -1 +0,0 ## -* \ No newline at end of property Index: trunk/sim/verilator/mpy_tb.cpp =================================================================== --- trunk/sim/verilator/mpy_tb.cpp (revision 204) +++ trunk/sim/verilator/mpy_tb.cpp (nonexistent) @@ -1,359 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Filename: mpy_tb.cpp -// -// Project: Zip CPU -- a small, lightweight, RISC CPU soft core -// -// Purpose: Bench testing for the multiply ALU instructions used within the -// Zip CPU. This depends upon the cpuops.v module, but should be -// independent of the internal settings within the module. -// -// -// Creator: Dan Gisselquist, Ph.D. -// Gisselquist Technology, LLC -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015-2016, Gisselquist Technology, LLC -// -// This program is free software (firmware): you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// License: GPL, v3, as defined and found on www.gnu.org, -// http://www.gnu.org/licenses/gpl.html -// -// -/////////////////////////////////////////////////////////////////////////////// -// -// -#include -#include -#include -#include - -#include -#include - -#include "verilated.h" -#include "Vcpuops.h" - -#include "testb.h" -#include "cpudefs.h" -// #include "twoc.h" - -class CPUOPS_TB : public TESTB { -public: - // Nothing special to do in a startup. - CPUOPS_TB(void) {} - - // ~CPUOPS_TB(void) {} - - // - // Calls TESTB<>::reset to reset the core. Makes sure the i_ce line - // is low during this reset. - // - void reset(void) { - // m_flash.debug(false); - m_core->i_ce = 0; - - TESTB::reset(); - } - - // - // dbgdump(); - // - // Just before the positive edge of every clock, we call this function - // (if the debug flag is set). This prints out a line of information - // telling us what is going on within the logic, allowing us access - // for debugging purposes to inspect things. - // - // Other than debugging, this isn't necessary for the functioning of the - // test bench. At the same time, what are you using a test bench for if - // not for debugging? - // - void dbgdump(void) { - char outstr[2048], *s; - sprintf(outstr, "Tick %4ld %s%s ", - m_tickcount, - (m_core->i_rst)?"R":" ", - (m_core->i_ce)?"CE":" "); - switch(m_core->i_op) { - case 0: strcat(outstr, " SUB"); break; - case 1: strcat(outstr, " AND"); break; - case 2: strcat(outstr, " ADD"); break; - case 3: strcat(outstr, " OR"); break; - case 4: strcat(outstr, " XOR"); break; - case 5: strcat(outstr, " LSR"); break; - case 6: strcat(outstr, " LSL"); break; - case 7: strcat(outstr, " ASR"); break; - case 8: strcat(outstr, " MPY"); break; - case 9: strcat(outstr, "LODILO"); break; - case 10: strcat(outstr, "MPYUHI"); break; - case 11: strcat(outstr, "MPYSHI"); break; - case 12: strcat(outstr, " BREV"); break; - case 13: strcat(outstr, " POPC"); break; - case 14: strcat(outstr, " ROL"); break; - case 15: strcat(outstr, " MOV"); break; - default: strcat(outstr, "UNKWN!"); break; - } s = &outstr[strlen(outstr)]; - sprintf(s, "(%x) 0x%08x 0x%08x -> 0x%08x [%x] %s%s", - m_core->i_op, - m_core->i_a, m_core->i_b, - m_core->o_c, m_core->o_f, - (m_core->o_valid)?"V":" ", - (m_core->o_busy)?"B":" "); - s = &outstr[strlen(outstr)]; - -#if(OPT_MULTIPLY==1) - sprintf(s, "1,MPY[][][%016lx]", - m_core->v__DOT__mpy_result); - s = &outstr[strlen(outstr)]; -#elif(OPT_MULTIPLY==2) - sprintf(s, "2,MPY[%016lx][%016lx][%016lx]", - m_core->v__DOT__genblk2__DOT__genblk2__DOT__genblk1__DOT__r_mpy_a_input, - m_core->v__DOT__genblk2__DOT__genblk2__DOT__genblk1__DOT__r_mpy_b_input, - m_core->v__DOT__mpy_result); - s = &outstr[strlen(outstr)]; -#elif(OPT_MULTIPLY==3) - sprintf(s, "3,MPY[%08x][%08x][%016lx], P[%d]", - m_core->v__DOT__genblk2__DOT__genblk2__DOT__genblk2__DOT__genblk1__DOT__r_mpy_a_input, - m_core->v__DOT__genblk2__DOT__genblk2__DOT__genblk2__DOT__genblk1__DOT__r_mpy_b_input, - m_core->v__DOT__genblk2__DOT__genblk2__DOT__genblk2__DOT__genblk1__DOT__r_smpy_result, - m_core->v__DOT__genblk2__DOT__genblk2__DOT__genblk2__DOT__genblk1__DOT__mpypipe); - -#endif - -#if(OPT_MULTIPLY != 1) - if (m_core->v__DOT__this_is_a_multiply_op) - strcat(s, " MPY-OP"); -#endif - puts(outstr); - } - - // - // tick() - // - // Call this to step the processor. - // - // This is a bit unusual compared to other tick() functions I have in - // my simulators in that there are a lot of calls to eval() with clk==0. - // This is because the multiply logic for OPT_MULTIPLY < 3 depends upon - // it to be valid. I assume any true Xilinx, or even higher level, - // implementation wouldn't have this problem. - // - void tick(void) { - bool debug = false; - - // Insist that we are never both busy and producing a valid - // result at the same time. One or the other may be true, - // but never both. - assert((!m_core->o_busy)||(!m_core->o_valid)); - // - TESTB::tick(); - - if (debug) - dbgdump(); - } - - // - // clear_ops - // - // Runs enough clocks through the device until it is neither busy nor - // valid. At this point, the ALU should be thoroughly clear. Then - // we tick things once more. - // - void clear_ops(void) { - m_core->i_ce = 0; - m_core->i_op = 0; - - do { - tick(); - } while((m_core->o_busy)||(m_core->o_valid)); - tick(); - } - - // - // This is a fairly generic CPU operation call. What makes it less - // than generic are two things: 1) the ALU is cleared before any - // new instruction, and 2) the tick count at the end is compared - // against the tick count OPT_MULTIPLY says we should be getting. - // A third difference between this call in simulation and a real - // call within the CPU is that we never set the reset mid-call, whereas - // the CPU may need to do that if a jump is made and the pipeline needs - // to be cleared. - // - unsigned op(int op, int a, int b) { - // Make sure we start witht he core idle - if (m_core->o_valid) - clear_ops(); - - // Set the arguments to the CPUOPS core to get a multiple - // started - m_core->i_ce = 1; - m_core->i_op = op; - m_core->i_a = a; - m_core->i_b = b; - - unsigned long now = m_tickcount; - - // Tick once to get it going - tick(); - - // Clear the input arguments to the multiply - m_core->i_ce = 0; - m_core->i_a = 0; - m_core->i_b = 0; - - // Wait for the result to be valid - while(!m_core->o_valid) - tick(); - - // Check that we used the number of clock ticks we said we'd - // be using. OPT_MULTIPLY is *supposed* to be equal to this - // number. - if((m_tickcount - now)!=OPT_MULTIPLY) { - printf("%ld ticks seen, %d ticks expected\n", - m_tickcount-now, OPT_MULTIPLY); - dbgdump(); - printf("TEST-FAILURE!\n"); - closetrace(); - exit(EXIT_FAILURE); - } - - return m_core->o_c; - } - - // - // Here's our testing function. Pardon the verbosity of the error - // messages within it, but ... well, hopefully you won't ever encounter - // any of those errors. ;) - // - // The function works by applying the two inputs to all three of the - // multiply functions, MPY, MPSHI, and MPYUHI. Results are compared - // against a local multiply on the local (host) machine. If there's - // any mismatch, an error message is printed and the test fails. - void mpy_test(int a, int b) { - const int OP_MPY = 0x08, OP_MPYSHI=0xb, OP_MPYUHI=0x0a; - long ia, ib, sv; - unsigned long ua, ub, uv; - unsigned r, s, u; - - clear_ops(); - - printf("MPY-TEST: 0x%08x x 0x%08x\n", a, b); - - ia = (long)a; ib = (long)b; sv = ia * ib; - ua = ((unsigned long)a)&0x0ffffffffu; - ub = ((unsigned long)b)&0x0ffffffffu; - uv = ua * ub; - - r = op(OP_MPY, a, b); - s = op(OP_MPYSHI, a, b); - u = op(OP_MPYUHI, a, b); - tick(); - - // Let's check our answers, and see if we got the right results - if ((r ^ sv)&0x0ffffffffu) { - printf("TEST FAILURE(MPY), MPY #1\n"); - printf("Comparing 0x%08x to 0x%016lx\n", r, sv); - printf("TEST-FAILURE!\n"); - closetrace(); - exit(EXIT_FAILURE); - } if ((r ^ uv)&0x0ffffffffu) { - printf("TEST FAILURE(MPY), MPY #2\n"); - printf("Comparing 0x%08x to 0x%016lx\n", r, uv); - printf("TEST-FAILURE!\n"); - closetrace(); - exit(EXIT_FAILURE); - } - - if ((s^(sv>>32))&0x0ffffffffu) { - printf("TEST FAILURE(MPYSHI), MPY #3\n"); - printf("Comparing 0x%08x to 0x%016lx\n", s, sv); - printf("TEST-FAILURE!\n"); - closetrace(); - exit(EXIT_FAILURE); - } if ((u^(uv>>32))&0x0ffffffffu) { - printf("TEST FAILURE(MPYUHI), MPY #4\n"); - printf("Comparing 0x%08x to 0x%016lx\n", u, uv); - printf("TEST-FAILURE!\n"); - closetrace(); - exit(EXIT_FAILURE); - } - } -}; - -void usage(void) { - printf("USAGE: mpy_tb [a b]\n"); - printf("\n"); - printf( -"The test is intended to be run with no arguments. When run in this fashion,\n" -"a series of multiplcation tests will be conducted using all three multiply\n" -"instructions. Any test failure will terminate the program with an exit\n" -"condition. Test success will terminate with a clear test condition. \n" -"During the test, you may expect a large amount of debug output to be\n" -"produced. This is a normal part of testing. For the meaning of the debug\n" -"output, please consider the source code. The last line of the debug output,\n" -"however, will always include either the word \"FAIL\" or \"SUCCESS\"\n" -"depending on whether the test succeeds or fails.\n\n" -"If the two arguments a and b are given, they will be interpreted according\n" -"to the form of strtol, and the test will only involve testing those two\n" -"parameters\n\n"); -} - -int main(int argc, char **argv) { - // Setup verilator - Verilated::commandArgs(argc, argv); - // Now, create a test bench. - CPUOPS_TB *tb = new CPUOPS_TB(); - int rcode = EXIT_SUCCESS; - // tb->opentrace("mpy_tb.vcd"); - - // Get us started by a couple of clocks past reset. This isn't that - // unreasonable, since the CPU needs to load up the pipeline before - // any first instruction will be executed. - tb->reset(); - tb->tick(); - tb->tick(); - tb->tick(); - - // Look for options, such as '-h'. Trap those here, and produce a usage - // statement. - if ((argc > 1)&&(argv[1][0]=='-')&&(isalpha(argv[1][1]))) { - usage(); - exit(EXIT_SUCCESS); - } - - if (argc == 3) { - // Were we given enough arguments to run a user-specified test? - tb->mpy_test( - strtol(argv[1], NULL, 0), - strtol(argv[2], NULL, 0)); - } else { - // Otherwise we run through a canned set of tests. - tb->mpy_test(0,0); - tb->mpy_test(-1,0); - tb->mpy_test(-1,-1); - tb->mpy_test(1,-1); - tb->mpy_test(1,0); - tb->mpy_test(0,1); - tb->mpy_test(1,1); - - for(int a=0; ((a&0xfff00000)==0); a+=137) - tb->mpy_test(139, a); - - for(int a=0; ((a&0x80000000)==0); a+=0x197e2) - tb->mpy_test(0xf97e27ab, a); - } - - printf("SUCCESS!\n"); - exit(rcode); -} - Index: trunk/sim/verilator/memsim.h =================================================================== --- trunk/sim/verilator/memsim.h (revision 204) +++ trunk/sim/verilator/memsim.h (nonexistent) @@ -1,74 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Filename: memsim.h -// -// Project: Zip CPU -- a small, lightweight, RISC CPU core -// -// Purpose: This creates a memory like device to act on a WISHBONE bus. -// It doesn't exercise the bus thoroughly, but does give some -// exercise to the bus to see whether or not the bus master -// can control it. -// -// -// Creator: Dan Gisselquist, Ph.D. -// Gisselquist Technology, LLC -// -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015,2017, Gisselquist Technology, LLC -// -// This program is free software (firmware): you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program. (It's in the $(ROOT)/doc directory, run make with no -// target there if the PDF file isn't present.) If not, see -// for a copy. -// -// License: GPL, v3, as defined and found on www.gnu.org, -// http://www.gnu.org/licenses/gpl.html -// -// -//////////////////////////////////////////////////////////////////////////////// -// -// -#ifndef MEMSIM_H -#define MEMSIM_H - -class MEMSIM { -public: - typedef unsigned int BUSW; - typedef unsigned char uchar; - - BUSW *m_mem, m_len, m_mask; - int m_nxt_ack; - BUSW m_nxt_data; - - - MEMSIM(const unsigned int nwords); - ~MEMSIM(void); - void load(const char *fname); - void load(const unsigned addr, const char *buf,const unsigned len); - void apply(const uchar wb_cyc, const uchar wb_stb, - const uchar wb_we, - const BUSW wb_addr, const BUSW wb_data, - const uchar wb_sel, - uchar &o_ack, uchar &o_stall, BUSW &o_data); - void operator()(const uchar wb_cyc, const uchar wb_stb, - const uchar wb_we, - const BUSW wb_addr, const BUSW wb_data, - const uchar wb_sel, - uchar &o_ack, uchar &o_stall, BUSW &o_data) { - apply(wb_cyc, wb_stb, wb_we, wb_addr, wb_data, wb_sel, o_ack, o_stall, o_data); - } - BUSW &operator[](const BUSW addr) { return m_mem[addr&m_mask]; } -}; - -#endif Index: trunk/sim/verilator/Makefile =================================================================== --- trunk/sim/verilator/Makefile (revision 204) +++ trunk/sim/verilator/Makefile (nonexistent) @@ -1,208 +0,0 @@ -################################################################################ -# -# Filename: Makefile -# -# Project: Zip CPU -- a small, lightweight, RISC CPU soft core -# -# Purpose: This makefile builds the final verilator simulation of the -# zipsystem. Specifically, it builds the final C++ portion -# of the simulator, and thus the final simulator executable. -# -# This simulator depends upon the libelf and ncurses libraries. -# -# Useful targets of this makefile include: -# -# zippy_tb (default) -# This is the test bench program / simulator that is built by -# this directory. -# -# test -# Runs the simulator on a test program found in the trunk/sw/zasm -# directory. That program needs to be built via 'make test' in -# that directory before this make test will work. Changes to the -# test itself will require a 'make test' in trunk/sw/zasm as well -# as 'make test' in this directory. -# -# The test itself consists of two tests. The first, the "step" -# test, tests whether the test works via "step"ing the CPU. -# This would be the interface to the CPU were the CPU placed in -# a device. -# -# The second test is an internal test which works by just running -# the CPU without step instructions. -# -# In either case the test is over upon reaching either a HALT -# or a BUSY instruction. A HALT instruction indicates success, -# BUSY a failure. -# -# stest -# Runs the test in "step" mode as described above. -# -# itest -# Runs the test file in interactive mode. The CPU will not -# execute any instructions without user interaction. This is -# useful for actually debugging the test. The other two modes -# are useful for quickly determining that the CPU does (or -# doesn't) work. -# -# dhrystone -# Runs a hand-optimized version of the dhrystone benchmark. -# Using the instructions at the top of the dhrystone assembly -# file, you should be able to convert the result to DMIPS or even -# DMIPS/MHz. -# -# div_tb -# A raw test bench to test the divide unit separate from the -# rest of the CPU. This test will fail with a failed assert() -# if unsuccessful, or complete with no error (but lots of -# debugging output) if successful. To actually run this test, -# you'll need to run ./div_tb (no arguments necessary). -# -# mpy_tb -# A raw test bench to test the multiply instructions within the -# cpuops (ALU) unit separate from the rest of the CPU. For more -# details, look at the usage statement wtihin mpy_tb. -# -# pfcache_tb -# -# zipmmu_tb -# Like div_tb, this is another raw component test bench. In this -# case, zipmmu_tb tests whether or not the MMU works when -# separated from the rest of the CPU. -# -# pdump -# zippy_tb can be configured to produce a profile output that is -# very useful when debugging the Dhrystone benchmark. (It is -# so configured by default.) This file will be name pfile.bin. -# pdump is a very simple program designed to read this file and -# produce some (very raw) information from it. To use this, -# type pdump and the name of the executable file, such as -# ../asm/zipdhry.z, and examine how many times each instruction -# was executed, and how many stalls took place between each -# instruction and the next. -# -# clean -# Removes all products of compilation--specifically zippy_tb, -# pdump and div_tb. -# -# -# Creator: Dan Gisselquist, Ph.D. -# Gisselquist Technology, LLC -# -################################################################################ -# -# Copyright (C) 2015-2017, Gisselquist Technology, LLC -# -# This program is free software (firmware): you can redistribute it and/or -# modify it under the terms of the GNU General Public License as published -# by the Free Software Foundation, either version 3 of the License, or (at -# your option) any later version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# License: GPL, v3, as defined and found on www.gnu.org, -# http://www.gnu.org/licenses/gpl.html -# -# -################################################################################ -# -all: zippy_tb pdump div_tb mpy_tb pfcache_tb # zipmmu_tb - -CXX := g++ -CFLAGS := -Wall -Og -g -OBJDIR := obj-pc -ZASM := ../../sw/zasm -RTLD := ../../rtl -RTLOBJD := $(RTLD)/obj_dir -BENCHOBJD:= ../../bench/rtl/obj_dir -VERILATOR_ROOT ?= $(shell bash -c 'verilator -V|grep VERILATOR_ROOT | head -1 | sed -e " s/^.*=\s*//"') -VROOT := $(VERILATOR_ROOT) -VINCS := -I$(VROOT)/include -I$(VROOT)/include/vltstd -INCS := -I$(RTLOBJD) -I$(RTLD) -I$(ZASM) $(VINCS) -ZLIBSRCS:= zipelf.cpp twoc.cpp byteswap.cpp -SOURCES := $(ZLIBSRCS) pdump.cpp zippy_tb.cpp memsim.cpp -ZDSMSRCS:= zopcodes.cpp -ZOBJS := $(addprefix $(OBJDIR)/,$(subst .cpp,.o,$(ZLIBSRCS) $(ZDSMSRCS))) -SIMSRCS := zippy_tb.cpp memsim.cpp $(ZLIBSRCS) $(ZDMSRCS) -SIMOBJS := $(addprefix $(OBJDIR)/,$(subst .cpp,.o,$(SIMSRCS) $(ZDSMSRCS))) -VLSRCS := verilated.cpp verilated_vcd_c.cpp -VLOBJS := $(OBJDIR)/verilated.o $(OBJDIR)/verilated_vcd_c.o -VLIB := $(addprefix $(VROOT)/include/,$(VLSRCS)) -RAWLIB := $(RTLOBJD)/Vzipsystem__ALL.a -LIBS := $(RAWLIB) -lncurses -lelf -TESTF := $(ZASM)/z.out -DHRYSTONEF := ../asm/zipdhry.z - -$(OBJDIR)/%.o: %.cpp - $(CXX) $(CFLAGS) $(INCS) -c $< -o $@ - -$(OBJDIR)/%.o: $(ZASM)/%.cpp - $(CXX) $(CFLAGS) $(INCS) -c $< -o $@ - -$(OBJDIR)/%.o: $(VROOT)/include/%.cpp - $(CXX) $(CFLAGS) $(INCS) -c $< -o $@ - -zippy_tb: $(SIMOBJS) $(VLOBJS) $(RAWLIB) - $(CXX) $(CFLAGS) $(INCS) $(SIMOBJS) $(VLOBJS) $(RAWLIB) $(LIBS) -o $@ - -div_tb: div_tb.cpp twoc.cpp $(VLIB) $(RTLOBJD)/Vdiv__ALL.a testb.h - $(CXX) $(CFLAGS) $(INCS) div_tb.cpp twoc.cpp $(VLIB) $(RTLOBJD)/Vdiv__ALL.a -o $@ - -mpy_tb: mpy_tb.cpp twoc.cpp $(VLIB) $(RTLOBJD)/Vcpuops__ALL.a testb.h - $(CXX) $(CFLAGS) $(INCS) mpy_tb.cpp twoc.cpp $(VLIB) $(RTLOBJD)/Vcpuops__ALL.a -o $@ - -zipmmu_tb: zipmmu_tb.cpp $(VLIB) $(BENCHOBJD)/Vzipmmu_tb__ALL.a - $(CXX) $(CFLAGS) $(INCS) -I$(BENCHOBJD) zipmmu_tb.cpp $(VLIB) $(BENCHOBJD)/Vzipmmu_tb__ALL.a -o $@ - -pfcache_tb: $(OBJDIR)/pfcache_tb.o $(OBJDIR)/memsim.o $(OBJDIR)/byteswap.o -pfcache_tb: $(VLIB) $(RTLOBJD)/Vpfcache__ALL.a - $(CXX) $(CFLAGS) $(INCS) -I$(RTLOBJD) $(OBJDIR)/pfcache_tb.o $(OBJDIR)/memsim.o $(OBJDIR)/byteswap.o $(VLIB) $(RTLOBJD)/Vpfcache__ALL.a -o $@ - -pdump: pdump.cpp $(ZOBJS) $(OBJDIR)/zopcodes.o $(OBJDIR)/pdump.o -pdump: $(ZASM)/zopcodes.h testb.h byteswap.h zipelf.h - $(CXX) $(CFLAGS) $(INCS) $(OBJDIR)/pdump.o $(ZOBJS) -lelf -o $@ - -.PHONY: stest -stest: zippy_tb - ./zippy_tb -s $(TESTF) - -.PHONY: itest -itest: zippy_tb - ./zippy_tb $(TESTF) - -.PHONY: test -test: zippy_tb stest - ./zippy_tb -a $(TESTF) - -.PHONY: dhrystone -dhrystone: zippy_tb - ./zippy_tb -a $(DHRYSTONEF) - -define build-depends - @echo "Building dependencies" - @$(CXX) $(CPPFLAGS) $(INCS) -MM $(VLIB) $(SOURCES) > $(OBJDIR)/xdepends.txt - @sed -e 's/^.*.o: /$(OBJDIR)\/&/' < $(OBJDIR)/xdepends.txt > $(OBJDIR)/depends.txt - @rm $(OBJDIR)/xdepends.txt -endef - -tags: $(VLIB) $(SOURCES) - @ctags $(SOURCES) $(VLIB) - -.PHONY: depends -depends: tags $(OBJDIR)/ - $(build-depends) - -$(OBJDIR)/: - @bash -c "if [ ! -e $(OBJDIR) ]; then mkdir -p $(OBJDIR)/; fi" - -$(OBJDIR)/depends.txt: $(OBJDIR)/ depends - -.PHONY: clean -clean: - rm -rf $(OBJDIR)/ - rm -rf ./zippy_tb pdump div_tb mpy_tb - --include $(OBJDIR)/depends.txt Index: trunk/sim/verilator/zipelf.h =================================================================== --- trunk/sim/verilator/zipelf.h (revision 204) +++ trunk/sim/verilator/zipelf.h (nonexistent) @@ -1 +0,0 @@ -link ../cpp/zipelf.h \ No newline at end of file
trunk/sim/verilator/zipelf.h Property changes : Deleted: svn:special ## -1 +0,0 ## -* \ No newline at end of property Index: trunk/sim/verilator/byteswap.cpp =================================================================== --- trunk/sim/verilator/byteswap.cpp (revision 204) +++ trunk/sim/verilator/byteswap.cpp (nonexistent) @@ -1,114 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Filename: byteswap.cpp -// -// Project: Zip CPU -- a small, lightweight, RISC CPU soft core -// -// Purpose: To convert between little endian and big endian byte orders, -// and to handle conversions between character strings and -// bit-endian words made from those characters. -// -// -// Creator: Dan Gisselquist, Ph.D. -// Gisselquist Technology, LLC -// -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015-2016, Gisselquist Technology, LLC -// -// This program is free software (firmware): you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program. (It's in the $(ROOT)/doc directory. Run make with no -// target there if the PDF file isn't present.) If not, see -// for a copy. -// -// License: GPL, v3, as defined and found on www.gnu.org, -// http://www.gnu.org/licenses/gpl.html -// -// -//////////////////////////////////////////////////////////////////////////////// -// -// -#include -#include "byteswap.h" - -/* - * byteswap - * - * Given a big (or little) endian word, return a little (or big) endian word. - */ -uint32_t -byteswap(uint32_t v) { - uint32_t r = 0; - - r = (v & 0x0ff); - r <<= 8; v >>= 8; - r |= (v & 0x0ff); - r <<= 8; v >>= 8; - r |= (v & 0x0ff); - r <<= 8; v >>= 8; - r |= (v & 0x0ff); - - return r; -} - - -/* - * byteswapbuf - * - * To swap from the byte order of every 32-bit word in the given buffer. - */ -void -byteswapbuf(int ln, uint32_t *buf) { - for(int i=0; i -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "verilated.h" -#include "verilated_vcd_c.h" -#include "Vzipsystem.h" -#include "cpudefs.h" - -#include "testb.h" -#include "zipelf.h" -// #include "twoc.h" -// #include "qspiflashsim.h" -#include "byteswap.h" -#include "memsim.h" -#include "zopcodes.h" - -#define CMD_REG 0 -#define CMD_DATA 1 -#define CMD_GIE (1<<13) -#define CMD_SLEEP (1<<12) -#define CMD_CLEAR_CACHE (1<<11) -#define CMD_HALT (1<<10) -#define CMD_STALL (1<<9) -#define CMD_INT (1<<7) -#define CMD_RESET (1<<6) -#define CMD_STEP ((1<<8)|CMD_HALT) - -#define KEY_ESCAPE 27 -#define KEY_RETURN 10 -#define CTRL(X) ((X)&0x01f) - -#define MAXERR 10000 - -/* -// We are just a raw CPU with memory. There is no flash. -#define LGFLASHLEN 24 -#define FLASHBASE 0x01000000 -#define FLASHWORDS (1<>2) - -class SPARSEMEM { -public: - bool m_valid; - unsigned int m_a, m_d; -}; - -class ZIPSTATE { -public: - bool m_valid, m_gie, m_last_pc_valid; - unsigned int m_sR[16], m_uR[16]; - unsigned int m_p[20]; - unsigned int m_last_pc, m_pc, m_sp; - SPARSEMEM m_smem[5]; // Nearby stack memory - SPARSEMEM m_imem[5]; // Nearby instruction memory - ZIPSTATE(void) : m_valid(false), m_last_pc_valid(false) {} - - void step(void) { - m_last_pc_valid = true; - m_last_pc = m_pc; - } -}; - -extern FILE *gbl_dbgfp; -FILE *gbl_dbgfp = NULL; - -// No particular "parameters" need definition or redefinition here. -class ZIPPY_TB : public TESTB { -public: - unsigned long m_mem_size; - MEMSIM m_mem; - // QSPIFLASHSIM m_flash; - FILE *m_dbgfp, *m_profile_fp; - bool dbg_flag, m_bomb, m_show_user_timers; - int m_cursor; - unsigned long m_last_instruction_tickcount; - ZIPSTATE m_state; - - ZIPPY_TB(void) : m_mem_size(RAMWORDS), m_mem(m_mem_size) { - if (true) { - m_dbgfp = fopen("debug.txt", "w"); - dbg_flag = true; - gbl_dbgfp = m_dbgfp; - } else { - m_dbgfp = NULL; - dbg_flag = false; - gbl_dbgfp = NULL; - } - - if(true) { - // TESTB::opentrace("trace.vcd"); - opentrace("trace.vcd"); - } else { - m_trace = NULL; - } - - m_bomb = false; - m_cursor = 0; - m_show_user_timers = false; - - m_last_instruction_tickcount = 0l; - if (true) { - m_profile_fp = fopen("pfile.bin","wb"); - } else { - m_profile_fp = NULL; - } - } - - ~ZIPPY_TB(void) { - if (m_dbgfp) - fclose(m_dbgfp); - if (m_profile_fp) - fclose(m_profile_fp); - if (m_trace) - m_trace->close(); - } - - void reset(void) { - // m_flash.debug(false); - TESTB::reset(); - } - - void step(void) { - wb_write(CMD_REG, CMD_STEP); - m_state.step(); - } - - void read_raw_state(void) { - m_state.m_valid = false; - for(int i=0; i<16; i++) - m_state.m_sR[i] = cmd_read(i); - for(int i=0; i<16; i++) - m_state.m_uR[i] = cmd_read(i+16); - for(int i=0; i<20; i++) - m_state.m_p[i] = cmd_read(i+32); - - m_state.m_gie = wb_read(CMD_REG) & CMD_GIE; - m_state.m_pc = (m_state.m_gie) ? (m_state.m_uR[15]):(m_state.m_sR[15]); - m_state.m_sp = (m_state.m_gie) ? (m_state.m_uR[13]):(m_state.m_sR[13]); - - if (m_state.m_last_pc_valid) - m_state.m_imem[0].m_a = m_state.m_last_pc; - else - m_state.m_imem[0].m_a = m_state.m_pc - 1; - m_state.m_imem[0].m_d = m_mem[m_state.m_imem[0].m_a & 0x0fffff]; - m_state.m_imem[0].m_valid = ((m_state.m_imem[0].m_a & 0xfff00000)==0x00100000); - m_state.m_imem[1].m_a = m_state.m_pc; - m_state.m_imem[1].m_valid = ((m_state.m_imem[1].m_a & 0xfff00000)==0x00100000); - m_state.m_imem[1].m_d = m_mem[m_state.m_imem[1].m_a & 0x0fffff]; - - for(int i=1; i<4; i++) { - if (!m_state.m_imem[i].m_valid) { - m_state.m_imem[i+1].m_valid = false; - m_state.m_imem[i+1].m_a = m_state.m_imem[i].m_a+1; - continue; - } - m_state.m_imem[i+1].m_a = zop_early_branch( - m_state.m_imem[i].m_a, - m_state.m_imem[i].m_d); - m_state.m_imem[i+1].m_d = m_mem[m_state.m_imem[i].m_a & 0x0fffff]; - m_state.m_imem[i+1].m_valid = ((m_state.m_imem[i].m_a&0xfff00000)==0x00100000); - } - - m_state.m_smem[0].m_a = m_state.m_sp; - for(int i=1; i<5; i++) - m_state.m_smem[i].m_a = m_state.m_smem[i-1].m_a+1; - for(int i=0; i<5; i++) { - m_state.m_smem[i].m_valid = - (m_state.m_imem[i].m_a > 0x10000); - m_state.m_smem[i].m_d = m_mem[m_state.m_imem[i].m_a & 0x0fffff]; - } - m_state.m_valid = true; - } - - void read_raw_state_cheating(void) { - m_state.m_valid = false; - for(int i=0; i<16; i++) - m_state.m_sR[i] = m_core->v__DOT__thecpu__DOT__regset[i]; - m_state.m_sR[14] = (m_state.m_sR[14]&0xffffe000)|m_core->v__DOT__thecpu__DOT__w_iflags; - m_state.m_sR[15] = m_core->v__DOT__thecpu__DOT__ipc; - for(int i=0; i<16; i++) - m_state.m_uR[i] = m_core->v__DOT__thecpu__DOT__regset[i+16]; - m_state.m_uR[14] = (m_state.m_uR[14]&0xffffe000)|m_core->v__DOT__thecpu__DOT__w_uflags; - m_state.m_uR[15] = m_core->v__DOT__thecpu__DOT__r_upc; - - m_state.m_gie = m_core->v__DOT__thecpu__DOT__r_gie; - m_state.m_pc = (m_state.m_gie) ? (m_state.m_uR[15]):(m_state.m_sR[15]); - m_state.m_sp = (m_state.m_gie) ? (m_state.m_uR[13]):(m_state.m_sR[13]); - - m_state.m_p[0] = m_core->v__DOT__pic_data; - m_state.m_p[1] = m_core->v__DOT__watchdog__DOT__r_value; - if (!m_show_user_timers) { - m_state.m_p[2] = m_core->v__DOT__watchbus__DOT__r_value; - } else { - m_state.m_p[2] = m_core->v__DOT__r_wdbus_data; - } - - m_state.m_p[3] = m_core->v__DOT__genblk7__DOT__ctri__DOT__r_int_state; - m_state.m_p[4] = m_core->v__DOT__timer_a__DOT__r_value; - m_state.m_p[5] = m_core->v__DOT__timer_b__DOT__r_value; - m_state.m_p[6] = m_core->v__DOT__timer_c__DOT__r_value; - m_state.m_p[7] = m_core->v__DOT__jiffies__DOT__r_counter; - - m_state.m_p[ 8] = m_core->v__DOT__utc_data; - m_state.m_p[ 9] = m_core->v__DOT__uoc_data; - m_state.m_p[10] = m_core->v__DOT__upc_data; - m_state.m_p[11] = m_core->v__DOT__uic_data; - - m_state.m_p[12] = m_core->v__DOT__mtc_data; - m_state.m_p[13] = m_core->v__DOT__moc_data; - m_state.m_p[14] = m_core->v__DOT__mpc_data; - m_state.m_p[15] = m_core->v__DOT__mic_data; - - } - - void showval(int y, int x, const char *lbl, unsigned int v, bool c) { - if (c) - mvprintw(y,x, ">%s> 0x%08x<", lbl, v); - else - mvprintw(y,x, " %s: 0x%08x ", lbl, v); - } - - void dispreg(int y, int x, const char *n, unsigned int v, bool c) { - // 4,4,8,1 = 17 of 20, +3 = 19 - if (c) - mvprintw(y, x, ">%s> 0x%08x<", n, v); - else - mvprintw(y, x, " %s: 0x%08x ", n, v); - } - - void dbgreg(FILE *fp, int id, const char *n, unsigned int v) { - /* - if ((id == 14)||(id == 14+16)) { - //char buf[64]; - //fprintf(fp, " %s:", - fprintf(fp, " %s: 0x%08x ", n, v); - } else - */ - fprintf(fp, " %s: 0x%08x ", n, v); - } - - void showreg(int y, int x, const char *n, int r, bool c) { - if (r < 16) - dispreg(y, x, n, m_state.m_sR[r], c); - else - dispreg(y, x, n, m_state.m_uR[r-16], c); - move(y,x+17); - -#ifdef OPT_PIPELINED - addch( ((r == (int)(dcd_Aid()&0x01f))&&(dcd_valid()) - &&(m_core->v__DOT__thecpu__DOT__dcd_rA)) - ?'a':((c)?'<':' ')); - addch( ((r == (int)(dcd_Bid()&0x01f))&&(dcd_valid()) - &&(m_core->v__DOT__thecpu__DOT__dcd_rB)) - ?'b':' '); - addch( ((r == m_core->v__DOT__thecpu__DOT__wr_reg_id) - &&(m_core->v__DOT__thecpu__DOT__wr_reg_ce)) - ?'W':' '); -#else - addch( ((r == m_core->v__DOT__thecpu__DOT__wr_reg_id) - &&(m_core->v__DOT__thecpu__DOT__wr_reg_ce)) - ?'W':((c)?'<':' ')); -#endif - } - - void showins(int y, const char *lbl, const int ce, const int valid, - const int gie, const int stall, const unsigned int pc, - const bool phase) { - char la[80], lb[80]; - - if (ce) - mvprintw(y, 0, "Ck "); - else - mvprintw(y, 0, " "); - if (stall) - printw("Stl "); - else - printw(" "); - printw("%s%c 0x%08x", lbl, (phase)?'/':':', pc); - - if (valid) { - if (gie) attroff(A_BOLD); - else attron(A_BOLD); - zipi_to_double_string(pc, m_mem[pc>>2], la, lb); - if (((m_mem[pc>>2]&0x80000000)==0)||(phase)) - printw(" %-24s", la); - else - printw(" %-24s", lb); - } else { - attroff(A_BOLD); - printw(" (0x%08x)%28s", m_mem[pc>>2],""); - } - attroff(A_BOLD); - } - - void dbgins(const char *lbl, const int ce, const int valid, - const int gie, const int stall, const unsigned int pc, - const bool phase, const bool illegal) { - char la[80], lb[80]; - - if (!m_dbgfp) - return; - - if (ce) - fprintf(m_dbgfp, "%s Ck ", lbl); - else - fprintf(m_dbgfp, "%s ", lbl); - if (stall) - fprintf(m_dbgfp, "Stl "); - else - fprintf(m_dbgfp, " "); - fprintf(m_dbgfp, "0x%08x%s: ", pc, (phase)?"/P":" "); - - if (valid) { - zipi_to_double_string(pc, m_mem[pc>>2], la, lb); - if ((phase)||((m_mem[pc>>2]&0x80000000)==0)) - fprintf(m_dbgfp, " %-24s", la); - else - fprintf(m_dbgfp, " %-24s", lb); - } else { - fprintf(m_dbgfp, " (0x%08x)", m_mem[pc]); - } if (illegal) - fprintf(m_dbgfp, " (Illegal)"); - fprintf(m_dbgfp, "\n"); - } - - void show_state(void) { - int ln= 0; - - read_raw_state_cheating(); - - mvprintw(ln,0, "Peripherals-SS"); ln++; -#ifdef OPT_ILLEGAL_INSTRUCTION - printw(" %s", - // (m_core->v__DOT__thecpu__DOT__pf_illegal)?"PI":" ", - (m_core->v__DOT__thecpu__DOT__dcd_illegal)?"DI":" " - ); -#endif - -#ifdef OPT_EARLY_BRANCHING - printw(" %s", - (m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_early_branch)?"EB":" "); - if (m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_early_branch) - printw(" 0x%08x", m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_branch_pc); - else printw(" %10s", ""); - printw(" %s", - (m_core->v__DOT__thecpu__DOT____Vcellinp__pf____pinNumber3)?"-> P3":" "); -#endif - - showval(ln, 0, "PIC ", m_state.m_p[0], (m_cursor==0)); - showval(ln,20, "WDT ", m_state.m_p[1], (m_cursor==1)); - // showval(ln,40, "CACH", m_core->v__DOT__manualcache__DOT__cache_base, (m_cursor==2)); - - if (!m_show_user_timers) { - showval(ln,40, "WBUS", m_core->v__DOT__watchbus__DOT__r_value, false); - } else { - showval(ln,40, "UBUS", m_core->v__DOT__r_wdbus_data, false); - } - - showval(ln,60, "PIC2", m_state.m_p[3], (m_cursor==3)); - - ln++; - showval(ln, 0, "TMRA", m_state.m_p[4], (m_cursor==4)); - showval(ln,20, "TMRB", m_state.m_p[5], (m_cursor==5)); - showval(ln,40, "TMRC", m_state.m_p[6], (m_cursor==6)); - showval(ln,60, "JIF ", m_state.m_p[7], (m_cursor==7)); - - - if (!m_show_user_timers) { - ln++; - showval(ln, 0, "MTSK", m_state.m_p[12], (m_cursor==8)); - showval(ln,20, "MOST", m_state.m_p[13], (m_cursor==9)); - showval(ln,40, "MPST", m_state.m_p[14], (m_cursor==10)); - showval(ln,60, "MICT", m_state.m_p[15], (m_cursor==11)); - } else { - ln++; - showval(ln, 0, "UTSK", m_state.m_p[ 8], (m_cursor==8)); - showval(ln,20, "UOST", m_state.m_p[ 9], (m_cursor==9)); - showval(ln,40, "UPST", m_state.m_p[10], (m_cursor==10)); - showval(ln,60, "UICT", m_state.m_p[11], (m_cursor==11)); - } - - ln++; - mvprintw(ln, 40, "%s %s", - (m_core->v__DOT__cpu_halt)? "CPU-HALT": " ", - (m_core->v__DOT__cpu_reset)?"CPU-RESET":" "); ln++; - mvprintw(ln, 40, "%s %s %s 0x%02x %s %s", - (m_core->v__DOT__cmd_halt)? "HALT": " ", - (m_core->v__DOT__cmd_reset)?"RESET":" ", - (m_core->v__DOT__cmd_step)? "STEP" :" ", - (m_core->v__DOT__cmd_addr)&0x3f, - (m_core->v__DOT__thecpu__DOT__master_ce)? "*CE*" :"(ce)", - (m_core->v__DOT__cpu_reset)? "*RST*" :"(rst)"); - if (m_core->v__DOT__thecpu__DOT__r_gie) - attroff(A_BOLD); - else - attron(A_BOLD); - mvprintw(ln, 0, "Supervisor Registers"); - ln++; - - showreg(ln, 0, "sR0 ", 0, (m_cursor==12)); - showreg(ln,20, "sR1 ", 1, (m_cursor==13)); - showreg(ln,40, "sR2 ", 2, (m_cursor==14)); - showreg(ln,60, "sR3 ", 3, (m_cursor==15)); ln++; - - showreg(ln, 0, "sR4 ", 4, (m_cursor==16)); - showreg(ln,20, "sR5 ", 5, (m_cursor==17)); - showreg(ln,40, "sR6 ", 6, (m_cursor==18)); - showreg(ln,60, "sR7 ", 7, (m_cursor==19)); ln++; - - showreg(ln, 0, "sR8 ", 8, (m_cursor==20)); - showreg(ln,20, "sR9 ", 9, (m_cursor==21)); - showreg(ln,40, "sR10", 10, (m_cursor==22)); - showreg(ln,60, "sR11", 11, (m_cursor==23)); ln++; - - showreg(ln, 0, "sR12", 12, (m_cursor==24)); - showreg(ln,20, "sSP ", 13, (m_cursor==25)); - - unsigned int cc = m_state.m_sR[14]; - if (false) { - mvprintw(ln,40, "%ssCC : 0x%08x", - (m_cursor==26)?">":" ", cc); - } else { - mvprintw(ln,40, "%ssCC :%s%s%s%s%s%s%s", - (m_cursor==26)?">":" ", - (cc&0x01000)?"FE":"", - (cc&0x00800)?"DE":"", - (cc&0x00400)?"BE":"", - (cc&0x00200)?"TP":"", - (cc&0x00100)?"IL":"", - (cc&0x00080)?"BK":"", - ((m_state.m_gie==0)&&(cc&0x010))?"HLT":""); - mvprintw(ln, 54, "%s%s%s%s", - (cc&8)?"V":" ", - (cc&4)?"N":" ", - (cc&2)?"C":" ", - (cc&1)?"Z":" "); - } - showval(ln,60, "sPC ", m_state.m_sR[15], (m_cursor==27)); - mvprintw(ln,60,"%s", - (m_core->v__DOT__thecpu__DOT__wr_reg_id == 0x0e) - &&(m_core->v__DOT__thecpu__DOT__wr_reg_ce) - ?"V" - :(((m_core->v__DOT__thecpu__DOT__wr_flags_ce) - &&(!m_core->v__DOT__thecpu__DOT__r_alu_gie))?"+" - :" ")); - ln++; - - if (m_core->v__DOT__thecpu__DOT__r_gie) - attron(A_BOLD); - else - attroff(A_BOLD); - mvprintw(ln, 0, "User Registers"); - mvprintw(ln, 42, "DCDR=%02x %s%s", - dcd_R(), - (m_core->v__DOT__thecpu__DOT__dcd_wR)?"W":" ", - (m_core->v__DOT__thecpu__DOT__dcd_wF)?"F":" "); - mvprintw(ln, 62, "OPR =%02x %s%s", - m_core->v__DOT__thecpu__DOT__r_op_R, - (m_core->v__DOT__thecpu__DOT__op_wR)?"W":" ", - (m_core->v__DOT__thecpu__DOT__op_wF)?"F":" "); - ln++; - showreg(ln, 0, "uR0 ", 16, (m_cursor==28)); - showreg(ln,20, "uR1 ", 17, (m_cursor==29)); - showreg(ln,40, "uR2 ", 18, (m_cursor==30)); - showreg(ln,60, "uR3 ", 19, (m_cursor==31)); ln++; - - showreg(ln, 0, "uR4 ", 20, (m_cursor==32)); - showreg(ln,20, "uR5 ", 21, (m_cursor==33)); - showreg(ln,40, "uR6 ", 22, (m_cursor==34)); - showreg(ln,60, "uR7 ", 23, (m_cursor==35)); ln++; - - showreg(ln, 0, "uR8 ", 24, (m_cursor==36)); - showreg(ln,20, "uR9 ", 25, (m_cursor==37)); - showreg(ln,40, "uR10", 26, (m_cursor==38)); - showreg(ln,60, "uR11", 27, (m_cursor==39)); ln++; - - showreg(ln, 0, "uR12", 28, (m_cursor==40)); - showreg(ln,20, "uSP ", 29, (m_cursor==41)); - cc = m_state.m_uR[14]; - if (false) { - mvprintw(ln,40, "%cuCC : 0x%08x", - (m_cursor == 42)?'>':' ', cc); - } else { - mvprintw(ln,40, "%cuCC :%s%s%s%s%s%s%s", - (m_cursor == 42)?'>':' ', - (cc & 0x1000)?"FE":"", - (cc & 0x0800)?"DE":"", - (cc & 0x0400)?"BE":"", - (cc & 0x0200)?"TP":"", - (cc & 0x0100)?"IL":"", - (cc & 0x0040)?"ST":"", - ((m_state.m_gie)&&(cc & 0x010))?"SL":""); - mvprintw(ln, 54, "%s%s%s%s", - (cc&8)?"V":" ", - (cc&4)?"N":" ", - (cc&2)?"C":" ", - (cc&1)?"Z":" "); - } - showval(ln,60, "uPC ", m_state.m_uR[15], (m_cursor==43)); - mvprintw(ln,60,"%s", - (m_core->v__DOT__thecpu__DOT__wr_reg_id == 0x1e) - &&(m_core->v__DOT__thecpu__DOT__wr_reg_ce) - ?"V" - :(((m_core->v__DOT__thecpu__DOT__wr_flags_ce) - &&(m_core->v__DOT__thecpu__DOT__r_alu_gie))?"+" - :" ")); - - attroff(A_BOLD); - ln+=1; - -#ifdef OPT_SINGLE_FETCH - ln++; - mvprintw(ln, 0, "PF BUS: %3s %3s %s @0x%08x[0x%08x] -> %s %s %08x", - (m_core->v__DOT__thecpu__DOT__pf_cyc)?"CYC":" ", - (m_core->v__DOT__thecpu__DOT__pf_stb)?"STB":" ", - " ", // (m_core->v__DOT__thecpu__DOT__pf_we )?"WE":" ", - (m_core->v__DOT__thecpu__DOT__pf_addr<<2), - 0, // (m_core->v__DOT__thecpu__DOT__pf_data), - (m_core->v__DOT__thecpu__DOT__pf_ack)?"ACK":" ", - " ",//(m_core->v__DOT__thecpu__DOT__pf_stall)?"STL":" ", - (m_core->v__DOT__wb_data)); ln++; -#else - - mvprintw(ln, 0, "PFCACH: v=%08x, %s%s, tag=%08x, pf_pc=%08x, lastpc=%08x", - m_core->v__DOT__thecpu__DOT__pf__DOT__vmask, - (m_core->v__DOT__thecpu__DOT__pf__DOT__r_v)?"V":" ", - (m_core->v__DOT__thecpu__DOT__pf_illegal)?"I":" ", - (m_core->v__DOT__thecpu__DOT__pf__DOT__tagsrc) - ?(m_core->v__DOT__thecpu__DOT__pf__DOT__tagvalipc) - :(m_core->v__DOT__thecpu__DOT__pf__DOT__tagvallst), - m_core->v__DOT__thecpu__DOT__pf_pc, - m_core->v__DOT__thecpu__DOT__pf__DOT__lastpc); - - ln++; - mvprintw(ln, 0, "PF BUS: %3s %3s %s @0x%08x[0x%08x] -> %s %s %08x", - (m_core->v__DOT__thecpu__DOT__pf_cyc)?"CYC":" ", - (m_core->v__DOT__thecpu__DOT__pf_stb)?"STB":" ", - " ", // (m_core->v__DOT__thecpu__DOT__pf_we )?"WE":" ", - (m_core->v__DOT__thecpu__DOT__pf_addr<<2), - 0, // (m_core->v__DOT__thecpu__DOT__pf_data), - (m_core->v__DOT__thecpu__DOT__pf_ack)?"ACK":" ", - (pfstall())?"STL":" ", - (m_core->v__DOT__wb_data)); ln++; -#endif - - mvprintw(ln, 0, "MEMBUS: %3s %3s %s @0x%08x[0x%08x] -> %s %s %08x", - (m_core->v__DOT__thecpu__DOT__domem__DOT__r_wb_cyc_gbl)?"GCY" - :((m_core->v__DOT__thecpu__DOT__domem__DOT__r_wb_cyc_lcl)?"LCY":" "), - (m_core->v__DOT__thecpu__DOT__mem_stb_gbl)?"GSB" - :((m_core->v__DOT__thecpu__DOT__mem_stb_lcl)?"LSB":" "), - (m_core->v__DOT__thecpu__DOT__mem_we )?"WE":" ", - (m_core->v__DOT__thecpu__DOT__mem_addr<<2), - (m_core->v__DOT__thecpu__DOT__mem_data), - (m_core->v__DOT__thecpu__DOT__mem_ack)?"ACK":" ", - (m_core->v__DOT__thecpu__DOT__mem_stall)?"STL":" ", - (m_core->v__DOT__thecpu__DOT__mem_result)); -// #define OPT_PIPELINED_BUS_ACCESS -#ifdef OPT_PIPELINED_BUS_ACCESS - printw(" %x%x%c%c", - (m_core->v__DOT__thecpu__DOT__domem__DOT__wraddr), - (m_core->v__DOT__thecpu__DOT__domem__DOT__rdaddr), - (m_core->v__DOT__thecpu__DOT__r_op_pipe)?'P':'-', - (mem_pipe_stalled())?'S':'-'); ln++; -#else - ln++; -#endif - - mvprintw(ln, 0, "SYSBS%c: %3s %3s %s @0x%08x[0x%08x] -> %s %s %08x %s", - (m_core->v__DOT__thecpu__DOT__pformem__DOT__r_a_owner)?'M':'P', - (m_core->o_wb_cyc)?"CYC":" ", - (m_core->o_wb_stb)?"STB":" ", - (m_core->o_wb_we )?"WE":" ", - (m_core->o_wb_addr<<2), - (m_core->o_wb_data), - (m_core->i_wb_ack)?"ACK":" ", - (m_core->i_wb_stall)?"STL":" ", - (m_core->i_wb_data), - (m_core->i_wb_err)?"(ER!)":" "); ln+=2; -#ifdef OPT_PIPELINED_BUS_ACCESS - mvprintw(ln-1, 0, "Mem CE: %d = %d%d%d%d%d, stall: %d = %d%d(%d|%d%d|..)", - (m_core->v__DOT__thecpu__DOT__mem_ce), - (m_core->v__DOT__thecpu__DOT__master_ce), //1 - (m_core->v__DOT__thecpu__DOT__op_valid_mem), //0 - (!m_core->v__DOT__thecpu__DOT__new_pc), //1 - // (!m_core->v__DOT__thecpu__DOT__clear_pipeline), //1 - (m_core->v__DOT__thecpu__DOT__set_cond), //1 - (!mem_stalled()), //1 - - (mem_stalled()), - (m_core->v__DOT__thecpu__DOT__op_valid_mem), - (m_core->v__DOT__thecpu__DOT__master_ce), - (mem_pipe_stalled()), - (!m_core->v__DOT__thecpu__DOT__r_op_pipe), - (m_core->v__DOT__thecpu__DOT__domem__DOT__cyc) - ); - printw(" op_pipe = %d", m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__r_pipe); - // mvprintw(4,4,"r_dcdI = 0x%06x", - // (m_core->v__DOT__thecpu__DOT__dcdI)&0x0ffffff); -#endif - mvprintw(4,42,"0x%08x", m_core->v__DOT__thecpu__DOT__pf_instruction); -#ifdef OPT_SINGLE_CYCLE - printw(" A:%c%c B:%c%c", - (m_core->v__DOT__thecpu__DOT__op_A_alu)?'A':'-', - (m_core->v__DOT__thecpu__DOT__op_A_mem)?'M':'-', - (m_core->v__DOT__thecpu__DOT__op_B_alu)?'A':'-', - (m_core->v__DOT__thecpu__DOT__op_B_mem)?'M':'-'); -#else - printw(" A:xx B:xx"); -#endif - printw(" PFPC=%08x", m_core->v__DOT__thecpu__DOT__pf_pc); - - - showins(ln, "I ", -#ifdef OPT_PIPELINED - !m_core->v__DOT__thecpu__DOT__dcd_stalled, -#else - 1, -#endif - m_core->v__DOT__thecpu__DOT__pf_valid, - //m_core->v__DOT__thecpu__DOT__instruction_gie, - m_core->v__DOT__thecpu__DOT__r_gie, - 0, - (m_core->v__DOT__thecpu__DOT__pf_instruction_pc)<<2, - false); ln++; - // m_core->v__DOT__thecpu__DOT__pf_pc); ln++; - - showins(ln, "Dc", - dcd_ce(), dcd_valid(), - m_core->v__DOT__thecpu__DOT__dcd_gie, -#ifdef OPT_PIPELINED - m_core->v__DOT__thecpu__DOT__dcd_stalled, -#else - 0, -#endif - (m_core->v__DOT__thecpu__DOT__dcd_pc-1)<<2, -#ifdef OPT_CIS - m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__r_phase -#else - false -#endif - ); ln++; -#ifdef OPT_ILLEGAL_INSTRUCTION - if (m_core->v__DOT__thecpu__DOT__dcd_illegal) - mvprintw(ln-1,10,"I"); - else -#endif - if (m_core->v__DOT__thecpu__DOT__dcd_M) - mvprintw(ln-1,10,"M"); - - showins(ln, "Op", - op_ce(), - m_core->v__DOT__thecpu__DOT__op_valid, - m_core->v__DOT__thecpu__DOT__r_op_gie, - m_core->v__DOT__thecpu__DOT__op_stall, - op_pc(), -#ifdef OPT_CIS - m_core->v__DOT__thecpu__DOT__r_op_phase -#else - false -#endif - ); ln++; -#ifdef OPT_ILLEGAL_INSTRUCTION - if (m_core->v__DOT__thecpu__DOT__op_illegal) - mvprintw(ln-1,10,"I"); - else -#endif - if (m_core->v__DOT__thecpu__DOT__op_valid_mem) - mvprintw(ln-1,10,"M"); - else if (m_core->v__DOT__thecpu__DOT__op_valid_alu) - mvprintw(ln-1,10,"A"); - - if (m_core->v__DOT__thecpu__DOT__op_valid_mem) { - showins(ln, "Mm", - m_core->v__DOT__thecpu__DOT__mem_ce, - m_core->v__DOT__thecpu__DOT__mem_pc_valid, - m_core->v__DOT__thecpu__DOT__r_alu_gie, -#ifdef OPT_PIPELINED - m_core->v__DOT__thecpu__DOT__mem_stall, -#else - 0, -#endif - alu_pc(), -#ifdef OPT_CIS - m_core->v__DOT__thecpu__DOT__r_alu_phase -#else - false -#endif - ); - } else { - showins(ln, "Al", - m_core->v__DOT__thecpu__DOT__alu_ce, - m_core->v__DOT__thecpu__DOT__alu_pc_valid, - m_core->v__DOT__thecpu__DOT__r_alu_gie, -#ifdef OPT_PIPELINED - m_core->v__DOT__thecpu__DOT__alu_stall, -#else - 0, -#endif - alu_pc(), -#ifdef OPT_CIS - m_core->v__DOT__thecpu__DOT__r_alu_phase -#else - false -#endif - ); - } ln++; - if (m_core->v__DOT__thecpu__DOT__wr_reg_ce) - mvprintw(ln-1,10,"W"); - else if (m_core->v__DOT__thecpu__DOT__alu_valid) - mvprintw(ln-1,10,(m_core->v__DOT__thecpu__DOT__alu_wR)?"w":"V"); - else if (m_core->v__DOT__thecpu__DOT__mem_valid) - mvprintw(ln-1,10,"v"); -#ifdef OPT_ILLEGAL_INSTRUCTION - else if (m_core->v__DOT__thecpu__DOT__r_alu_illegal) - mvprintw(ln-1,10,"I"); -#endif - // else if (m_core->v__DOT__thecpu__DOT__alu_illegal_op) - // mvprintw(ln-1,10,"i"); - - mvprintw(ln-5, 65,"%s %s", - (m_core->v__DOT__thecpu__DOT__r_op_break)?"OB":" ", - (m_core->v__DOT__thecpu__DOT__new_pc)?"CLRP":" "); - mvprintw(ln-4, 48, - (m_core->v__DOT__thecpu__DOT__new_pc)?"new-pc":" "); - printw("(%s:%02x,%x)", - (m_core->v__DOT__thecpu__DOT__set_cond)?"SET":" ", - (m_core->v__DOT__thecpu__DOT__op_F&0x0ff), - (m_core->v__DOT__thecpu__DOT__r_op_gie) - ? (m_core->v__DOT__thecpu__DOT__w_uflags) - : (m_core->v__DOT__thecpu__DOT__w_iflags)); - - printw("(%s%s%s:%02x)", - (m_core->v__DOT__thecpu__DOT__op_wF)?"OF":" ", - (m_core->v__DOT__thecpu__DOT__alu_wF)?"FL":" ", - (m_core->v__DOT__thecpu__DOT__wr_flags_ce)?"W":" ", - (m_core->v__DOT__thecpu__DOT__alu_flags)); - mvprintw(ln-3, 48, "Op(%x)%8x,%8x->", - m_core->v__DOT__thecpu__DOT__r_op_opn, - m_core->v__DOT__thecpu__DOT__op_Aid, - m_core->v__DOT__thecpu__DOT__op_Bid); - if (m_core->v__DOT__thecpu__DOT__alu_valid) - printw("%08x", m_core->v__DOT__thecpu__DOT__alu_result); - else - printw("%8s",""); - mvprintw(ln-1, 48, "%s%s%s ", - (m_core->v__DOT__thecpu__DOT__alu_valid)?"A" - :((m_core->v__DOT__thecpu__DOT__doalu__DOT__r_busy)?"a":" "), - (m_core->v__DOT__thecpu__DOT__div_valid)?"D" - :((m_core->v__DOT__thecpu__DOT__div_busy)?"d":" "), - (m_core->v__DOT__thecpu__DOT__div_valid)?"F" - :((m_core->v__DOT__thecpu__DOT__div_busy)?"f":" ")); - printw("MEM: %s%s %s%s %s %-5s", - (m_core->v__DOT__thecpu__DOT__op_valid_mem)?"M":" ", - (m_core->v__DOT__thecpu__DOT__mem_ce)?"CE":" ", - (m_core->v__DOT__thecpu__DOT__mem_we)?"Wr ":"Rd ", - (mem_stalled())?"PIPE":" ", - (m_core->v__DOT__thecpu__DOT__mem_valid)?"V":" ", - zip_regstr[(m_core->v__DOT__thecpu__DOT__mem_wreg&0x1f)^0x10]); - } - - void show_user_timers(bool v) { - m_show_user_timers = v; - } - - unsigned int cmd_read(unsigned int a) { - int errcount = 0; - if (m_dbgfp) { - dbg_flag= true; - fprintf(m_dbgfp, "CMD-READ(%d)\n", a); - } - wb_write(CMD_REG, CMD_HALT|(a&0x3f)); - while(((wb_read(CMD_REG) & CMD_STALL) == 0)&&(errcount= MAXERR) { - endwin(); - - printf("ERR: errcount >= MAXERR on wb_read(a=%x)\n", a); - // printf("Clear-Pipeline = %d\n", m_core->v__DOT__thecpu__DOT__clear_pipeline); - printf("cpu-dbg-stall = %d\n", m_core->v__DOT__thecpu__DOT__r_halted); - printf("pf_cyc = %d\n", m_core->v__DOT__thecpu__DOT__pf_cyc); - printf("mem_cyc_gbl = %d\n", (m_core->v__DOT__thecpu__DOT__domem__DOT__r_wb_cyc_gbl)); - printf("mem_cyc_lcl = %d\n", m_core->v__DOT__thecpu__DOT__domem__DOT__r_wb_cyc_lcl); - printf("op_valid = %d\n", m_core->v__DOT__thecpu__DOT__op_valid); - printf("dcd_valid = %d\n", dcd_valid()?1:0); - printf("dcd_ce = %d\n", dcd_ce()?1:0); -#ifdef OPT_PIPELINED - printf("dcd_stalled = %d\n", m_core->v__DOT__thecpu__DOT__dcd_stalled); -#endif - printf("pf_valid = %d\n", m_core->v__DOT__thecpu__DOT__pf_valid); -// #ifdef OPT_EARLY_BRANCHING - // printf("dcd_early_branch=%d\n", m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__genblk1__DOT__r_early_branch); -// #endif - - exit(-2); - } - - assert(errcount < MAXERR); - unsigned int v = wb_read(CMD_DATA); - - if (dbg_flag) - fprintf(m_dbgfp, "CMD-READ(%d) = 0x%08x\n", a, v); - dbg_flag = false; - return v; - } - - void cmd_write(unsigned int a, int v) { - int errcount = 0; - if ((a&0x0f)==0x0f) - dbg_flag = true; - wb_write(CMD_REG, CMD_HALT|(a&0x3f)); - while(((wb_read(CMD_REG) & CMD_STALL) == 0)&&(errcount < MAXERR)) - errcount++; - assert(errcount < MAXERR); - if (dbg_flag) - fprintf(m_dbgfp, "CMD-WRITE(%d) <= 0x%08x\n", a, v); - wb_write(CMD_DATA, v); - } - - bool halted(void) { - return (m_core->v__DOT__cmd_halt != 0); - } - - void read_state(void) { - int ln= 0; - bool gie; - - read_raw_state(); - if (m_cursor < 0) - m_cursor = 0; - else if (m_cursor >= 44) - m_cursor = 43; - - mvprintw(ln,0, "Peripherals-RS"); - mvprintw(ln,40,"%-40s", "CPU State: "); - { - unsigned int v = wb_read(CMD_REG); - mvprintw(ln,51, ""); - if (v & 0x010000) - printw("EXT-INT "); - if ((v & 0x003000) == 0x03000) - printw("Halted "); - else if (v & 0x001000) - printw("Sleeping "); - else if (v & 0x002000) - printw("User Mod "); - if (v & 0x008000) - printw("Break-Enabled "); - if (v & 0x000080) - printw("PIC Enabled "); - } ln++; - showval(ln, 0, "PIC ", m_state.m_p[0], (m_cursor==0)); - showval(ln,20, "WDT ", m_state.m_p[1], (m_cursor==1)); - showval(ln,40, "WBUS", m_state.m_p[2], false); - showval(ln,60, "PIC2", m_state.m_p[3], (m_cursor==3)); - ln++; - showval(ln, 0, "TMRA", m_state.m_p[4], (m_cursor==4)); - showval(ln,20, "TMRB", m_state.m_p[5], (m_cursor==5)); - showval(ln,40, "TMRC", m_state.m_p[6], (m_cursor==6)); - showval(ln,60, "JIF ", m_state.m_p[7], (m_cursor==7)); - - ln++; - if (!m_show_user_timers) { - showval(ln, 0, "MTSK", m_state.m_p[12], (m_cursor==8)); - showval(ln,20, "MMST", m_state.m_p[13], (m_cursor==9)); - showval(ln,40, "MPST", m_state.m_p[14], (m_cursor==10)); - showval(ln,60, "MICT", m_state.m_p[15], (m_cursor==11)); - } else { - showval(ln, 0, "UTSK", m_state.m_p[ 8], (m_cursor==8)); - showval(ln,20, "UMST", m_state.m_p[ 9], (m_cursor==9)); - showval(ln,40, "UPST", m_state.m_p[10], (m_cursor==10)); - showval(ln,60, "UICT", m_state.m_p[11], (m_cursor==11)); - } - - ln++; - ln++; - unsigned int cc = m_state.m_sR[14]; - if (m_dbgfp) fprintf(m_dbgfp, "CC = %08x, gie = %d\n", cc, - m_core->v__DOT__thecpu__DOT__r_gie); - gie = (cc & 0x020); - if (gie) - attroff(A_BOLD); - else - attron(A_BOLD); - mvprintw(ln, 0, "Supervisor Registers"); - ln++; - - dispreg(ln, 0, "sR0 ", m_state.m_sR[ 0], (m_cursor==12)); - dispreg(ln,20, "sR1 ", m_state.m_sR[ 1], (m_cursor==13)); - dispreg(ln,40, "sR2 ", m_state.m_sR[ 2], (m_cursor==14)); - dispreg(ln,60, "sR3 ", m_state.m_sR[ 3], (m_cursor==15)); ln++; - - dispreg(ln, 0, "sR4 ", m_state.m_sR[ 4], (m_cursor==16)); - dispreg(ln,20, "sR5 ", m_state.m_sR[ 5], (m_cursor==17)); - dispreg(ln,40, "sR6 ", m_state.m_sR[ 6], (m_cursor==18)); - dispreg(ln,60, "sR7 ", m_state.m_sR[ 7], (m_cursor==19)); ln++; - - dispreg(ln, 0, "sR8 ", m_state.m_sR[ 8], (m_cursor==20)); - dispreg(ln,20, "sR9 ", m_state.m_sR[ 9], (m_cursor==21)); - dispreg(ln,40, "sR10", m_state.m_sR[10], (m_cursor==22)); - dispreg(ln,60, "sR11", m_state.m_sR[11], (m_cursor==23)); ln++; - - dispreg(ln, 0, "sR12", m_state.m_sR[12], (m_cursor==24)); - dispreg(ln,20, "sSP ", m_state.m_sR[13], (m_cursor==25)); - - if (true) { - mvprintw(ln,40, "%ssCC : 0x%08x", - (m_cursor==26)?">":" ", cc); - } else { - mvprintw(ln,40, "%ssCC :%s%s%s%s%s%s%s", - (m_cursor==26)?">":" ", - (cc&0x01000)?"FE":"", - (cc&0x00800)?"DE":"", - (cc&0x00400)?"BE":"", - (cc&0x00200)?"TP":"", - (cc&0x00100)?"IL":"", - (cc&0x00080)?"BK":"", - ((m_state.m_gie==0)&&(cc&0x010))?"HLT":""); - mvprintw(ln, 54, "%s%s%s%s", - (cc&8)?"V":" ", - (cc&4)?"N":" ", - (cc&2)?"C":" ", - (cc&1)?"Z":" "); - } - dispreg(ln,60, "sPC ", cmd_read(15), (m_cursor==27)); - ln++; - - if (gie) - attron(A_BOLD); - else - attroff(A_BOLD); - mvprintw(ln, 0, "User Registers"); - mvprintw(ln, 42, "DCDR=%02x %s", - dcd_R(), (m_core->v__DOT__thecpu__DOT__dcd_wR)?"W":" "); - mvprintw(ln, 62, "OPR =%02x %s%s", - m_core->v__DOT__thecpu__DOT__r_op_R, - (m_core->v__DOT__thecpu__DOT__op_wR)?"W":" ", - (m_core->v__DOT__thecpu__DOT__op_wF)?"F":" "); - ln++; - dispreg(ln, 0, "uR0 ", m_state.m_uR[ 0], (m_cursor==28)); - dispreg(ln,20, "uR1 ", m_state.m_uR[ 1], (m_cursor==29)); - dispreg(ln,40, "uR2 ", m_state.m_uR[ 2], (m_cursor==30)); - dispreg(ln,60, "uR3 ", m_state.m_uR[ 3], (m_cursor==31)); ln++; - - dispreg(ln, 0, "uR4 ", m_state.m_uR[ 4], (m_cursor==32)); - dispreg(ln,20, "uR5 ", m_state.m_uR[ 5], (m_cursor==33)); - dispreg(ln,40, "uR6 ", m_state.m_uR[ 6], (m_cursor==34)); - dispreg(ln,60, "uR7 ", m_state.m_uR[ 7], (m_cursor==35)); ln++; - - dispreg(ln, 0, "uR8 ", m_state.m_uR[ 8], (m_cursor==36)); - dispreg(ln,20, "uR9 ", m_state.m_uR[ 9], (m_cursor==37)); - dispreg(ln,40, "uR10", m_state.m_uR[10], (m_cursor==38)); - dispreg(ln,60, "uR11", m_state.m_uR[11], (m_cursor==39)); ln++; - - dispreg(ln, 0, "uR12", m_state.m_uR[12], (m_cursor==40)); - dispreg(ln,20, "uSP ", m_state.m_uR[13], (m_cursor==41)); - cc = m_state.m_uR[14]; - if (false) { - mvprintw(ln,40, "%cuCC : 0x%08x", - (m_cursor == 42)?'>':' ', cc); - } else { - mvprintw(ln,40, "%cuCC :%s%s%s%s%s%s%s", - (m_cursor == 42)?'>':' ', - (cc & 0x1000)?"FE":"", - (cc & 0x0800)?"DE":"", - (cc & 0x0400)?"BE":"", - (cc & 0x0200)?"TP":"", - (cc & 0x0100)?"IL":"", - (cc & 0x0040)?"ST":"", - ((m_state.m_gie)&&(cc & 0x010))?"SL":""); - mvprintw(ln, 54, "%s%s%s%s", - (cc&8)?"V":" ", - (cc&4)?"N":" ", - (cc&2)?"C":" ", - (cc&1)?"Z":" "); - } - dispreg(ln,60, "uPC ", m_state.m_uR[15], (m_cursor==43)); - - attroff(A_BOLD); - ln+=2; - - ln+=3; - - showins(ln, "I ", -#ifdef OPT_PIPELINED - !m_core->v__DOT__thecpu__DOT__dcd_stalled, -#else - 1, -#endif - m_core->v__DOT__thecpu__DOT__pf_valid, - m_core->v__DOT__thecpu__DOT__r_gie, - 0, - m_core->v__DOT__thecpu__DOT__pf_instruction_pc, - true); ln++; - // m_core->v__DOT__thecpu__DOT__pf_pc); ln++; - - showins(ln, "Dc", - dcd_ce(), dcd_valid(), - m_core->v__DOT__thecpu__DOT__dcd_gie, -#ifdef OPT_PIPELINED - m_core->v__DOT__thecpu__DOT__dcd_stalled, -#else - 0, -#endif - m_core->v__DOT__thecpu__DOT__dcd_pc-1, -#ifdef OPT_CIS - m_core->v__DOT__thecpu__DOT__dcd_phase -#else - false -#endif - ); ln++; - - showins(ln, "Op", - op_ce(), - m_core->v__DOT__thecpu__DOT__op_valid, - m_core->v__DOT__thecpu__DOT__r_op_gie, - m_core->v__DOT__thecpu__DOT__op_stall, - op_pc(), -#ifdef OPT_CIS - m_core->v__DOT__thecpu__DOT__r_op_phase -#else - false -#endif - ); ln++; - - if (m_core->v__DOT__thecpu__DOT__op_valid_mem) { - showins(ln, "Mm", - m_core->v__DOT__thecpu__DOT__mem_ce, - m_core->v__DOT__thecpu__DOT__mem_pc_valid, - m_core->v__DOT__thecpu__DOT__r_alu_gie, -#ifdef OPT_PIPELINED - m_core->v__DOT__thecpu__DOT__mem_stall, -#else - 0, -#endif - alu_pc(), -#ifdef OPT_CIS - m_core->v__DOT__thecpu__DOT__r_alu_phase -#else - false -#endif - ); - } else { - showins(ln, "Al", - m_core->v__DOT__thecpu__DOT__alu_ce, - m_core->v__DOT__thecpu__DOT__alu_pc_valid, - m_core->v__DOT__thecpu__DOT__r_alu_gie, -#ifdef OPT_PIPELINED - m_core->v__DOT__thecpu__DOT__alu_stall, -#else - 0, -#endif - alu_pc(), -#ifdef OPT_CIS - m_core->v__DOT__thecpu__DOT__r_alu_phase -#else - false -#endif - ); - } ln++; - } - - void tick(void) { - int gie = m_core->v__DOT__thecpu__DOT__r_gie; - /* - m_core->i_qspi_dat = m_flash(m_core->o_qspi_cs_n, - m_core->o_qspi_sck, - m_core->o_qspi_dat); - */ - - int stb = m_core->o_wb_stb, mask = (RAMBASE-1); - unsigned addr = m_core->o_wb_addr<<2; - - m_core->i_wb_err = 0; - if ((addr & (~mask))!=RAMBASE) - stb = 0; - if ((m_core->o_wb_cyc)&&(m_core->o_wb_stb)&&(!stb)) { - m_core->i_wb_ack = 1; - m_core->i_wb_err = 1; - m_bomb = true; - if (m_dbgfp) fprintf(m_dbgfp, - "BOMB!! (Attempting to access %08x/%08x->%08x)\n", - addr, RAMBASE, ((addr)&(~mask))); - } else if ((!m_core->o_wb_cyc)&&(m_core->o_wb_stb)) { - if (m_dbgfp) fprintf(m_dbgfp, - "BOMB!! (Strobe high, CYC low)\n"); - m_bomb = true; - } - - if ((dbg_flag)&&(m_dbgfp)) { - fprintf(m_dbgfp, "BUS %s %s %s @0x%08x/[0x%08x 0x%08x] %s %s\n", - (m_core->o_wb_cyc)?"CYC":" ", - (m_core->o_wb_stb)?"STB":" ", - (m_core->o_wb_we)?"WE":" ", - (m_core->o_wb_addr<<2), - (m_core->o_wb_data), - (m_core->i_wb_data), - (m_core->i_wb_stall)?"STALL":" ", - (m_core->i_wb_ack)?"ACK":" "); - fprintf(m_dbgfp, "DBG %s %s %s @0x%08x/%d[0x%08x] %s %s [0x%08x] %s %s %s%s%s%s%s%s%s%s%s\n", - (m_core->i_dbg_cyc)?"CYC":" ", - (m_core->i_dbg_stb)?"STB": - ((m_core->v__DOT__dbg_stb)?"DBG":" "), - ((m_core->i_dbg_we)?"WE":" "), - (m_core->i_dbg_addr),0, - m_core->i_dbg_data, - (m_core->o_dbg_ack)?"ACK":" ", - (m_core->o_dbg_stall)?"STALL":" ", - (m_core->o_dbg_data), - (m_core->v__DOT__cpu_halt)?"CPU-HALT ":"", - (m_core->v__DOT__thecpu__DOT__r_halted)?"CPU-DBG_STALL":"", - (dcd_valid())?"DCDV ":"", - (m_core->v__DOT__thecpu__DOT__op_valid)?"OPV ":"", - (m_core->v__DOT__thecpu__DOT__pf_cyc)?"PCYC ":"", - (m_core->v__DOT__thecpu__DOT__domem__DOT__r_wb_cyc_gbl)?"GC":" ", - (m_core->v__DOT__thecpu__DOT__domem__DOT__r_wb_cyc_lcl)?"LC":" ", - (m_core->v__DOT__thecpu__DOT__alu_wR)?"ALUW ":"", - (m_core->v__DOT__thecpu__DOT__alu_ce)?"ALCE ":"", - (m_core->v__DOT__thecpu__DOT__alu_valid)?"ALUV ":"", - (m_core->v__DOT__thecpu__DOT__mem_valid)?"MEMV ":""); - fprintf(m_dbgfp, " SYS %s %s %s @0x%08x/%d[0x%08x] %s [0x%08x]\n", - (m_core->v__DOT__sys_cyc)?"CYC":" ", - (m_core->v__DOT__sys_stb)?"STB":" ", - (m_core->v__DOT__sys_we)?"WE":" ", - (m_core->v__DOT__sys_addr<<2), - (m_core->v__DOT__dbg_addr<<2), - (m_core->v__DOT__sys_data), - (m_core->v__DOT__dbg_ack)?"ACK":" ", - (m_core->v__DOT__wb_data)); - } - - if (m_dbgfp) - fprintf(m_dbgfp, "CEs %d/0x%08x,%d/0x%08x DCD: ->%02x, OP: ->%02x, ALU: halt=%d,%d ce=%d, valid=%d, wr=%d Reg=%02x, IPC=%08x, UPC=%08x\n", - dcd_ce(), - m_core->v__DOT__thecpu__DOT__dcd_pc, - op_ce(), - op_pc(), - dcd_Aid()&0x01f, - m_core->v__DOT__thecpu__DOT__r_op_R, - m_core->v__DOT__cmd_halt, - m_core->v__DOT__cpu_halt, - m_core->v__DOT__thecpu__DOT__alu_ce, - m_core->v__DOT__thecpu__DOT__alu_valid, - m_core->v__DOT__thecpu__DOT__alu_wR, - m_core->v__DOT__thecpu__DOT__alu_reg, - m_core->v__DOT__thecpu__DOT__ipc, - m_core->v__DOT__thecpu__DOT__r_upc); - - if ((m_dbgfp)&&(!gie)&&(m_core->v__DOT__thecpu__DOT__w_release_from_interrupt)) { - fprintf(m_dbgfp, "RELEASE: int=%d, %d/%02x[%08x] ?/%02x[0x%08x], ce=%d %d,%d,%d\n", - m_core->v__DOT__genblk9__DOT__pic__DOT__r_interrupt, - m_core->v__DOT__thecpu__DOT__wr_reg_ce, - m_core->v__DOT__thecpu__DOT__wr_reg_id, - m_core->v__DOT__thecpu__DOT__wr_spreg_vl, - m_core->v__DOT__cmd_addr<<2, - m_core->v__DOT__dbg_idata, - m_core->v__DOT__thecpu__DOT__master_ce, - m_core->v__DOT__thecpu__DOT__alu_wR, - m_core->v__DOT__thecpu__DOT__alu_valid, - m_core->v__DOT__thecpu__DOT__mem_valid); - } else if ((m_dbgfp)&&(gie)&&(m_core->v__DOT__thecpu__DOT__w_switch_to_interrupt)) { - fprintf(m_dbgfp, "SWITCH: %d/%02x[%08x] ?/%02x[0x%08x], ce=%d %d,%d,%d, F%02x,%02x\n", - m_core->v__DOT__thecpu__DOT__wr_reg_ce, - m_core->v__DOT__thecpu__DOT__wr_reg_id, - m_core->v__DOT__thecpu__DOT__wr_spreg_vl, - m_core->v__DOT__cmd_addr<<2, - m_core->v__DOT__dbg_idata, - m_core->v__DOT__thecpu__DOT__master_ce, - m_core->v__DOT__thecpu__DOT__alu_wR, - m_core->v__DOT__thecpu__DOT__alu_valid, - m_core->v__DOT__thecpu__DOT__mem_valid, - m_core->v__DOT__thecpu__DOT__w_iflags, - m_core->v__DOT__thecpu__DOT__w_uflags); - fprintf(m_dbgfp, "\tbrk=%s %d,%d\n", - (m_core->v__DOT__thecpu__DOT__master_ce)?"CE":" ", - m_core->v__DOT__thecpu__DOT__break_en, - m_core->v__DOT__thecpu__DOT__r_op_break); - } else if ((m_dbgfp)&& - ((m_core->v__DOT__thecpu__DOT__r_op_break) - ||(m_core->v__DOT__thecpu__DOT__r_alu_illegal) - ||(m_core->v__DOT__thecpu__DOT__dcd_break))) { - fprintf(m_dbgfp, "NOT SWITCHING TO GIE (gie = %d)\n", gie); - fprintf(m_dbgfp, "\tbrk=%s breaken=%d,dcdbreak=%d,opbreak=%d,alu_illegal=%d\n", - (m_core->v__DOT__thecpu__DOT__master_ce)?"CE":" ", - m_core->v__DOT__thecpu__DOT__break_en, - m_core->v__DOT__thecpu__DOT__dcd_break, - m_core->v__DOT__thecpu__DOT__r_op_break, - m_core->v__DOT__thecpu__DOT__r_alu_illegal); - } - - if (m_dbgfp) { - // if(m_core->v__DOT__thecpu__DOT__clear_pipeline) - // fprintf(m_dbgfp, "\tClear Pipeline\n"); - if(m_core->v__DOT__thecpu__DOT__new_pc) - fprintf(m_dbgfp, "\tNew PC\n"); - } - - if (m_dbgfp) - fprintf(m_dbgfp, "----------- TICK (%08x) ----------%s\n", - m_core->v__DOT__jiffies__DOT__r_counter, - (m_bomb)?" BOMBED!!":""); - m_mem(m_core->o_wb_cyc, m_core->o_wb_stb, m_core->o_wb_we, - m_core->o_wb_addr & mask, m_core->o_wb_data, m_core->o_wb_sel & 0x0f, - m_core->i_wb_ack, m_core->i_wb_stall,m_core->i_wb_data); - - - TESTB::tick(); - - if ((m_dbgfp)&&(gie != m_core->v__DOT__thecpu__DOT__r_gie)) { - fprintf(m_dbgfp, "SWITCH FROM %s to %s: sPC = 0x%08x uPC = 0x%08x pf_pc = 0x%08x\n", - (gie)?"User":"Supervisor", - (gie)?"Supervisor":"User", - m_core->v__DOT__thecpu__DOT__ipc, - m_core->v__DOT__thecpu__DOT__r_upc, - m_core->v__DOT__thecpu__DOT__pf_pc); - } if (m_dbgfp) { -#ifdef OPT_TRADITIONAL_PFCACHE - fprintf(m_dbgfp, "PFCACHE %s(%08x,%08x%s),%08x - %08x %s%s%s\n", - (m_core->v__DOT__thecpu__DOT__new_pc)?"N":" ", - m_core->v__DOT__thecpu__DOT__pf_pc, - m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_branch_pc, - ((m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__genblk3__DOT__r_early_branch) - &&(dcd_valid()) - &&(!m_core->v__DOT__thecpu__DOT__new_pc))?"V":"-", - m_core->v__DOT__thecpu__DOT__pf__DOT__lastpc, - m_core->v__DOT__thecpu__DOT__pf_instruction_pc, - (m_core->v__DOT__thecpu__DOT__pf__DOT__r_v)?"R":" ", - (m_core->v__DOT__thecpu__DOT__pf_valid)?"V":" ", - (m_core->v__DOT__thecpu__DOT__pf_illegal)?"I":" "); -#endif - dbgins("Dc - ", - dcd_ce(), dcd_valid(), - m_core->v__DOT__thecpu__DOT__dcd_gie, -#ifdef OPT_PIPELINED - m_core->v__DOT__thecpu__DOT__dcd_stalled, -#else - 0, -#endif - (m_core->v__DOT__thecpu__DOT__dcd_pc-1)<<2, -#ifdef OPT_CIS - m_core->v__DOT__thecpu__DOT__instruction_decoder__DOT__r_phase, -#else - false, -#endif -#ifdef OPT_ILLEGAL_INSTRUCTION - m_core->v__DOT__thecpu__DOT__dcd_illegal -#else - false -#endif - ); - if (m_dbgfp) { - fprintf(m_dbgfp, "\t\t\tR[%2d] = (*Dc=%d%s)[ A[%2d], B[%2d] + %08x], dcd_pc = %08x\n", - m_core->v__DOT__thecpu__DOT____Vcellout__instruction_decoder____pinNumber14, - m_core->v__DOT__thecpu__DOT__dcd_opn, - (m_core->v__DOT__thecpu__DOT__dcd_M)?"M":" ", - m_core->v__DOT__thecpu__DOT____Vcellout__instruction_decoder____pinNumber15&0x0f, - m_core->v__DOT__thecpu__DOT____Vcellout__instruction_decoder____pinNumber16&0x0f, - m_core->v__DOT__thecpu__DOT__dcd_I, - m_core->v__DOT__thecpu__DOT__dcd_pc); - } - dbgins("Op - ", - op_ce(), - m_core->v__DOT__thecpu__DOT__op_valid, - m_core->v__DOT__thecpu__DOT__r_op_gie, - m_core->v__DOT__thecpu__DOT__op_stall, - op_pc(), -#ifdef OPT_CIS - m_core->v__DOT__thecpu__DOT__r_op_phase, -#else - false, -#endif -#ifdef OPT_ILLEGAL_INSTRUCTION - m_core->v__DOT__thecpu__DOT__op_illegal -#else - false -#endif - ); - if (m_dbgfp) { - fprintf(m_dbgfp, "\t\t\t(*OP=%d)[ A = 0x%08x , B = 0x%08x ], op_pc= %08x\n", - m_core->v__DOT__thecpu__DOT__r_op_opn, - m_core->v__DOT__thecpu__DOT__op_Av, - m_core->v__DOT__thecpu__DOT__op_Bv, - m_core->v__DOT__thecpu__DOT__op_pc); - } - dbgins("Al - ", - m_core->v__DOT__thecpu__DOT__alu_ce, - m_core->v__DOT__thecpu__DOT__alu_pc_valid, - m_core->v__DOT__thecpu__DOT__r_alu_gie, -#ifdef OPT_PIPELINED - m_core->v__DOT__thecpu__DOT__alu_stall, -#else - 0, -#endif - alu_pc(), -#ifdef OPT_CIS - m_core->v__DOT__thecpu__DOT__r_alu_phase, -#else - false, -#endif -#ifdef OPT_ILLEGAL_INSTRUCTION - m_core->v__DOT__thecpu__DOT__r_alu_illegal -#else - false -#endif - ); - if (m_core->v__DOT__thecpu__DOT__wr_reg_ce) - fprintf(m_dbgfp, "WB::Reg[%2x] <= %08x\n", - m_core->v__DOT__thecpu__DOT__wr_reg_id, - m_core->v__DOT__thecpu__DOT__wr_gpreg_vl); - - } - - if ((m_dbgfp)&&((m_core->v__DOT__thecpu__DOT__div_valid) - ||(m_core->v__DOT__thecpu__DOT__div_ce) - ||(m_core->v__DOT__thecpu__DOT__div_busy) - )) { - fprintf(m_dbgfp, "DIV: %s %s %s %s[%2x] GP:%08x/SP:%08x %s:0x%08x\n", - (m_core->v__DOT__thecpu__DOT__div_ce)?"CE":" ", - (m_core->v__DOT__thecpu__DOT__div_busy)?"BUSY":" ", - (m_core->v__DOT__thecpu__DOT__div_valid)?"VALID":" ", - (m_core->v__DOT__thecpu__DOT__wr_reg_ce)?"REG-CE":" ", - m_core->v__DOT__thecpu__DOT__wr_reg_id, - m_core->v__DOT__thecpu__DOT__wr_gpreg_vl, - m_core->v__DOT__thecpu__DOT__wr_spreg_vl, - (m_core->v__DOT__thecpu__DOT__alu_pc_valid)?"PCV":" ", - alu_pc()); - - fprintf(m_dbgfp, "ALU-PC: %08x %s %s\n", - alu_pc(), - (m_core->v__DOT__thecpu__DOT__r_alu_pc_valid)?"VALID":"", - (m_core->v__DOT__thecpu__DOT__r_alu_gie)?"ALU-GIE":""); - } - - if (m_core->v__DOT__dma_controller__DOT__dma_state) { - fprintf(m_dbgfp, "DMA[%d]%s%s%s%s@%08x,%08x [%d%d/%4d/%4d] -> [%d%d/%04d/%04d]\n", - m_core->v__DOT__dma_controller__DOT__dma_state, - (m_core->v__DOT__dc_cyc)?"C":" ", - (m_core->v__DOT__dc_stb)?"S":" ", - (m_core->v__DOT__dc_ack)?"A":" ", - (m_core->v__DOT__dc_err)?"E":" ", - m_core->v__DOT__dc_addr<<2, - (m_core->v__DOT__dc_data), - m_core->v__DOT__dma_controller__DOT__last_read_request, - m_core->v__DOT__dma_controller__DOT__last_read_ack, - m_core->v__DOT__dma_controller__DOT__nracks, - m_core->v__DOT__dma_controller__DOT__nread, - m_core->v__DOT__dma_controller__DOT__last_write_request, - m_core->v__DOT__dma_controller__DOT__last_write_ack, - m_core->v__DOT__dma_controller__DOT__nwacks, - m_core->v__DOT__dma_controller__DOT__nwritten); - } - if (((m_core->v__DOT__thecpu__DOT__alu_pc_valid) - ||(m_core->v__DOT__thecpu__DOT__mem_pc_valid)) - &&(!m_core->v__DOT__thecpu__DOT__new_pc)) { - unsigned long iticks = m_tickcount - m_last_instruction_tickcount; - if (m_profile_fp) { - unsigned buf[2]; - buf[0] = alu_pc(); - buf[1] = iticks; - fwrite(buf, sizeof(unsigned), 2, m_profile_fp); - } - m_last_instruction_tickcount = m_tickcount; - } - } - - bool test_success(void) { - return ((!m_core->v__DOT__thecpu__DOT__r_gie) - &&(m_core->v__DOT__thecpu__DOT__sleep)); - } - - unsigned op_pc(void) { - return (m_core->v__DOT__thecpu__DOT__op_pc<<2)-4; - } - - bool dcd_ce(void) { - if (m_core->v__DOT__thecpu__DOT__new_pc) - return false; - if (!dcd_valid()) - return true; - if (!m_core->v__DOT__thecpu__DOT__dcd_stalled) - return true; - return false; - } bool dcd_valid(void) { - return (m_core->v__DOT__thecpu__DOT__r_dcd_valid !=0); - } - bool pfstall(void) { - return((!(m_core->v__DOT__thecpu__DOT__pformem__DOT__r_a_owner)) - ||(m_core->v__DOT__cpu_stall)); - } - unsigned dcd_R(void) { - return (m_core->v__DOT__thecpu__DOT____Vcellout__instruction_decoder____pinNumber14); - } - unsigned dcd_Aid(void) { - return (m_core->v__DOT__thecpu__DOT____Vcellout__instruction_decoder____pinNumber15); - } - unsigned dcd_Bid(void) { - return (m_core->v__DOT__thecpu__DOT____Vcellout__instruction_decoder____pinNumber16); - } - - bool op_ce(void) { - return dcd_valid(); - } bool op_valid(void) { - return (m_core->v__DOT__thecpu__DOT__op_valid !=0); - } - - bool mem_busy(void) { - // return m_core->v__DOT__thecpu__DOT__mem_busy; -#ifdef OPT_PIPELINED - return m_core->v__DOT__thecpu__DOT__domem__DOT__cyc; -#else - return 0; -#endif - } - - bool mem_stalled(void) { - bool a, b, c, d, wr_write_cc, wr_write_pc, op_gie; - - wr_write_cc=((m_core->v__DOT__thecpu__DOT__wr_reg_id&0x0f)==0x0e); - wr_write_pc=((m_core->v__DOT__thecpu__DOT__wr_reg_id&0x0f)==0x0f); - op_gie = m_core->v__DOT__thecpu__DOT__r_op_gie; - -#ifdef OPT_PIPELINED_BUS_ACCESS - //a = m_core->v__DOT__thecpu__DOT__mem_pipe_stalled; - a = mem_pipe_stalled(); - b = (!m_core->v__DOT__thecpu__DOT__r_op_pipe)&&(mem_busy()); -#else - a = false; - b = false; -#endif - d = ((wr_write_pc)||(wr_write_cc)); - c = ((m_core->v__DOT__thecpu__DOT__wr_reg_ce) - &&(((m_core->v__DOT__thecpu__DOT__wr_reg_id&0x010)?true:false)==op_gie) - &&d); - d =(m_core->v__DOT__thecpu__DOT__op_valid_mem)&&((a)||(b)||(c)); - return ((!m_core->v__DOT__thecpu__DOT__master_ce)||(d)); - } - - unsigned alu_pc(void) { - /* - unsigned r = op_pc(); - if (m_core->v__DOT__thecpu__DOT__op_valid) - r--; - return r; - */ - return (m_core->v__DOT__thecpu__DOT__r_alu_pc<<2)-4; - } - -#ifdef OPT_PIPELINED_BUS_ACCESS - bool mem_pipe_stalled(void) { - int r = 0; - r = ((m_core->v__DOT__thecpu__DOT__domem__DOT__r_wb_cyc_gbl) - ||(m_core->v__DOT__thecpu__DOT__domem__DOT__r_wb_cyc_lcl)); - r = r && ((m_core->v__DOT__thecpu__DOT__mem_stall) - ||( - ((!m_core->v__DOT__thecpu__DOT__mem_stb_gbl) - &&(!m_core->v__DOT__thecpu__DOT__mem_stb_lcl)))); - return r; - // return m_core->v__DOT__thecpu__DOT__mem_pipe_stalled; - } -#endif - - bool test_failure(void) { - if (m_core->v__DOT__thecpu__DOT__sleep) - return 0; - else if (m_core->v__DOT__thecpu__DOT__r_gie) - return (m_mem[m_core->v__DOT__thecpu__DOT__r_upc] == 0x7bc3dfff); - else if (m_mem[m_core->v__DOT__thecpu__DOT__ipc] == 0x7883ffff) - return true; // ADD to PC instruction - else // MOV to PC instruction - return (m_mem[m_core->v__DOT__thecpu__DOT__ipc] == 0x7bc3dfff); - /* - return ((m_core->v__DOT__thecpu__DOT__alu_pc_valid) - &&(m_mem[alu_pc()] == 0x2f0f7fff) - &&(!m_core->v__DOT__thecpu__DOT__clear_pipeline)); - */ - } - - void wb_write(unsigned a, unsigned int v) { - int errcount = 0; - mvprintw(0,35, "%40s", ""); - mvprintw(0,40, "wb_write(%d,%x)", a, v); - m_core->i_dbg_cyc = 1; - m_core->i_dbg_stb = 1; - m_core->i_dbg_we = 1; - m_core->i_dbg_addr = (a>>2) & 1; - m_core->i_dbg_data = v; - - while((errcount++ < 100)&&(m_core->o_dbg_stall)) - tick(); - tick(); - - m_core->i_dbg_stb = 0; - while((errcount++ < 100)&&(!m_core->o_dbg_ack)) - tick(); - - // Release the bus - m_core->i_dbg_cyc = 0; - m_core->i_dbg_stb = 0; - tick(); - mvprintw(0,35, "%40s", ""); - mvprintw(0,40, "wb_write -- complete"); - - - if (errcount >= 100) { - if (m_dbgfp) fprintf(m_dbgfp, "WB-WRITE: ERRCount = %d, BOMB!!\n", errcount); - m_bomb = true; - } - } - - unsigned long wb_read(unsigned a) { - unsigned int v; - int errcount = 0; - mvprintw(0,35, "%40s", ""); - mvprintw(0,40, "wb_read(0x%08x)", a); - m_core->i_dbg_cyc = 1; - m_core->i_dbg_stb = 1; - m_core->i_dbg_we = 0; - m_core->i_dbg_addr = (a>>2) & 1; - - while((errcount++<100)&&(m_core->o_dbg_stall)) - tick(); - tick(); - - m_core->i_dbg_stb = 0; - while((errcount++<100)&&(!m_core->o_dbg_ack)) - tick(); - v = m_core->o_dbg_data; - - // Release the bus - m_core->i_dbg_cyc = 0; - m_core->i_dbg_stb = 0; - tick(); - - mvprintw(0,35, "%40s", ""); - mvprintw(0,40, "wb_read = 0x%08x", v); - - if (errcount >= 100) { - if (m_dbgfp) fprintf(m_dbgfp, "WB-READ: ERRCount = %d, BOMB!!\n", errcount); - m_bomb = true; - } - return v; - } - - void cursor_up(void) { - if (m_cursor > 3) - m_cursor -= 4; - } void cursor_down(void) { - if (m_cursor < 40) - m_cursor += 4; - } void cursor_left(void) { - if (m_cursor > 0) - m_cursor--; - else m_cursor = 43; - } void cursor_right(void) { - if (m_cursor < 43) - m_cursor++; - else m_cursor = 0; - } - - int cursor(void) { return m_cursor; } - - void jump_to(ZIPI address) { - if (m_dbgfp) - fprintf(m_dbgfp, "JUMP_TO(%08x) ... Setting PC to %08x\n", address, address & -4); - m_core->v__DOT__thecpu__DOT__pf_pc = address & -4; - m_core->v__DOT__thecpu__DOT__pf_request_address = address >> 2; - // m_core->v__DOT__thecpu__DOT__clear_pipeline = 1; - m_core->v__DOT__thecpu__DOT__new_pc = 1; - } - - void dump_state(void) { - if (m_dbgfp) - dump_state(m_dbgfp); - } - - void dump_state(FILE *fp) { - if (!fp) - return; - fprintf(fp, "FINAL STATE: %s\n", - (m_state.m_gie)?"GIE(User-Mode)":"Supervisor-mode"); - fprintf(fp, "Supervisor Registers\n"); - for(int i=0; i<16; i++) { - char str[16]; - if (i==13) - sprintf(str, "sSP"); - else if (i==14) - sprintf(str, "sCC"); - else if (i==15) - sprintf(str, "sPC"); - else // if (i<=12) - sprintf(str, "s-%2d", i); - dbgreg(fp, i, str, m_state.m_sR[i]); - if ((i&3)==3) - fprintf(fp, "\n"); - } - fprintf(fp, "User Registers\n"); - for(int i=0; i<16; i++) { - char str[16]; - if (i==13) - sprintf(str, "uSP"); - else if (i==14) - sprintf(str, "uCC"); - else if (i==15) - sprintf(str, "uPC"); - else // if (i<=12) - sprintf(str, "u-%2d", i); - dbgreg(fp, i, str, m_state.m_uR[i]); - if ((i&3)==3) - fprintf(fp, "\n"); - } - } -}; - -void get_value(ZIPPY_TB *tb) { - int wy, wx, ra; - int c = tb->cursor(); - - wx = (c & 0x03) * 20 + 9; - wy = (c>>2); - if (wy >= 3+4) - wy++; - if (wy > 3) - wy += 2; - wy++; - - if (c >= 12) - ra = c - 12; - else - ra = c + 32; - - bool done = false; - char str[16]; - int pos = 0; str[pos] = '\0'; - while(!done) { - int chv = getch(); - switch(chv) { - case KEY_ESCAPE: - pos = 0; str[pos] = '\0'; done = true; - break; - case KEY_RETURN: case KEY_ENTER: case KEY_UP: case KEY_DOWN: - done = true; - break; - case KEY_LEFT: case KEY_BACKSPACE: - if (pos > 0) pos--; - break; - case CTRL('L'): redrawwin(stdscr); break; - case KEY_CLEAR: - pos = 0; - break; - case '0': case ' ': str[pos++] = '0'; break; - case '1': str[pos++] = '1'; break; - case '2': str[pos++] = '2'; break; - case '3': str[pos++] = '3'; break; - case '4': str[pos++] = '4'; break; - case '5': str[pos++] = '5'; break; - case '6': str[pos++] = '6'; break; - case '7': str[pos++] = '7'; break; - case '8': str[pos++] = '8'; break; - case '9': str[pos++] = '9'; break; - case 'A': case 'a': str[pos++] = 'A'; break; - case 'B': case 'b': str[pos++] = 'B'; break; - case 'C': case 'c': str[pos++] = 'C'; break; - case 'D': case 'd': str[pos++] = 'D'; break; - case 'E': case 'e': str[pos++] = 'E'; break; - case 'F': case 'f': str[pos++] = 'F'; break; - } - - if (pos > 8) - pos = 8; - str[pos] = '\0'; - - attron(A_NORMAL | A_UNDERLINE); - mvprintw(wy, wx, "%-8s", str); - if (pos > 0) { - attron(A_NORMAL | A_UNDERLINE | A_BLINK); - mvprintw(wy, wx+pos-1, "%c", str[pos-1]); - } - attrset(A_NORMAL); - } - - if (pos > 0) { - int v; - v = strtoul(str, NULL, 16); - if (!tb->halted()) { - switch(ra) { - case 15: - tb->m_core->v__DOT__thecpu__DOT__ipc = v; - if (!tb->m_core->v__DOT__thecpu__DOT__r_gie) { - tb->jump_to(v); - // tb->m_core->v__DOT__thecpu__DOT__clear_pipeline = 1; - tb->m_core->v__DOT__thecpu__DOT__alu_pc_valid = 0; -#ifdef OPT_PIPELINED - // tb->m_core->v__DOT__thecpu__DOT__dcd_ce = 0; - tb->m_core->v__DOT__thecpu__DOT__r_dcd_valid = 0; -#endif - tb->m_core->v__DOT__thecpu__DOT__op_valid = 0; - } - break; - case 31: - tb->m_core->v__DOT__thecpu__DOT__r_upc = v; - if (tb->m_core->v__DOT__thecpu__DOT__r_gie) { - tb->jump_to(v); - // tb->m_core->v__DOT__thecpu__DOT__clear_pipeline = 1; - tb->m_core->v__DOT__thecpu__DOT__alu_pc_valid = 0; -#ifdef OPT_PIPELINED - tb->m_core->v__DOT__thecpu__DOT__r_dcd_valid = 0; -#endif - tb->m_core->v__DOT__thecpu__DOT__op_valid = 0; - } - break; - case 32: tb->m_core->v__DOT__pic_data = v; break; - case 33: tb->m_core->v__DOT__watchdog__DOT__r_value = v; break; - // case 34: tb->m_core->v__DOT__manualcache__DOT__cache_base = v; break; - case 35: tb->m_core->v__DOT__genblk7__DOT__ctri__DOT__r_int_state = v; break; - case 36: tb->m_core->v__DOT__timer_a__DOT__r_value = v; break; - case 37: tb->m_core->v__DOT__timer_b__DOT__r_value = v; break; - case 38: tb->m_core->v__DOT__timer_c__DOT__r_value = v; break; - case 39: tb->m_core->v__DOT__jiffies__DOT__r_counter = v; break; - case 44: tb->m_core->v__DOT__utc_data = v; break; - case 45: tb->m_core->v__DOT__uoc_data = v; break; - case 46: tb->m_core->v__DOT__upc_data = v; break; - case 47: tb->m_core->v__DOT__uic_data = v; break; - default: - tb->m_core->v__DOT__thecpu__DOT__regset[ra] = v; - break; - } - } else - tb->cmd_write(ra, v); - } -} - - - -void usage(void) { - printf("USAGE: zippy_tb [-a] \n"); - printf("\n"); - printf("\tWhere testfile.out is an output file from the assembler.\n"); - printf("\tThis file needs to be in a raw format and not an ELF\n"); - printf("\texecutable. It will be inserted into memory at a memory\n"); - printf("\taddress of 0x0100000. The memory device itself, the only\n"); - printf("\tdevice supported by this simulator, occupies addresses from\n"); - printf("\t0x0100000 to 0x01fffff.\n"); - printf("\n"); - printf("\t-a\tSets the testbench to run automatically without any\n"); - printf("\t\tuser interaction.\n"); - printf("\n"); - printf("\tUser Commands:\n"); - printf("\t\tWhen the test bench is run interactively, the following\n"); - printf("\t\tkey strokes are recognized:\n"); - printf("\t\t\'h\'\tHalt the processor using the external interface.\n"); - printf("\t\t\'g\'\tLet the processor run at full throttle with no.\n"); - printf("\t\t\tuser intervention.\n"); - printf("\t\t\'q\'\tQuit the simulation.\n"); - printf("\t\t\'r\'\tReset the processor.\n"); - printf("\t\t\'s\'\tStep the CPU using the external stepping command\n"); - printf("\t\t\tThis may consume more than one tick.\n"); - printf("\t\t\'t\'\tClock a single tick through the system.\n"); -} - -bool signalled = false; - -void sigint(int v) { - signalled = true; -} - -int main(int argc, char **argv) { - Verilated::commandArgs(argc, argv); - ZIPPY_TB *tb = new ZIPPY_TB(); - bool autorun = false, exit_on_done = false, autostep=false; - ZIPI entry = RAMBASE; - - signal(SIGINT, sigint); - - if (argc <= 1) { - usage(); - exit(-1); - } else { - for(int argn=1; argnm_len; i++) { - const char *data; - - secp = secpp[i]; - assert(secp->m_start >= RAMBASE); - assert(secp->m_start+secp->m_len <= RAMBASE+RAMWORDS); - assert((secp->m_len & 3)==0); - - data = &secp->m_data[0]; - tb->m_mem.load((secp->m_start-RAMBASE)>>2, data, secp->m_len); - } - } else { - fprintf(stderr, "No access to %s, or unknown arg\n", argv[argn]); - exit(-2); - } - } - } - - - if (autorun) { - bool done = false; - - printf("Running in non-interactive mode\n"); - tb->reset(); - for(int i=0; i<2; i++) - tb->tick(); - tb->m_core->v__DOT__cmd_halt = 0; - tb->wb_write(CMD_REG, CMD_HALT|CMD_RESET|15); - tb->wb_write(CMD_DATA, entry); - tb->wb_write(CMD_REG, 15); - while(!done) { - tb->tick(); - - // tb->m_core->v__DOT__thecpu__DOT__step = 0; - // tb->m_core->v__DOT__cmd_halt = 0; - // tb->m_core->v__DOT__cmd_step = 0; - - /* - printf("PC = %08x:%08x (%08x)\n", - tb->m_core->v__DOT__thecpu__DOT__ipc, - tb->m_core->v__DOT__thecpu__DOT__r_upc, - tb->m_core->v__DOT__thecpu__DOT__alu_pc); - */ - - done = (tb->test_success())||(tb->test_failure()); - done = done || signalled; - } - } else if (autostep) { - bool done = false; - - printf("Running in non-interactive mode, via step commands\n"); - tb->wb_write(CMD_REG, CMD_HALT|CMD_RESET|15); - tb->wb_write(CMD_DATA, entry); - tb->wb_write(CMD_REG, 15); - while(!done) { - tb->wb_write(CMD_REG, CMD_STEP); - done = (tb->test_success())||(tb->test_failure()); - done = done || signalled; - } - } else { // Interactive - initscr(); - raw(); - noecho(); - keypad(stdscr, true); - - // tb->reset(); - // for(int i=0; i<2; i++) - // tb->tick(); - tb->m_core->v__DOT__cmd_reset = 1; - tb->m_core->v__DOT__cmd_halt = 1; - tb->tick(); - - tb->m_core->v__DOT__cmd_reset = 0; - tb->m_core->v__DOT__cmd_halt = 0; - tb->tick(); - tb->jump_to(entry); - tb->tick(); - tb->jump_to(entry); - tb->tick(); - tb->jump_to(entry); - - - // For debugging purposes: do we wish to skip some number of - // instructions to fast forward to a time of interest?? - for(int i=0; i<0; i++) { - tb->m_core->v__DOT__cmd_halt = 0; - tb->tick(); - } - - int chv = 'q'; - - bool done = false, halted = true, manual = true, - high_speed = false; - - halfdelay(1); - // tb->wb_write(CMD_REG, CMD_HALT | CMD_RESET); - // while((tb->wb_read(CMD_REG) & (CMD_HALT|CMD_STALL))==(CMD_HALT|CMD_STALL)) - // tb->show_state(); - - while(!done) { - if ((high_speed)&&(!manual)&&(!halted)) { - // chv = getch(); - - struct pollfd fds[1]; - fds[0].fd = STDIN_FILENO; - fds[0].events = POLLIN; - - if (poll(fds, 1, 0) > 0) - chv = getch(); - else - chv = ERR; - - } else { - chv = getch(); - } - switch(chv) { - case 'h': case 'H': - tb->wb_write(CMD_REG, CMD_HALT); - if (!halted) - erase(); - halted = true; - break; - case 'G': - high_speed = true; - // cbreak(); - case 'g': - tb->wb_write(CMD_REG, 0); - if (halted) - erase(); - halted = false; - manual = false; - break; - case 'm': - tb->show_user_timers(false); - break; - case 'q': case 'Q': - done = true; - break; - case 'r': case 'R': - if (manual) - tb->reset(); - else - tb->wb_write(CMD_REG, CMD_RESET|CMD_HALT); - halted = true; - erase(); - break; - case 's': - if (!halted) - erase(); - tb->step(); - manual = false; - halted = true; - // if (high_speed) - // halfdelay(1); - high_speed = false; - break; - case 'S': - if ((!manual)||(halted)) - erase(); - manual = true; - halted = true; - // if (high_speed) - // halfdelay(1); - high_speed = false; - tb->m_core->v__DOT__cmd_halt = 0; - tb->m_core->v__DOT__cmd_step = 1; - tb->eval(); - tb->tick(); - break; - case 'T': // - if ((!manual)||(halted)) - erase(); - manual = true; - halted = true; - // if (high_speed) - // halfdelay(1); - high_speed = false; - tb->m_core->v__DOT__cmd_halt = 1; - tb->m_core->v__DOT__cmd_step = 0; - tb->eval(); - tb->tick(); - break; - case 't': - if ((!manual)||(halted)) - erase(); - manual = true; - halted = false; - // if (high_speed) - // halfdelay(1); - high_speed = false; - // tb->m_core->v__DOT__thecpu__DOT__step = 0; - tb->m_core->v__DOT__cmd_halt = 0; - // tb->m_core->v__DOT__cmd_step = 0; - tb->tick(); - break; - case 'u': - tb->show_user_timers(true); - break; - case KEY_IC: case KEY_ENTER: case KEY_RETURN: - get_value(tb); - break; - case KEY_UP: tb->cursor_up(); break; - case KEY_DOWN: tb->cursor_down(); break; - case KEY_LEFT: tb->cursor_left(); break; - case KEY_RIGHT: tb->cursor_right(); break; - case CTRL('L'): redrawwin(stdscr); break; - case ERR: case KEY_CLEAR: - default: - if (!manual) - tb->tick(); - } - - if (manual) { - tb->show_state(); - } else if (halted) { - if (tb->m_dbgfp) - fprintf(tb->m_dbgfp, "\n\nREAD-STATE ******\n"); - tb->read_state(); - } else - tb->show_state(); - - if (tb->m_core->i_rst) - done =true; - if ((tb->m_bomb)||(signalled)) - done = true; - - if (exit_on_done) { - if (tb->test_success()) - done = true; - if (tb->test_failure()) - done = true; - } - } - endwin(); - } -#ifdef MANUAL_STEPPING_MODE - else { // Manual stepping mode - tb->jump_to(entry); - tb->show_state(); - - while('q' != tolower(chv = getch())) { - tb->tick(); - tb->show_state(); - - if (tb->test_success()) - break; - else if (tb->test_failure()) - break; - else if (signalled) - break; - } - } -#endif - - printf("\n"); - if (tb->test_failure()) { - tb->dump_state(); - } - - printf("Clocks used : %08x\n", tb->m_core->v__DOT__mtc_data); - printf("Instructions Issued : %08x\n", tb->m_core->v__DOT__mic_data); - printf("Tick Count : %08lx\n", tb->m_tickcount); - if (tb->m_core->v__DOT__mtc_data != 0) - printf("Instructions / Clock: %.2f\n", - (double)tb->m_core->v__DOT__mic_data - / (double)tb->m_core->v__DOT__mtc_data); - - int rcode = 0; - if (tb->m_bomb) { - printf("TEST BOMBED\n"); - rcode = -1; - } else if (tb->test_success()) { - printf("SUCCESS!\n"); - } else if (tb->test_failure()) { - rcode = -2; - printf("TEST FAILED!\n"); - } else - printf("User quit\n"); - delete tb; - exit(rcode); -} - Index: trunk/sim/verilator/byteswap.h =================================================================== --- trunk/sim/verilator/byteswap.h (revision 204) +++ trunk/sim/verilator/byteswap.h (nonexistent) @@ -1,90 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Filename: byteswap.h -// -// Project: Zip CPU -- a small, lightweight, RISC CPU soft core -// -// Purpose: To convert between little endian and big endian byte orders, -// and to handle conversions between character strings and -// bit-endian words made from those characters. -// -// -// Creator: Dan Gisselquist, Ph.D. -// Gisselquist Technology, LLC -// -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015-2016, Gisselquist Technology, LLC -// -// This program is free software (firmware): you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program. (It's in the $(ROOT)/doc directory. Run make with no -// target there if the PDF file isn't present.) If not, see -// for a copy. -// -// License: GPL, v3, as defined and found on www.gnu.org, -// http://www.gnu.org/licenses/gpl.html -// -// -//////////////////////////////////////////////////////////////////////////////// -// -// -#ifndef BYTESWAP_H -#define BYTESWAP_H - -#include - -/* - * The byte swapping routines below are designed to support conversions from a little endian - * machine/host (such as my PC) to the big endian byte order used on the ZipCPU. If the current - * machine is already little endian, no byte swapping is required. - */ -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -/* - * byteswap - * - * Given a big (or little) endian word, return a little (or big) endian word. - */ -extern uint32_t -byteswap(uint32_t v); - -/* - * byteswapbuf - * - * To swap from the byte order of every 32-bit word in the given buffer. - */ -extern void byteswapbuf(int ln, uint32_t *buf); - -#else -#define byteswap(A) (A) -#define byteswapbuf(A, B) -#endif - -/* - * buildword - * - * Given a pointer within an array of characters, build a 32-bit big-endian - * word from those characters. Does not require the character pointer to be - * aligned. - */ -extern uint32_t buildword(const unsigned char *p); - -/* - * buildswap - * - * Same as buildword, except that we build a little endian word from the - * characters given to us. Hence the first character is the low order octet - * of the word. - */ -extern uint32_t buildswap(const unsigned char *p); - -#endif Index: trunk/sim/verilator/zipmmu_tb.cpp =================================================================== --- trunk/sim/verilator/zipmmu_tb.cpp (revision 204) +++ trunk/sim/verilator/zipmmu_tb.cpp (nonexistent) @@ -1,810 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Filename: zipmmu_tb.cpp -// -// Project: Zip CPU -- a small, lightweight, RISC CPU soft core -// -// Purpose: A quick test bench to determine if the zipmmu module works. -// This test bench does nothing to determine whether or not it -// is connected properly, but only tests whether or not the zipmmu works -// as it is supposed to. -// -// -// Creator: Dan Gisselquist, Ph.D. -// Gisselquist Technology, LLC -// -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015-2016, Gisselquist Technology, LLC -// -// This program is free software (firmware): you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// License: GPL, v3, as defined and found on www.gnu.org, -// http://www.gnu.org/licenses/gpl.html -// -// -//////////////////////////////////////////////////////////////////////////////// -// -// -#include - -#include -#include -#include "testb.h" -#include "Vzipmmu_tb.h" - -#define MMUFLAG_RONW 8 // Read only (not writeable) -#define MMUFLAG_ACCS 4 // Accessed -#define MMUFLAG_CCHE 2 // Cachable -#define MMUFLAG_THSP 1 // Page has this context - -const int BOMBCOUNT = 32, - LGMEMSIZE = 15; - -class ZIPMMU_TB : public TESTB { - long m_tickcount; - bool m_bomb, m_miss, m_err, m_debug; - int m_last_tlb_index; -public: - - ZIPMMU_TB(void) { - m_debug = true; - m_last_tlb_index = 0; - } - -#define v__DOT__mem_stb v__DOT__mut__DOT__r_valid - void tick(void) { - - TESTB::tick(); - - bool writeout = true; - - if ((m_debug)&&(writeout)) { - printf("%08lx-MMU: ", m_tickcount); - printf("(%s%s%s%s) %08x (%s%s%s)%08x%s %s %08x/%08x %s%s%s%s%s", - (m_core->i_ctrl_cyc_stb)?"CT":" ", - (m_core->i_wbm_cyc)?"CYC":" ", - (m_core->i_wbm_stb)?"STB":" ", - (m_core->i_wb_we)?"WE":" ", - (m_core->i_wb_addr), - (m_core->v__DOT__mem_cyc)?"CYC":" ", - (m_core->v__DOT__mem_stb)?"STB":" ", -#define v__DOT__mem_we v__DOT__mut__DOT__r_we - (m_core->v__DOT__mem_we)?"WE":" ", - (m_core->v__DOT__mem_addr), - (m_core->v__DOT__mem_err)?"ER":" ", - (m_core->i_wb_we)?"<-":"->", - (m_core->i_wb_we)?m_core->i_wb_data:m_core->o_rtn_data, - (m_core->v__DOT__mem_we)?m_core->v__DOT__mut__DOT__r_data:m_core->v__DOT__mem_odata, - (m_core->o_rtn_stall)?"STALL":" ", - (m_core->v__DOT__mut__DOT__setup_ack)?"S":" ", - (m_core->o_rtn_ack )?"ACK":" ", - (m_core->o_rtn_miss)?"MISS":" ", - (m_core->o_rtn_err )?"ERR":" "); - - printf("[%d,%d]", - m_core->v__DOT__mut__DOT__wr_vtable, - m_core->v__DOT__mut__DOT__wr_ptable); - printf("[%d,%d,%04x]", - m_core->v__DOT__mut__DOT__wr_control, - m_core->v__DOT__mut__DOT__z_context, - m_core->v__DOT__mut__DOT__r_context_word); - /* - printf("[%08x,%08x-%08x]", - m_core->v__DOT__mut__DOT__w_vtable_reg, - m_core->v__DOT__mut__DOT__w_ptable_reg, - m_core->v__DOT__mut__DOT__setup_data); - */ - printf(" %s[%s%s@%08x,%08x]", - (m_core->v__DOT__mut__DOT__r_pending)?"R":" ", - (m_core->v__DOT__mut__DOT__r_we)?"W":" ", - (m_core->v__DOT__mut__DOT__r_valid)?"V":" ", - (m_core->v__DOT__mut__DOT__r_addr), - (m_core->v__DOT__mut__DOT__r_data)); - printf("@%2x[%s%s%s][%s%s%s%s]", - (m_core->v__DOT__mut__DOT__s_tlb_addr), - (m_core->v__DOT__mut__DOT__s_pending)?"P":" ", - (m_core->v__DOT__mut__DOT__s_tlb_hit)?"HT":" ", - (m_core->v__DOT__mut__DOT__s_tlb_miss)?"MS":" ", - (m_core->v__DOT__mut__DOT__ro_flag)?"RO":" ", - (m_core->v__DOT__mut__DOT__simple_miss)?"SM":" ", - (m_core->v__DOT__mut__DOT__ro_miss)?"RM":" ", - (m_core->v__DOT__mut__DOT__table_err)?"TE":" "); - //(m_core->v__DOT__mut__DOT__cachable)?"CH":" "); - /* - printf(" M[%016lx]", - m_core->v__DOT__mut__DOT__r_tlb_match); - printf(" P[%3d] = 0x%08x, V=0x%08x, C=0x%08x, CTXT=%04x", - m_last_tlb_index, - m_core->v__DOT__mut__DOT__tlb_pdata[m_last_tlb_index], - m_core->v__DOT__mut__DOT__tlb_vdata[m_last_tlb_index], - m_core->v__DOT__mut__DOT__tlb_cdata[m_last_tlb_index], - m_core->v__DOT__mut__DOT__r_context_word); - */ - printf("\n"); - } - } - - void reset(void) { - m_core->i_rst = 1; - m_core->i_ctrl_cyc_stb = 0; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - m_core->i_rst = 0; - } - - void wb_tick(void) { - m_core->i_rst = 0; - m_core->i_ctrl_cyc_stb = 0; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - assert(!m_core->o_rtn_ack); - assert(!m_core->o_rtn_err); - } - - unsigned operator[](unsigned a) { - a &= ((1<v__DOT__ram__DOT__mem[a]; - } - - unsigned setup_read(unsigned a) { - int errcount = 0; - unsigned result; - m_miss = false; m_err = false; - - printf("WB-READS(%08x)\n", a); - - m_core->i_ctrl_cyc_stb = 1; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - m_core->i_wb_we = 0; - m_core->i_wb_addr= a; - - if (m_core->o_rtn_stall) { - while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) - tick(); - } tick(); - - m_core->i_ctrl_cyc_stb = 0; - - while((errcount++ < BOMBCOUNT)&&(!m_core->o_rtn_ack)) { - tick(); - } - - - result = m_core->o_rtn_data; - assert(!m_core->o_rtn_err); - assert(!m_core->o_rtn_miss); - - if(errcount >= BOMBCOUNT) { - printf("SETTING ERR TO TRUE!!!!! (BOMB)\n"); - m_bomb = true; - } else if (!m_core->o_rtn_ack) { - printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n"); - m_bomb = true; - } - tick(); - - assert(!m_core->o_rtn_ack); - assert(!m_core->o_rtn_miss); - assert(!m_core->o_rtn_err); - assert(!m_core->o_rtn_stall); - - return result; - } - - void setup_write(unsigned a, unsigned v) { - int errcount = 0; - m_miss = false; m_err = false; - - printf("WB-WRITES(%08x,%08x)\n", a,v); - - m_core->i_ctrl_cyc_stb = 1; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - m_core->i_wb_we = 1; - m_core->i_wb_addr= a; - m_core->i_wb_data= v; - - if (a & 0x080) - m_last_tlb_index = (a>>1)&0x3f; - - if (m_core->o_rtn_stall) { - while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) - tick(); - } tick(); - - m_core->i_ctrl_cyc_stb = 0; - - while((errcount++ < BOMBCOUNT)&&(!m_core->o_rtn_ack)) { - tick(); - } - - - assert(!m_core->o_rtn_err); - assert(!m_core->o_rtn_miss); - - if(errcount >= BOMBCOUNT) { - printf("SETTING ERR TO TRUE!!!!! (BOMB)\n"); - m_bomb = true; - } else if (!m_core->o_rtn_ack) { - printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n"); - m_bomb = true; - } - tick(); - - assert(!m_core->o_rtn_ack); - assert(!m_core->o_rtn_miss); - assert(!m_core->o_rtn_err); - assert(!m_core->o_rtn_stall); - } - - unsigned wb_read(unsigned a, bool *err) { - int errcount = 0; - unsigned result; - if (err) *err = false; - - printf("WB-READM(%08x)\n", a); - - m_core->i_ctrl_cyc_stb = 0; - m_core->i_wbm_cyc = 1; - m_core->i_wbm_stb = 1; - m_core->i_wb_we = 0; - m_core->i_wb_addr= a; - - if (m_core->o_rtn_stall) { - while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) { - tick(); - if ((err)&&((m_core->o_rtn_err)||(m_core->o_rtn_miss))) { - if (!*err) { - m_miss = (m_core->o_rtn_miss); - m_err = (m_core->o_rtn_err); - } *err = true; - m_core->i_ctrl_cyc_stb = 0; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - return 0; - } - } - } tick(); - - m_core->i_wbm_stb = 0; - - while((errcount++ < BOMBCOUNT)&&(!m_core->o_rtn_ack)) { - tick(); - if ((err)&&((m_core->o_rtn_err)||(m_core->o_rtn_miss))) { - if (!*err) { - m_miss = (m_core->o_rtn_miss); - m_err = (m_core->o_rtn_err); - } *err = true; - m_core->i_ctrl_cyc_stb = 0; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - return 0; - } - } - - - result = m_core->o_rtn_data; - assert(!m_core->o_rtn_err); - assert(!m_core->o_rtn_miss); - - // Release the bus? - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - - if(errcount >= BOMBCOUNT) { - printf("SETTING ERR TO TRUE!!!!! (BOMB)\n"); - m_bomb = true; - } else if (!m_core->o_rtn_ack) { - printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n"); - m_bomb = true; - } - tick(); - - assert(!m_core->o_rtn_ack); - assert(!m_core->o_rtn_miss); - assert(!m_core->o_rtn_err); - assert(!m_core->o_rtn_stall); - - return result; - } - - void wb_read(unsigned a, int len, unsigned *buf, bool *err) { - int errcount = 0; - int THISBOMBCOUNT = BOMBCOUNT * len; - int cnt, rdidx, inc; - - if (err) *err = false; - printf("WB-READM(%08x, %d)\n", a, len); - - while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) - wb_tick(); - - if (errcount >= BOMBCOUNT) { - printf("WB-READ(%d): Setting bomb to true (errcount = %d)\n", __LINE__, errcount); - m_bomb = true; - return; - } - - errcount = 0; - - m_core->i_ctrl_cyc_stb = 0; - m_core->i_wbm_cyc = 1; - m_core->i_wbm_stb = 1; - m_core->i_wb_we = 0; - m_core->i_wb_addr = a; - - rdidx =0; cnt = 0; - inc = 1; - - do { - int s; - s = (m_core->o_rtn_stall==0)?0:1; - tick(); - if (!s) - m_core->i_wb_addr += inc; - cnt += (s==0)?1:0; - if (m_core->o_rtn_ack) - buf[rdidx++] = m_core->o_rtn_data; - if ((err)&&((m_core->o_rtn_err)||(m_core->o_rtn_miss))) { - if (!*err) { - m_miss = (m_core->o_rtn_miss); - m_err = (m_core->o_rtn_err); - } *err = true; - m_core->i_ctrl_cyc_stb = 0; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - return; - } - } while((cnt < len)&&(errcount++ < THISBOMBCOUNT)); - - m_core->i_wbm_stb = 0; - - while((rdidx < len)&&(errcount++ < THISBOMBCOUNT)) { - tick(); - if ((err)&&((m_core->o_rtn_err)||(m_core->o_rtn_miss))) { - if (!*err) { - m_miss = (m_core->o_rtn_miss); - m_err = (m_core->o_rtn_err); - } *err = true; - m_core->i_ctrl_cyc_stb = 0; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - return; - } - if (m_core->o_rtn_ack) - buf[rdidx++] = m_core->o_rtn_data; - } - - // Release the bus? - m_core->i_wbm_cyc = 0; - - if(errcount >= THISBOMBCOUNT) { - printf("SETTING ERR TO TRUE!!!!! (errcount=%08x, THISBOMBCOUNT=%08x)\n", errcount, THISBOMBCOUNT); - m_bomb = true; - } else if (!m_core->o_rtn_ack) { - printf("SETTING ERR TO TRUE--NO ACK, NO TIMEOUT\n"); - m_bomb = true; - } - tick(); - assert(!m_core->o_rtn_ack); - assert(!m_core->o_rtn_miss); - assert(!m_core->o_rtn_err); - assert(!m_core->o_rtn_stall); - } - - void wb_write(unsigned a, unsigned v, bool *err) { - int errcount = 0; - - if (err) *err = false; - printf("WB-WRITEM(%08x) <= %08x\n", a, v); - m_core->i_ctrl_cyc_stb = 0; - m_core->i_wbm_cyc = 1; - m_core->i_wbm_stb = 1; - m_core->i_wb_we = 1; - m_core->i_wb_addr= a; - m_core->i_wb_data= v; - - if (m_core->o_rtn_stall) - while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) { - printf("Stalled, so waiting, errcount=%d\n", errcount); - tick(); - if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) { - if (!*err) { - m_miss = (m_core->o_rtn_miss); - m_err = (m_core->o_rtn_err); - } *err = true; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - return; - } - } - tick(); - if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) { - if (!*err) { - m_miss = (m_core->o_rtn_miss); - m_err = (m_core->o_rtn_err); - } *err = true; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - return; - } - - m_core->i_wbm_stb = 0; - - while((errcount++ < BOMBCOUNT)&&(!m_core->o_rtn_ack)) { - tick(); - if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) { - if (!*err) { - m_miss = (m_core->o_rtn_miss); - m_err = (m_core->o_rtn_err); - } *err = true; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - return; - } - } tick(); - if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) { - if (!*err) { - m_miss = (m_core->o_rtn_miss); - m_err = (m_core->o_rtn_err); - } *err = true; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - return; - } - - // Release the bus? - m_core->i_ctrl_cyc_stb = 0; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - - if(errcount >= BOMBCOUNT) { - printf("SETTING ERR TO TRUE!!!!! (BOMB) (LINE=%d, count=%d)\n",__LINE__, errcount); - m_bomb = true; - } tick(); - assert(!m_core->o_rtn_ack); - assert(!m_core->o_rtn_miss); - assert(!m_core->o_rtn_err); - assert(!m_core->o_rtn_stall); - } - - void wb_write(unsigned a, unsigned int ln, unsigned *buf, bool *err) { - unsigned errcount = 0, nacks = 0; - if (err) *err = false; - - printf("WB-WRITEM(%08x, %d, ...)\n", a, ln); - m_core->i_ctrl_cyc_stb = 0; - m_core->i_wbm_cyc = 1; - m_core->i_wbm_stb = 1; - m_core->i_wb_we = 1; - for(unsigned stbcnt=0; stbcnti_wb_addr= a+stbcnt; - m_core->i_wb_data= buf[stbcnt]; - errcount = 0; - - while((errcount++ < BOMBCOUNT)&&(m_core->o_rtn_stall)) { - tick(); - if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) { - if (!*err) { - m_miss = (m_core->o_rtn_miss); - m_err = (m_core->o_rtn_err); - } *err = true; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - return; - } - if (m_core->o_rtn_ack) nacks++; - } - // Tick, now that we're not stalled. This is the tick - // that gets accepted. - tick(); if (m_core->o_rtn_ack) nacks++; - if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) { - if (!*err) { - m_miss = (m_core->o_rtn_miss); - m_err = (m_core->o_rtn_err); - } *err = true; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - return; - } - } - - m_core->i_wbm_stb = 0; - - errcount = 0; - while((nacks < ln)&&(errcount++ < BOMBCOUNT)) { - tick(); - if (m_core->o_rtn_ack) { - nacks++; - errcount = 0; - } - if ((err)&&((m_core->o_rtn_miss)||(m_core->o_rtn_err))) { - if (!*err) { - m_miss = (m_core->o_rtn_miss); - m_err = (m_core->o_rtn_err); - } *err = true; - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - tick(); - return; - } - } - - // Release the bus - m_core->i_wbm_cyc = 0; - m_core->i_wbm_stb = 0; - - if(errcount >= BOMBCOUNT) { - printf("SETTING ERR TO TRUE!!!!! (BOMB)\n"); - m_bomb = true; - } tick(); - assert(!m_core->o_rtn_ack); - assert(!m_core->o_rtn_miss); - assert(!m_core->o_rtn_err); - assert(!m_core->o_rtn_stall); - } - - bool miss(void) { - return m_miss; - } bool err(void) { - return m_err; - } - - bool bombed(void) const { return m_bomb; } - - bool debug(void) const { return m_debug; } - bool debug(bool nxtv) { return m_debug = nxtv; } -}; - -void uload(unsigned len, unsigned *buf) { - FILE *fp = fopen("/dev/urandom", "r"); - - if ((NULL == fp)||(len != fread(buf, sizeof(unsigned), len, fp))) { - for(int i=0; i<(int)len; i++) - buf[i] = ((unsigned)rand()); - } if (NULL == fp) - fclose(fp); -} - -void install_page(ZIPMMU_TB *tb, int idx, unsigned va, unsigned pa, int flags) { - int LGTBL, LGPGSZ, LGCTXT; - int c; - unsigned base; - bool hdebug = tb->debug(); - - tb->debug(false); - c=tb->setup_read(0); - printf("CONTEXT-REG = %08x\n", c); - LGTBL = ((c>>24)&15); - LGPGSZ= (((c>>20)&15)+8)&31; - LGCTXT= (((c>>16)&15)+1)&31; - c &= ((1< %08xP %s%s\n", - idx, c, va, pa, - (flags&MMUFLAG_RONW)?"RO":" ", - (flags&MMUFLAG_CCHE)?"Cachable":""); - tb->setup_write(base , va|(( c &0x0ff)<<4)|flags); - tb->setup_write(base+1, pa|(((c>>8)&0x0ff)<<4)|flags); - tb->debug(hdebug); -} - -int main(int argc, char **argv) { - Verilated::commandArgs(argc, argv); - ZIPMMU_TB *tb = new ZIPMMU_TB; - unsigned *rdbuf; // *mbuf; - unsigned mlen = (1<opentrace("zipmmu_tb.vcd"); - printf("Giving the core 2 cycles to start up\n"); - // Before testing, let's give the unit time enough to warm up - tb->reset(); - for(int i=0; i<2; i++) - tb->wb_tick(); - - mlen = 1<<16; - - printf("Getting some memory ...\n"); - rdbuf = new unsigned[mlen]; - // mbuf = new unsigned[mlen]; // Match buffer - printf("Charging my memory with random values\n"); - uload(mlen, rdbuf); - - - int LGADR, LGTBL, LGPGSZ, LGCTXT, sr; - - c=tb->setup_read(0); - printf("CONTROL-REG = %08x\n = %2d\n", c, c); - sr = tb->setup_read(1); - printf("STATUS-REG = %08x = %2d\n", sr, sr); - LGADR = (((c>>28)&15)+17)&31; - LGTBL = ((c>>24)&15); - LGPGSZ= (((c>>20)&15)+8)&31; - LGCTXT= (((c>>16)&15)+1)&31; - printf("LGADR = %08x = %2d\n", LGADR, LGADR); - printf("LGTBL = %08x = %2d\n", LGTBL, LGTBL); - printf("LGPGSZ = %08x = %2d\n", LGPGSZ, LGPGSZ); - printf("LGCTXT = %08x = %2d\n", LGCTXT, LGCTXT); - - // First, let's make sure we can read/write the context - printf("\n\nTest: Can we read/write the context register?\n"); - tb->setup_write(0,0x01fec); - c=tb->setup_read(0); - printf("CONTEXT = %08x (0x1fec?)\n", c&0x0ffff); - if ((c&0x0ffff) != 0x01fec) - goto test_failure; - - // Load the table with TLB misses - printf("\n\nTest: Can we load the table with TLB misses? (%d entries)\n", (1<setup_write((2<setup_write((2<setup_read((2<setup_read((2< %08x\n", i, v, p); - if (v != (unsigned)(0x00f72+(((1<wb_write(0xffffffff, 0x0fe, &tberr); - if ((!tberr)||(!tb->miss())||(tb->err())) { - printf("TBERR = %s\nMISS = %s\nERR = %s\n", - (tberr)?"true":"false", (tb->miss())?"true":"false", - (tb->err())?"true":"false"); - goto test_failure; - } - - tberr = false; - install_page(tb, 0, 0x0ffffffff, (1<wb_write(0xffffffff, 0x0fe, &tberr); - if ((!tberr)||(!tb->miss())||(tb->err())) { - printf("TBERR = %s\nMISS = %s\nERR = %s\n", - (tberr)?"true":"false", (tb->miss())?"true":"false", - (tb->err())?"true":"false"); - goto test_failure; - } - - tberr = false; - printf("\n\nTest: What if we make this into a writeable page?\n"); - install_page(tb, 0, 0xffffffff, (1<wb_write(0xffffffff, 0x0fe, &tberr); - if (tberr) { - printf("TBERR = %s\nMISS = %s\nERR = %s\n", - (tberr)?"true":"false", (tb->miss())?"true":"false", - (tb->err())?"true":"false"); - goto test_failure; - } - printf("\n\nTest: Is the next access done w/in a single clock?\n"); - tb->wb_write(0xfffffff7, 0xdeadbeef, &tberr); - if (tberr) { - printf("TBERR = %s\nMISS = %s\nERR = %s\n", - (tberr)?"true":"false", (tb->miss())?"true":"false", - (tb->err())?"true":"false"); - goto test_failure; - } - - - tberr = false; - printf("\n\nTest: What if we make this into a writeable page?\n"); - install_page(tb, 0, 0xffffffff, (1<wb_write(0xffffffff, 0x0fe, &tberr); - if ((tberr)||((*tb)[0x0fff]!=0x0fe)) { - unsigned v; - v = ((*tb)[0x0fff]!=0x0fe); - printf("V = 0x%08x (!= 0x0fe?)\nTBERR = %s\nMISS = %s\nERR = %s\n", - v, (tberr)?"true":"false", (tb->miss())?"true":"false", - (tb->err())?"true":"false"); - goto test_failure; - } - - tberr = false; - printf("\n\nTest: How about a read from the same location?\n"); - { - unsigned v; - v = tb->wb_read(0xffffffff, &tberr); - if ((tberr)||(v != 0x0fe)) { - printf("V = 0x%08x (!= 0x0fe?)\nTBERR = %s\nMISS = %s\nERR = %s\n", - v, - (tberr)?"true":"false", (tb->miss())?"true":"false", - (tb->err())?"true":"false"); - goto test_failure; - } - } - - printf("Test: Burst write, within page\n"); - tb->setup_write(0, 0x0dad); - install_page(tb, 0, ((0x0ffffffffl)&(-(1l<wb_write(((0xffffffff)&(-(1l<miss())?"true":"false", - (tb->err())?"true":"false"); - printf("STATUS= %08x\n", tb->setup_read(1)); - goto test_failure; - } for(unsigned i=0; iwb_read(((0xffffffff)&(-(1<miss())?"true":"false", - (tb->err())?"true":"false"); - printf("STATUS= %08x\n", tb->setup_read(1)); - goto test_failure; - } for(unsigned i=0; itick(); - printf("TEST FAILED\n"); - exit(-1); -} Index: trunk/sim/cpp/zsim.cpp =================================================================== --- trunk/sim/cpp/zsim.cpp (revision 204) +++ trunk/sim/cpp/zsim.cpp (nonexistent) @@ -1,1102 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Filename: zsim.cpp -// -// Project: Zip CPU -- a small, lightweight, RISC CPU soft core -// -// Purpose: The main portion of a Simulator, not based upon any RTL or -// Verilog code. Why? To get something up and running and testing -// faster (even though the Verilog should be working/running?). -// -// -// Creator: Dan Gisselquist, Ph.D. -// Gisselquist Technology, LLC -// -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015-2016, Gisselquist Technology, LLC -// -// This program is free software (firmware): you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// License: GPL, v3, as defined and found on www.gnu.org, -// http://www.gnu.org/licenses/gpl.html -// -// -//////////////////////////////////////////////////////////////////////////////// -// -// -#include -#include -#include -#include -#include -#include -#include -#include -#include "twoc.h" -#include "zipelf.h" - -#define CC_CLRCACHE (1<<14) -#define CC_PHASE_BIT (1<<13) -#define CC_PHASE (1<<13) -#define CC_FPUERR (1<<12) -#define CC_DIVERR (1<<11) -#define CC_BUSERR (1<<10) -#define CC_TRAP (1<<9) -#define CC_ILL (1<<8) -#define CC_BREAK (1<<7) -#define CC_STEP (1<<6) -#define CC_GIE (1<<5) -#define CC_SLEEP (1<<4) -#define CC_V (1<<3) -#define CC_N (1<<2) -#define CC_C (1<<1) -#define CC_Z (1 ) - -class SIMDEV { -public: - virtual uint32_t lw(uint32_t addr) = 0; - virtual void sw(uint32_t addr, uint32_t vl) = 0; - - virtual uint32_t lb(uint32_t addr) { - uint32_t v = lw(addr&-4); - - // fprintf(stderr, "\tLH(%08x) -> %08x", addr, v); - v >>= (8*(3-(addr&3))); - // fprintf(stderr, " -> %08x", v); - v &= 0x0ff; - // fprintf(stderr, " -> %02x\n", v); - return v; - } - virtual uint32_t lh(uint32_t addr) { - uint32_t v = lw(addr&-4); - - // fprintf(stderr, "\tLH(%08x) -> %08x", addr, v); - if ((addr&2)==0) - v >>= 16; - // fprintf(stderr, " -> %08x", v); - v &= 0x0ffff; - // fprintf(stderr, " -> %04x\n", v); - return v; - } - - virtual void sh(uint32_t addr, uint32_t vl) { - uint32_t v = (vl & 0x0ffff); - v = v | (v<<16); - sw(addr, v); - } - - virtual void sb(uint32_t addr, uint32_t vl) { - uint32_t v = (vl & 0x0ff); - v = v | (v<<16); - v = v | (v<<8); - sw(addr, v); - } - - virtual bool interrupt(void) { return false; }; - virtual void tick(void) {}; - - virtual void load(uint32_t addr, const char *buf, size_t ln) {} -}; - -class UARTDEV : public SIMDEV { - uint32_t m_setup; - bool m_debug; -public: - UARTDEV(void) { m_setup = 868; m_debug = false; } - - virtual uint32_t lw(uint32_t addr) { - switch(addr&0x0c) { - case 0: return m_setup; - case 4: return 0; - case 8: return 0x100; - case 12: return 0; - } return 0; - } - - virtual void sw(uint32_t addr, uint32_t vl) { - if (m_debug) fprintf(stderr, - "UART->SW(%08x, %08x)\n", addr, vl); - switch(addr&0x0c) { - case 0: m_setup = vl & 0x3fffffff; break; - case 4: break; - case 8: break; - case 12: putchar(vl & 0x0ff); - } - } -}; - - -class MEMDEV : public SIMDEV { -protected: - char *m_mem; - bool m_dbg; -public: - MEMDEV(int nbits) { - m_mem = new char[(1< %02x:%02x:%02x:%02x -> v=%08x\n", addr, - a, b, c, d, v); - - return v; - } - - virtual void sw(uint32_t addr, uint32_t vl) { - uint32_t maddr = addr & -4; - m_mem[(maddr) ] = (vl >>24)&0x0ff; - m_mem[(maddr)+1] = (vl >>16)&0x0ff; - m_mem[(maddr)+2] = (vl >> 8)&0x0ff; - m_mem[(maddr)+3] = (vl )&0x0ff; - - if (m_dbg) - fprintf(stderr, - "\tSW %08x <- %08x - %02x:%02x:%02x:%02x\n", - addr, vl, m_mem[(maddr) ] & 0x0ff, - m_mem[(maddr)+1] & 0x0ff, - m_mem[(maddr)+2] & 0x0ff, - m_mem[(maddr)+3] & 0x0ff); - } - - virtual void sh(uint32_t addr, uint32_t vl) { - uint32_t maddr = addr & -2; - m_mem[(maddr) ] = (vl >> 8)&0x0ff; - m_mem[(maddr)+1] = (vl )&0x0ff; - if (m_dbg) - fprintf(stderr, "\tSH %08x <- %04x - %02x:%02x\n", - addr, vl & 0x0ffff, m_mem[(maddr) ] & 0x0ff, - m_mem[(maddr)+1] & 0x0ff); - } - - virtual void sb(uint32_t addr, uint32_t vl) { - m_mem[addr] = vl; - if (m_dbg) - fprintf(stderr, "\tSB %08x <- %02x\n", - addr, vl & 0x0ff); - } - - void load(uint32_t addr, const char *src, size_t n) { - memcpy(&m_mem[addr], src, n); - } -}; - -class ROMDEV : public MEMDEV { -public: - ROMDEV(int nbits) : MEMDEV(nbits) {} - - // virtual uint32_t lw(uint32_t addr); - virtual void sw(uint32_t addr, uint32_t vl) {} - virtual void sh(uint32_t addr, uint32_t vl) {} - virtual void sb(uint32_t addr, uint32_t vl) {} - void load(uint32_t addr, const char *src, size_t n) { - memcpy(&m_mem[addr], src, n); - } -}; - -#ifndef L_OK -#define L_OK 8 // Okay for loads -#endif - -class SIMENTRY { -public: - SIMDEV *m_dev; - uint32_t m_addr, m_mask; - int m_flags; - char *m_name; -}; - -class SIMBUS { - bool m_buserr; - std::vector m_devlist; - int getdev(uint32_t addr) { - for(size_t i=0; im_mask)==m_devlist[i]->m_addr){ - return i; - } - - /* - fprintf(stderr, "GETDEV(0x%08x) - not found\n", addr); - for(size_t i=0; im_mask, - addr & m_devlist[i]->m_mask, - m_devlist[i]->m_addr); - } */ - - return -1; - } - int getwrdev(uint32_t addr) { - int devid = getdev(addr); - if (0 <= devid) { - if (m_devlist[devid]->m_flags & W_OK) - return devid; -fprintf(stderr, "ADDRESS %08x in %s is not writable!!\n", addr, m_devlist[devid]->m_name); - } -else fprintf(stderr, "ADDRESS %08x not found\n", addr); - return -1; - } - int getexdev(uint32_t addr) { - int devid = getdev(addr); - if (0 <= devid) { - if (m_devlist[devid]->m_flags & X_OK) - return devid; - fprintf(stderr, "Address in %s is not executable\n", m_devlist[devid]->m_name); - } - fprintf(stderr, "ExDEV not found (0x%08x), devid = %d\n", addr, devid); - return -1; - } -public: - SIMBUS(void) { m_buserr = false; } - void add(SIMDEV *dev, uint32_t addr, uint32_t mask, const char *p, const char *name = "") { - SIMENTRY *s = new SIMENTRY; - - s->m_dev = dev; - s->m_addr= addr; - s->m_mask= mask; - s->m_name= strdup(name); - s->m_flags= 0; - - if ((strchr(p, 'w'))||(strchr(p, 'W'))) - s->m_flags |= W_OK; - if ((strchr(p, 'r'))||(strchr(p, 'R'))) - s->m_flags |= R_OK; - if ((strchr(p, 'x'))||(strchr(p, 'X'))) - s->m_flags |= X_OK; - if ((strchr(p, 'l'))||(strchr(p, 'L'))) - s->m_flags |= L_OK; - m_devlist.push_back(s); - } - - uint32_t lb(uint32_t addr) { - int devid; - if (0 <= (devid = getdev(addr))) - return m_devlist[devid]->m_dev->lb(addr & (~m_devlist[devid]->m_mask)); - m_buserr = true; - return 0; - } - uint32_t lh(uint32_t addr) { - int devid; - if (0 <= (devid = getdev(addr))) - return m_devlist[devid]->m_dev->lh(addr & ((~m_devlist[devid]->m_mask)&-2)); - m_buserr = true; - return 0; - } - uint32_t lw(uint32_t addr) { - int devid; - if (0 <= (devid = getdev(addr))) - return m_devlist[devid]->m_dev->lw(addr & ((~m_devlist[devid]->m_mask)&-4)); - m_buserr = true; - return 0; - } - uint32_t lx(uint32_t addr) { - int devid; - if (0 <= (devid = getexdev(addr))) - return m_devlist[devid]->m_dev->lw(addr & ((~m_devlist[devid]->m_mask)&-4)); - m_buserr = true; - return 0; - } - void sb(uint32_t addr, uint32_t vl) { - int devid; - if (0 <= (devid = getwrdev(addr))) { - return m_devlist[devid]->m_dev->sb(addr & (~m_devlist[devid]->m_mask), vl & 0x0ff); - } else { - fprintf(stderr, "No such address, %08x\n", addr); - } - m_buserr = true; - return; - } - void sh(uint32_t addr, uint32_t vl) { - int devid; - if (0 <= (devid = getwrdev(addr))) - return m_devlist[devid]->m_dev->sh(addr & -2 & (~m_devlist[devid]->m_mask), vl & 0x0ffff); - m_buserr = true; - return; - } - void sw(uint32_t addr, uint32_t vl) { - int devid; - if (0 <= (devid = getwrdev(addr))) - return m_devlist[devid]->m_dev->sw(addr & -4 & (~m_devlist[devid]->m_mask), vl); - m_buserr = true; - return; - } - bool interrupt(void) { return false; }; - - bool error(void) { - bool tmp = m_buserr; - m_buserr = false; - return tmp; - } - - void tick(void) { - for(size_t i=0; im_dev->tick(); - } - - void load(uint32_t addr, const char *data, size_t len) { - int devid; - if ((0 <= (devid = getdev(addr))) - &&(m_devlist[devid]->m_flags & L_OK)) - m_devlist[devid]->m_dev->load( - addr & (~m_devlist[devid]->m_mask), data, len); - else { - fprintf(stderr, "DEVID = %d\n", devid); - m_buserr = true; - } return; - } -}; - -class ZIPMACHINE { - bool m_gie, m_jumped, m_advance_pc, m_locked; - int m_lockcount; - unsigned long m_icount; -public: - uint32_t m_r[32]; - SIMBUS *m_bus; - FILE *m_mapf; - - ZIPMACHINE(void) { - m_locked = false; m_lockcount = 0; - m_mapf = NULL; - m_bus = NULL; - m_gie = false; - m_jumped= m_advance_pc = false; - m_icount = 0; - } - - void dump() { - fflush(stderr); - fflush(stdout); - printf("ZIPM--DUMP: "); - if (gie()) - printf("Interrupts-enabled\n"); - else - printf("Supervisor mode\n"); - printf("\n"); - - printf("sR0 : %08x ", m_r[0]); - printf("sR1 : %08x ", m_r[1]); - printf("sR2 : %08x ", m_r[2]); - printf("sR3 : %08x\n",m_r[3]); - printf("sR4 : %08x ", m_r[4]); - printf("sR5 : %08x ", m_r[5]); - printf("sR6 : %08x ", m_r[6]); - printf("sR7 : %08x\n",m_r[7]); - printf("sR8 : %08x ", m_r[8]); - printf("sR9 : %08x ", m_r[9]); - printf("sR10: %08x ", m_r[10]); - printf("sR11: %08x\n",m_r[11]); - printf("sR12: %08x ", m_r[12]); - printf("sSP : %08x ", m_r[13]); - printf("sCC : %08x ",(m_r[14] & (~CC_GIE))); - printf("sPC : %08x\n",m_r[15]); - - printf("\n"); - - printf("uR0 : %08x ", m_r[16]); - printf("uR1 : %08x ", m_r[17]); - printf("uR2 : %08x ", m_r[18]); - printf("uR3 : %08x\n",m_r[19]); - printf("uR4 : %08x ", m_r[20]); - printf("uR5 : %08x ", m_r[21]); - printf("uR6 : %08x ", m_r[22]); - printf("uR7 : %08x\n",m_r[23]); - printf("uR8 : %08x ", m_r[24]); - printf("uR9 : %08x ", m_r[25]); - printf("uR10: %08x ", m_r[26]); - printf("uR11: %08x\n",m_r[27]); - printf("uR12: %08x ", m_r[28]); - printf("uSP : %08x ", m_r[29]); - printf("uCC : %08x ",(m_r[30]|CC_GIE)); - printf("uPC : %08x\n",m_r[31]); - printf("\n"); - fflush(stderr); - fflush(stdout); - } - - void ccodes(uint32_t newflags) { - m_r[14+rbase()] = (cc() & -16)|(newflags&0x0f); - } - - int rbase(void) { return m_gie?16:0; } - bool gie() { return m_gie; }; - bool locked() { return m_locked; }; - bool sleeping() { - return (gie())&&(m_r[14+16]&CC_SLEEP)?true:false; - }; - bool sleep(bool nv) { - if (nv) { - m_r[14 ] |= CC_SLEEP; - m_r[14+16] |= CC_SLEEP; - } else { - m_r[14 ] &= (~CC_SLEEP); - m_r[14+16] &= (~CC_SLEEP); - } return sleeping(); - }; - bool halted() { - return (!gie()) && (m_r[14]&CC_SLEEP); - }; - uint32_t cc() { return m_r[14+rbase()]|((m_gie)?CC_GIE:0); }; - bool fault() { - if (cc() & (CC_PHASE|CC_ILL|CC_BREAK|CC_BUSERR|CC_DIVERR)) - return true; - return false; - } - bool gie(bool v) { - m_jumped = (m_gie != v); - m_gie = v; - return v; - } - bool jumped(void) { return m_jumped; }; - void pc_advance(bool pcgie) { - m_r[15+((pcgie)?16:0)] += 4; - m_r[15+((pcgie)?16:0)] &= -4; - } void pc_advance(void) { pc_advance(gie()); } - uint32_t pc(void) { - return m_r[15+rbase()]; - } - - static uint32_t bitreverse(uint32_t bv) { - uint32_t b, r=0; - for(b=0; b<32; b++, bv>>=1) - r = (r<<1)|(bv&1); - return r; - } - - void init(SIMBUS *bus) { - m_bus = bus; - for(int i=0; i<32; i++) - m_r[i] = 0; - m_gie = false; - } - - void siminsn(uint32_t insn) { - // fprintf(stderr, "SIM-INSN(0x%08x)\n", insn); - if ((insn & 0x0fffff)==0x00100) { - // SIM Exit(0) - exit(0); - } else if ((insn & 0x0ffff0)==0x00310) { - // SIM Exit(User-Reg) - int rcode; - rcode = m_r[(insn&0x0f)+16] & 0x0ff; - exit(rcode); - } else if ((insn & 0x0ffff0)==0x00300) { - // SIM Exit(Reg) - int rcode; - rcode = m_r[(insn&0x0f)+rbase()] & 0x0ff; - exit(rcode); - } else if ((insn & 0x0fff00)==0x00100) { - // SIM Exit(Imm) - int rcode; - rcode = insn & 0x0ff; - exit(rcode); - } else if ((insn & 0x0fffff)==0x002ff) { - // Full/unconditional dump - fprintf(stderr, "SIM-DUMP\n"); - dump(); - } else if ((insn & 0x0ffff0)==0x00200) { - // Dump a register - int rid = (insn&0x0f)+rbase(); - fprintf(stderr, "R[%2d] = 0x%08x\n", rid, m_r[rid]); - } else if ((insn & 0x0ffff0)==0x00210) { - // Dump a user register - int rid = (insn&0x0f); - fprintf(stderr, "uR[%2d] = 0x%08x\n", rid, m_r[rid+16]); - } else if ((insn & 0x0ffff0)==0x00230) { - // SOUT[User Reg] - int rid = (insn&0x0f)+16; - fprintf(stderr, "%c", m_r[rid]&0x0ff); - } else if ((insn & 0x0fffe0)==0x00220) { - // SOUT[User Reg] - int rid = (insn&0x0f)+rbase(); - fprintf(stderr, "%c", m_r[rid]&0x0ff); - } else if ((insn & 0x0fff00)==0x00400) { - // SOUT[Imm] - fprintf(stderr, "%c", insn&0x0ff); - } else { // if ((insn & 0x0f7c00000)==0x77800000) - uint32_t imm = insn & 0x03fffff; - // Simm instruction that we dont recognize - // if (imm) - fprintf(stderr, "SIM 0x%08x\n", imm); - } - } - - void fullinsn(uint32_t insn) { - bool wf, wb, fpu, noop, lock, wbreak, cmptst, mem, - sto, ldi, mov, div, execinsn; - bool diverr, illegal; - uint32_t av, bv, result, f, arg, brg, opc; - int32_t imm; - int rb, cnd; - const bool dbg = false; - - m_icount ++ ; - - if (dbg) { - fprintf(stderr, "%8ld INSN(@0x%08x, %08x)", m_icount, pc(), insn); - if (m_mapf) { - // bool dbg = pc() == 0x040003cc; - char line[512], needle[512], *ptr = NULL,*lp; - sprintf(needle, "%08x", pc()); - rewind(m_mapf); - while(NULL != (lp = fgets(line, sizeof(line), m_mapf))) { - while((*lp)&&(isspace(*lp))) - lp++; - if ((*lp != '0')||(tolower(*lp) == 'x')) - continue; - // if (dbg)fprintf(stderr, "\tMAP (%s?) %s\n", needle, lp); - if (NULL != (ptr = strstr(lp, needle))){ - break; - } - } if (ptr) { - if (strlen(ptr) > 8) - ptr += 8; - while((*ptr)&&(isspace(*ptr))) - ptr++; - int ln = strlen(ptr); - while((ln > 0)&&(isspace(ptr[ln-1]))) - ptr[--ln] = '\0'; - fprintf(stderr, "\t%s", ptr); - } else if (0x7b400000 == (insn&0x7fffffff)) - fprintf(stderr, "\treturn"); - } else fprintf(stderr, "\tNO-MAPF"); - fprintf(stderr, "\n"); - } - m_jumped = false; - m_advance_pc = true; - illegal = false; - noop = false; - lock = false; - wbreak = false; - - if (m_locked) { - m_lockcount--; - if (m_lockcount <= 0) - m_locked = false; - } - - m_r[14+rbase()] - &= ~(CC_ILL|CC_BREAK|CC_BUSERR|CC_DIVERR); - - opc = (insn >> 22) & 0x01f; - arg = (insn >> 27) & 0x0f; - brg = (insn >> 14) & 0x0f; - - cmptst=((opc&0x1e)==0x010); - mem = ((opc&0x1c) == 0x014)||((opc&0x1e) == 0x012); - sto = (mem)&&(opc&1); - fpu =(((opc&0x1c)==0x1c) // Top four FPU ops - ||((opc&0x1e)==0x1a)); // Bottom two FPU ops - div =((opc&0x1e)==0x0e); - ldi =((opc&0x1e)==0x18); - mov =((opc&0x1f)==0x0d); - - if (ldi) imm = sbits(insn, 23); - else if (mov) imm = sbits(insn, 13); - else if (insn & 0x040000) - imm = sbits(insn, 14); - else imm = sbits(insn, 18); - - // Do we read the B register? - rb = (mov)||(((insn>>18)&1)&&(!ldi)); - - // WriteBack - wb = (!cmptst)&&(!sto); - - // Do we write flags back? - wf = true; - if (ldi) wf = false; - if (mov) wf = false; - if (mem) wf = false; - if (opc==0x08) wf = false; // BREV - if (opc==0x09) wf = false; // LDILO - if ((!cmptst)&&((arg & 0x0e)==0x0e)) // Writes to CC or PC - wf = false; // dont set the flags. - - cnd = (ldi) ? 0 : ((insn >> 19) & 7); - - if (fpu & ((arg&0x0e)==0x0e)) { - fpu = false; - noop = ((opc&0x1e) == 0x1e); - lock = ((opc&0x1f) == 0x1d); - wbreak = ((opc&0x1f) == 0x1c); - illegal = !(noop|lock|wbreak); - wb = false; - wf = false; - cnd = 0; - } else if (div & ((arg&0x0e)==0x0e)) { - illegal = true; - } - - if (cnd != 0) { - if (!cmptst) - wf = false; - int ccodes = cc() & 0x0f; - switch(cnd) { - case 1: execinsn = (ccodes & CC_Z); break; - case 2: execinsn = (ccodes & CC_N); break; - case 3: execinsn = (ccodes & CC_C); break; - case 4: execinsn = (ccodes & CC_V); break; - case 5: execinsn = ((ccodes & CC_Z)==0); break; // NZ - case 6: execinsn = ((ccodes & CC_N)==0); break; // GE - case 7: execinsn = ((ccodes & CC_C)==0); break; // NC - default: execinsn = true; break; - } - } else - execinsn = true; - - if ((mov)&&(!gie())) { - // Supervisor can read all registers - arg |= (insn&0x40000)?0x10:0; - brg |= (insn&0x02000)?0x10:0; - } else { - arg |= (gie())?0x10:0; - brg |= (gie())?0x10:0; - } - result = 0; - - bv = imm; - if (rb) { - if ((brg&0x0f)==15) { // PC - bv = (imm << 2) + m_r[brg]; - if (gie()) { - if (brg & 0x010) - bv += 4; - } else if ((brg & 0x10)==0) - bv += 4; - } else - bv += m_r[brg]; - } - av = m_r[arg]; - if ((int)arg == 15 + rbase()) - av += 4; - - if (execinsn) { - f = 0; // Resulting flags - if (fpu) { - float fva, fvb, fvr; - fva = *(float *)&av; - fvb = *(float *)&bv; - - switch(opc) { - case 26: fvr = fva + fvb; break; - case 27: fvr = fva - fvb; break; - case 28: fvr = fva * fvb; break; - case 29: fvr = fva / fvb; break; - case 30: fvr = (float)bv; break; - case 31: result = (int)fvb; break; - default: illegal = true; - } if (opc != 31) - result = *(uint32_t *)&fvr; - if (result == 0) - f = CC_Z; - if (opc == 31) { - if (result & 0x80000000) - f |= CC_N; - } else if (fvr < 0.0) - f |= CC_N; - } else if (noop) { - if (insn != 0x7fc00000) - siminsn(insn); - } else if (wbreak) { - wf = wb = false; - m_advance_pc = false; - if (gie()) { - m_r[16+14] &= CC_BREAK; - gie(false); - } else { - fprintf(stderr, "BREAK!\n"); - dump(); - exit(EXIT_FAILURE); - } - } else if (lock) { - m_locked = true; - m_lockcount = 3; - } else { - uint32_t presign = (av>>31)&1, nsgn; - switch(opc) { - case 0: case 16: { // SUB, or CMP - result = av - bv; - if (av < bv) - f |= CC_C; - nsgn = (result >> 31)&1; - if (presign != nsgn) - f |= CC_V; - } break; - case 1: case 17: result = bv & av; break;//AND or TST - case 2: { // ADD - result = bv + av; - if (result<(uint64_t)bv+(uint64_t)av) - f |= CC_C; - nsgn = (result >> 31)&1; - if (presign != nsgn) - f |= CC_V; - } break; - case 3: result = bv | av; break; // OR - case 4: result = bv ^ av; break; // XOR - case 5: { // LSR - uint32_t nsgn; - if (bv >= 32) - result = 0; - else - result = ((uint32_t)av >> bv); - nsgn = (result >> 31)&1; - if (presign != nsgn) - f |= CC_V; - - if ((bv !=0)&&(bv<33)&&(av&(1<<(bv-1)))) - f |= CC_C; - } break; - case 6: { // LSL - uint32_t nsgn; - if (bv >= 32) - result = 0; - else - result = av << bv; - nsgn = (result >> 31)&1; - if (presign != nsgn) - f |= CC_V; - if((bv !=0)&&(bv<33)&&(av&(1<<(33-bv)))) - f |= CC_C; - } break; - case 7: { // ASR - if ((bv >= 32)&&(av & 0x80000000)) - result = -1; - else if (bv >= 32) - result = 0; - else - result = ((int)av >> bv); - - if (av & 0x80000000) { - // Signed carry - if (bv >= 31) - f |= CC_C; - else if((bv != 0) - &&(av&(1<<(33-bv)))) - f |= CC_C; - } else { - // Unsigned carry - if((bv !=0)&&(bv<32) - &&(av&(1<<(33-bv)))) - f |= CC_C; - } - } break; - case 8: result = bitreverse(bv); break; // BREV - case 9: result = (av&0xffff0000)|(bv&0x0ffff); break; // LDILO - case 10: { // MPYUHI - uint64_t ulv = av * bv; - result = (ulv >> 32); - } break; - case 11: { // MPYSHI - int64_t lv = av * bv; - result = (lv >> 32); - } break; - case 12: { // MPY - int64_t ulv = av * bv; - // bool sn = (av<0)^(bv<0); - result = (int32_t)(ulv & 0x0ffffffff); - //if (((result&0x80000000)?1:0) - // ^ ((sn)?1:0)) - // f |= CC_V; - } break; - case 13: result = bv; break; // MOV - case 14: { // DIVU - if (bv == 0) - diverr = true; - else - result = (uint32_t)av - / (uint32_t)bv; - } break; - case 15: { // DIVS - if (bv == 0) - diverr = true; - else - result =(int32_t)av/(int32_t)bv; - } break; - // case 16: result = av - bv; break; - // case 17: result = av & bv; break; - case 18: result = m_bus->lw(bv); - break;// LW - case 19: - m_bus->sw(bv, av); break;// SW - case 20: result = m_bus->lh(bv);break;// LH - case 21: m_bus->sh(bv, av); break;// SH - case 22: result = m_bus->lb(bv);break;// LB - case 23: m_bus->sb(bv, av); break;// SB - case 24: result = bv; break;// LDI - case 25: result = bv; break;// LDI - default: illegal = true; - } - if (result == 0) - f |= CC_Z; - if (result & 0x80000000) - f |= CC_N; - } - - if (illegal) { - if (gie()) { - m_r[16+14] |= CC_ILL; - gie(false); - m_jumped = true; - m_advance_pc = false; - } else { - m_r[14] |= CC_ILL; - fprintf(stderr, "ILLegal Instruction Exception\n"); - dump(); - exit(EXIT_FAILURE); - } - } else if ((mem)&&(m_bus->error())) { - if (gie()) { - m_r[16+14] |= CC_BUSERR; - gie(false); - m_jumped = true; - m_advance_pc = false; - } else { - m_r[14] |= CC_BUSERR; - fprintf(stderr, "BUS ERR\n"); - dump(); - exit(EXIT_FAILURE); - } - } else if ((div)&&(diverr)) { - if (gie()) { - m_r[16+14] |= CC_DIVERR; - gie(false); - m_jumped = true; - m_advance_pc = false; - } else { - m_r[14] |= CC_DIVERR; - fprintf(stderr, "DIV ERR: division by zero\n"); - dump(); - exit(EXIT_FAILURE); - } - } if (wf) - ccodes(f); - if (wb) { - if (arg == (uint32_t)(15+rbase())) - m_jumped = true; - else if (arg == (uint32_t)(14+rbase())) { - if (gie()) { - if ((result & CC_GIE)==0) { - result |= CC_TRAP; - result &= (~(CC_SLEEP - |CC_ILL - |CC_BREAK - |CC_BUSERR - |CC_DIVERR - |CC_FPUERR - |CC_STEP - |CC_SLEEP)); - } - } else if (result & CC_GIE) { - // Returning to userspace - m_r[16+14] &= (~(CC_ILL - |CC_BREAK - |CC_BUSERR - |CC_DIVERR - |CC_FPUERR)); - } - } - if (dbg) fprintf(stderr, - "\tREG[%02x] = %08x\n", arg, result); - m_r[arg] = result; - if ((int)arg == 15+rbase()) - m_advance_pc = false; - if (((int)arg==14+rbase())&&(((m_gie)?1:0)^((result&CC_GIE)?1:0))) { - gie((result&CC_GIE)?true:false); - // Prevent us from advancing the PC - m_jumped = true; - // m_advance_pc = true; - } - // Some CC bits are constant. Keep them that - // way. - m_r[14 ] &= (~CC_GIE); - m_r[14+16] |= ( CC_GIE); - m_r[15 ] &= -4; - m_r[15+16] &= -4; - } - } - } - - void cisinsn(uint16_t insn) { - uint32_t imm; - int dr, br, cisop, fullop; - - cisop = (insn >> 8) & 0x07; - switch(cisop) { - case 0: fullop = 0; break; // SUB - case 1: fullop = 1; break; // AND - case 2: fullop = 2; break; // ADD - case 3: fullop = 16; break; // CMP - case 4: fullop = 18; break; // LW - case 5: fullop = 19; break; // SW - case 6: fullop = 24; break; // LDI - case 7: fullop = 13; break; // MOV - } - - dr = (insn>>11) & 0x0f; - - if (fullop == 24) { - // LDI - imm = sbits(insn, 8) & 0x07fffff; - fullinsn(0x80000000 | (dr<<27) | (fullop<<22) | imm); - } else if (fullop == 13) { - // MOV - br = (insn >> 3) & 0x0f; - imm = sbits(insn, 3) & 0x01fff; - fullinsn(0x80000000 | (dr << 27) | (fullop<<22) | (br<<14) | imm); - } else if (insn & 0x80) { - // Uses a breg - br = (insn >> 3) & 0x0f; - imm = sbits(insn, 3) & 0x3fff; - fullinsn(0x80040000 | (dr << 27) | (fullop<<22) | (br<<14) | imm); - } else if ((fullop == 18)||(fullop == 19)) { - // Load or store, breg is assumed to be SP -// 0x04844000 - br = 13; - imm = sbits(insn, 7) & 0x3fff; - fullinsn(0x80040000 | (dr << 27) | (fullop<<22) | (br<<14) | imm); - } else { - imm = sbits(insn, 7) & 0x03ffff; - fullinsn(0x80000000 | (dr << 27) | (fullop<<22) | imm); - } - } - - void execute(uint32_t insn) { - /// fprintf(stderr, "EXEC-INSN(@0x%08x - %08x)\n", pc(), insn); - bool igie = gie(); - if (insn & 0x80000000) { - int ibase = rbase(); - cisinsn((insn>>16) & 0x0ffff); - if (m_advance_pc) - m_r[14+ibase] |= (CC_PHASE); - if ((!m_jumped)&&(igie == gie())) { - cisinsn(insn & 0x0ffff); - m_r[14+ibase] &= ~(CC_PHASE); - } if (m_advance_pc) - pc_advance(igie); - m_jumped = false; - } else { - m_r[14+rbase()] &= ~(CC_PHASE); - fullinsn(insn); - - if (m_advance_pc) - pc_advance(igie); - - if ((gie())&&(cc() & CC_STEP)) - gie(false); - } - } -}; - -int main(int argc, char **argv) { - const char *executable = "a.out"; - SIMBUS *bus; - bool done; - ZIPMACHINE *zipm; - ELFSECTION **secpp, *secp; - uint32_t entry; - - if (argc > 1) - executable = argv[1]; - if (access(executable, R_OK)!=0) { - fprintf(stderr, "Cannot read %s\n", executable); - exit(EXIT_FAILURE); - } elfread(executable, entry, secpp); - if (0 == secpp[0]->m_len) { - fprintf(stderr, "Executable file has no contents!\n"); - exit(EXIT_FAILURE); - } - - // Timer at 0x0100? - // Buserr at 0x0101? - // Addresses are given in 32-bit glory, so they reference 8-bit bytes - bus = new SIMBUS(); - // BUSITEM net = new NETDEV(); - - bus->add(new UARTDEV(), 0x00000150, 0xfffffff0, "RW", "UART");// 4 words - // bus->add(new SDCDEV(12), 0x00000420, 0xfffffff0, "RW");// 4 words - // bus->add(net->ctrl, 0x00000440, 0xffffffe0, "RW");// 8 words - // bus->add(net->data, 0x00002000, 0xffffe000, "R"); // 8 words - // bus->add(net->data, 0x00003000, 0xffffe000, "R"); // 8 words - bus->add(new MEMDEV(17), 0x0020000, 0x7fe0000, "RWX", "BlockRAM");// Block RAM - bus->add(new ROMDEV(24),0x01000000,0xff000000, "RXL", "Flash"); // Flash - bus->add(new MEMDEV(28),0x10000000,0xf0000000, "RWX", "SDRAM");// SDRAM - - for(int s=0; secpp[s]->m_len; s++) { - secp = secpp[s]; - if (false) fprintf(stderr, - "Attempting to LOAD->(%08x, ..., %d)\n", - secp->m_start, secp->m_len); - bus->load(secp->m_start, (const char *)&secp->m_data[0], secp->m_len); - if (bus->error()) { - fprintf(stderr, "LOAD: Error writing to mem @ 0x%08x\n", secp->m_start); - // exit(EXIT_FAILURE); - } - } - - if(bus->error()) { - fprintf(stderr, "ERR: Executable file doesn\'t fit in simulator\n"); - exit(EXIT_FAILURE); - } - - done = false; - zipm = new ZIPMACHINE; - if (access("map.txt", R_OK)==0) - zipm->m_mapf = fopen("map.txt","r"); - zipm->init(bus); - zipm->m_r[15] = entry; - while(!done) { - uint32_t insn; - insn = bus->lx(zipm->pc()); - - if (bus->error()) { - if (zipm->gie()) { - zipm->m_r[14+16] |= CC_BUSERR; - zipm->gie(false); - continue; - } else { - zipm->m_r[14] |= CC_BUSERR; - fprintf(stderr, "IFetch BUSERR, %08x\n", zipm->pc()); - zipm->dump(); - exit(EXIT_FAILURE); - } - } else { - if (!zipm->sleeping()) - zipm->execute(insn); - } - - if (zipm->halted()) { - fflush(stderr); - fflush(stdout); - printf("CPU HALT\n"); - done = true; - break; - } - - bus->tick(); - if ((bus->interrupt())&&(zipm->gie())&&(!zipm->locked())) { - zipm->gie(false); - zipm->sleep(false); - } - } -} - Index: trunk/sim/cpp/zipelf.cpp =================================================================== --- trunk/sim/cpp/zipelf.cpp (revision 204) +++ trunk/sim/cpp/zipelf.cpp (nonexistent) @@ -1,246 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// Filename: zipelf.cpp -// -// Project: Zip CPU -- a small, lightweight, RISC CPU soft core -// -// Purpose: -// -// -// Creator: Dan Gisselquist, Ph.D. -// Gisselquist Technology, LLC -// -/////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015-2016, Gisselquist Technology, LLC -// -// This program is free software (firmware): you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// License: GPL, v3, as defined and found on www.gnu.org, -// http://www.gnu.org/licenses/gpl.html -// -// -/////////////////////////////////////////////////////////////////////////////// -// -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "zipelf.h" - -bool -iself(const char *fname) -{ - FILE *fp; - bool ret = true; - fp = fopen(fname, "rb"); - - if (!fp) return false; - if (0x7f != fgetc(fp)) ret = false; - if ('E' != fgetc(fp)) ret = false; - if ('L' != fgetc(fp)) ret = false; - if ('F' != fgetc(fp)) ret = false; - fclose(fp); - return ret; -} - -void elfread(const char *fname, unsigned &entry, ELFSECTION **§ions) -{ - Elf *e; - int fd, i; - size_t n; - char *id; - Elf_Kind ek; - GElf_Ehdr ehdr; - GElf_Phdr phdr; - const bool dbg = false; - - if (elf_version(EV_CURRENT) == EV_NONE) { - fprintf(stderr, "ELF library initialization err, %s\n", elf_errmsg(-1)); - perror("O/S Err:"); - exit(EXIT_FAILURE); - } if ((fd = open(fname, O_RDONLY, 0)) < 0) { - fprintf(stderr, "Could not open %s\n", fname); - perror("O/S Err:"); - exit(EXIT_FAILURE); - } if ((e = elf_begin(fd, ELF_C_READ, NULL))==NULL) { - fprintf(stderr, "Could not run elf_begin, %s\n", elf_errmsg(-1)); - exit(EXIT_FAILURE); - } - - ek = elf_kind(e); - if (ek == ELF_K_ELF) { - ; // This is the kind of file we should expect - } else if (ek == ELF_K_AR) { - fprintf(stderr, "Cannot run an archive!\n"); - exit(EXIT_FAILURE); - } else if (ek == ELF_K_NONE) { - ; - } else { - fprintf(stderr, "Unexpected ELF file kind!\n"); - exit(EXIT_FAILURE); - } - - if (gelf_getehdr(e, &ehdr) == NULL) { - fprintf(stderr, "getehdr() failed: %s\n", elf_errmsg(-1)); - exit(EXIT_FAILURE); - } if ((i=gelf_getclass(e)) == ELFCLASSNONE) { - fprintf(stderr, "getclass() failed: %s\n", elf_errmsg(-1)); - exit(EXIT_FAILURE); - } if ((id = elf_getident(e, NULL)) == NULL) { - fprintf(stderr, "getident() failed: %s\n", elf_errmsg(-1)); - exit(EXIT_FAILURE); - } if (i != ELFCLASS32) { - fprintf(stderr, "This is a 64-bit ELF file, ZipCPU ELF files are all 32-bit\n"); - exit(EXIT_FAILURE); - } - - if (dbg) { - printf(" %-20s 0x%jx\n", "e_type", (uintmax_t)ehdr.e_type); - printf(" %-20s 0x%jx\n", "e_machine", (uintmax_t)ehdr.e_machine); - printf(" %-20s 0x%jx\n", "e_version", (uintmax_t)ehdr.e_version); - printf(" %-20s 0x%jx\n", "e_entry", (uintmax_t)ehdr.e_entry); - printf(" %-20s 0x%jx\n", "e_phoff", (uintmax_t)ehdr.e_phoff); - printf(" %-20s 0x%jx\n", "e_shoff", (uintmax_t)ehdr.e_shoff); - printf(" %-20s 0x%jx\n", "e_flags", (uintmax_t)ehdr.e_flags); - printf(" %-20s 0x%jx\n", "e_ehsize", (uintmax_t)ehdr.e_ehsize); - printf(" %-20s 0x%jx\n", "e_phentsize", (uintmax_t)ehdr.e_phentsize); - printf(" %-20s 0x%jx\n", "e_shentsize", (uintmax_t)ehdr.e_shentsize); - printf("\n"); - } - - - // Check whether or not this is an ELF file for the ZipCPU ... - if (ehdr.e_machine != 0x0dad1) { - fprintf(stderr, "This is not a ZipCPU/8 ELF file\n"); - exit(EXIT_FAILURE); - } - - // Get our entry address - entry = ehdr.e_entry; - - - // Now, let's go look at the program header - if (elf_getphdrnum(e, &n) != 0) { - fprintf(stderr, "elf_getphdrnum() failed: %s\n", elf_errmsg(-1)); - exit(EXIT_FAILURE); - } - -assert(n != 0); - - unsigned total_octets = 0, current_offset=0, current_section=0; - for(i=0; i<(int)n; i++) { - total_octets += sizeof(ELFSECTION *)+sizeof(ELFSECTION); - - if (gelf_getphdr(e, i, &phdr) != &phdr) { - fprintf(stderr, "getphdr() failed: %s\n", elf_errmsg(-1)); - exit(EXIT_FAILURE); - } - - if (dbg) { - printf(" %-20s 0x%x\n", "p_type", phdr.p_type); - printf(" %-20s 0x%jx\n", "p_offset", phdr.p_offset); - printf(" %-20s 0x%jx\n", "p_vaddr", phdr.p_vaddr); - printf(" %-20s 0x%jx\n", "p_paddr", phdr.p_paddr); - printf(" %-20s 0x%jx\n", "p_filesz", phdr.p_filesz); - printf(" %-20s 0x%jx\n", "p_memsz", phdr.p_memsz); - printf(" %-20s 0x%x [", "p_flags", phdr.p_flags); - - if (phdr.p_flags & PF_X) printf(" Execute"); - if (phdr.p_flags & PF_R) printf(" Read"); - if (phdr.p_flags & PF_W) printf(" Write"); - printf("]\n"); - printf(" %-20s 0x%jx\n", "p_align", phdr.p_align); - } - - total_octets += phdr.p_memsz; - } - - char *d = (char *)malloc(total_octets + sizeof(ELFSECTION)+sizeof(ELFSECTION *)); - memset(d, 0, total_octets); - - ELFSECTION **r = sections = (ELFSECTION **)d; - current_offset = (n+1)*sizeof(ELFSECTION *); - current_section = 0; - - for(i=0; i<(int)n; i++) { - r[i] = (ELFSECTION *)(&d[current_offset]); - - if (gelf_getphdr(e, i, &phdr) != &phdr) { - fprintf(stderr, "getphdr() failed: %s\n", elf_errmsg(-1)); - exit(EXIT_FAILURE); - } - - if (dbg) { - printf(" %-20s 0x%jx\n", "p_offset", phdr.p_offset); - printf(" %-20s 0x%jx\n", "p_vaddr", phdr.p_vaddr); - printf(" %-20s 0x%jx\n", "p_paddr", phdr.p_paddr); - printf(" %-20s 0x%jx\n", "p_filesz", phdr.p_filesz); - printf(" %-20s 0x%jx\n", "p_memsz", phdr.p_memsz); - printf(" %-20s 0x%x [", "p_flags", phdr.p_flags); - - if (phdr.p_flags & PF_X) printf(" Execute"); - if (phdr.p_flags & PF_R) printf(" Read"); - if (phdr.p_flags & PF_W) printf(" Write"); - printf("]\n"); - - printf(" %-20s 0x%jx\n", "p_align", phdr.p_align); - } - - current_section++; - - r[i]->m_start = phdr.p_paddr; - r[i]->m_len = phdr.p_filesz; - - current_offset += phdr.p_memsz + sizeof(ELFSECTION); - - // Now, let's read in our section ... - if (lseek(fd, phdr.p_offset, SEEK_SET) < 0) { - fprintf(stderr, "Could not seek to file position %08lx\n", phdr.p_offset); - perror("O/S Err:"); - exit(EXIT_FAILURE); - } if (phdr.p_filesz > phdr.p_memsz) - phdr.p_filesz = 0; - if (read(fd, r[i]->m_data, phdr.p_filesz) != (int)phdr.p_filesz) { - fprintf(stderr, "Didnt read entire section\n"); - perror("O/S Err:"); - exit(EXIT_FAILURE); - } - - /* - // Next, we need to byte swap it from big to little endian - for(unsigned j=0; jm_len; j++) - r[i]->m_data[j] = byteswap(r[i]->m_data[j]); - */ - - if (dbg) for(unsigned j=0; jm_len; j++) - fprintf(stderr, "ADR[%04x] = %02x\n", r[i]->m_start+j, - r[i]->m_data[j] & 0x0ff); - } - - r[i] = (ELFSECTION *)(&d[current_offset]); - r[current_section]->m_start = 0; - r[current_section]->m_len = 0; - - elf_end(e); - close(fd); -} - Index: trunk/sim/cpp/twoc.cpp =================================================================== --- trunk/sim/cpp/twoc.cpp (revision 204) +++ trunk/sim/cpp/twoc.cpp (nonexistent) @@ -1,55 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Filename: twoc.cpp -// -// Project: A Doubletime Pipelined FFT -// -// Purpose: Some various two's complement related C++ helper routines. -// Specifically, these help extract signed numbers from -// packed bitfields, while guaranteeing that the upper bits -// are properly sign extended (or not) as desired. -// -// Creator: Dan Gisselquist, Ph.D. -// Gisselquist Technology, LLC -// -/////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015, Gisselquist Technology, LLC -// -// This program is free software (firmware): you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program. (It's in the $(ROOT)/doc directory, run make with no -// target there if the PDF file isn't present.) If not, see -// for a copy. -// -// License: GPL, v3, as defined and found on www.gnu.org, -// http://www.gnu.org/licenses/gpl.html -// -// -/////////////////////////////////////////////////////////////////////////// -#include "twoc.h" - -long sbits(const long val, const int bits) { - long r; - - r = val & ((1l< - -class ELFSECTION { -public: - uint32_t m_start, m_len; - char m_data[4]; -}; - -bool iself(const char *fname); -void elfread(const char *fname, uint32_t &entry, ELFSECTION **§ions); - -#endif Index: trunk/sim/cpp/twoc.h =================================================================== --- trunk/sim/cpp/twoc.h (revision 204) +++ trunk/sim/cpp/twoc.h (nonexistent) @@ -1,46 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// Filename: twoc.h -// -// Project: A Doubletime Pipelined FFT -// -// Purpose: Some various two's complement related C++ helper routines. -// Specifically, these help extract signed numbers from -// packed bitfields, while guaranteeing that the upper bits -// are properly sign extended (or not) as desired. -// -// Creator: Dan Gisselquist, Ph.D. -// Gisselquist Technology, LLC -// -/////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015, Gisselquist Technology, LLC -// -// This program is free software (firmware): you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program. (It's in the $(ROOT)/doc directory, run make with no -// target there if the PDF file isn't present.) If not, see -// for a copy. -// -// License: GPL, v3, as defined and found on www.gnu.org, -// http://www.gnu.org/licenses/gpl.html -// -// -/////////////////////////////////////////////////////////////////////////// -#ifndef TWOC_H -#define TWOC_H - -extern long sbits(const long val, const int bits); -extern unsigned long ubits(const long val, const int bits); - -#endif - Index: trunk/sim/zip-sim.exp =================================================================== --- trunk/sim/zip-sim.exp (revision 204) +++ trunk/sim/zip-sim.exp (nonexistent) @@ -1,58 +0,0 @@ -# -set_board_info target_install "{zip}" - -# Load the generic configuration for the board. This will define a basic -# set of routines needed by the tool to communicate with the board. -load_generic_config "sim" - - -# basic-sim.exp is a basic description for the standard Cygnus simulator -load_base_board_description "basic-sim" - -# zip is the name of the sim subdir -setup_sim zip - -# No multilib options needed by default -process_multilib_options "" - -# The compiler used to build for this board. This has *nothing* to do with what -# compiler is tested if we're testing gcc. -set_board_info compiler "[find_gcc]" - -# We only support newlib on this targte. -# However, we include libgloss so we can find the linker scripts -set_board_info cflags "[newlib_include_flags] [libgloss_include_flags]" -set_board_info ldflags "[newlib_link_flags] -lzipbasic" - -# For now, the simulator won't return an exit status and we'll need to indicate -# this, the standard GCC wrapper will work with this target. -set_board_info needs_status_wrapper 1 - -# The linker script for this board -set_board_info ldscript "-Tzipsim.ld" - -# Can't pass arguments to this target -set_board_info noargs 1 - -# No signals -set_board_info gdb,nosignals 1 -# Cant return results -set_board_info gdb,noresults 1 -# Doesnt do inferiori -set_board_info gdb,noinferiorio 1 - -# And it can't call functions -set_board_info gdb,cannot_call_functions 1 - - -# -# -# Okay, so some of my own fields here -# -# First, the command to run the ZipCPU simulator -set_board_info sim zip-sim -set_board_info objcopy zip-objcopy -set_board_info is_simulator 1 -set_board_info gdb,reload_on_run 1 - - Index: trunk/bench/zipsim.ld =================================================================== --- trunk/bench/zipsim.ld (revision 204) +++ trunk/bench/zipsim.ld (nonexistent) @@ -1,74 +0,0 @@ -/******************************************************************************* -* -* Filename: zipsim.ld -* -* Project: Zip CPU -- a small, lightweight, RISC CPU soft core -* -* Purpose: This script provides a description of the memory on the Arty, -* for the purposes of where to place programs in memory during -* linking. -* -* Creator: Dan Gisselquist, Ph.D. -* Gisselquist Technology, LLC -* -******************************************************************************** -* -* Copyright (C) 2017, Gisselquist Technology, LLC -* -* This program is free software (firmware): you can redistribute it and/or -* modify it under the terms of the GNU General Public License as published -* by the Free Software Foundation, either version 3 of the License, or (at -* your option) any later version. -* -* This program is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -* for more details. -* -* You should have received a copy of the GNU General Public License along -* with this program. (It's in the $(ROOT)/doc directory. Run make with no -* target there if the PDF file isn't present.) If not, see -* for a copy. -* -* License: GPL, v3, as defined and found on www.gnu.org, -* http://www.gnu.org/licenses/gpl.html -* -* -*******************************************************************************/ - -ENTRY(_start) - -MEMORY -{ - flash (wx) : ORIGIN = 0x01000000, LENGTH = 0x01000000 /* 2^24 = 16MB */ - sdram (wx) : ORIGIN = 0x10000000, LENGTH = 0x10000000 /* 2^28 = 256MB */ -} - -_flash = ORIGIN(flash); -_blkram = 0; -_sdram = ORIGIN(sdram); -_top_of_stack = ORIGIN(sdram) + LENGTH(sdram) - 4; - -SECTIONS -{ - .rocode ORIGIN(flash) : { - _boot_address = .; - *(.start) - } > flash - _kernel_image_start = . ; - _kernel_image_end = . ; - _sdram_image_start = . ; - .ramcode ORIGIN(sdram) : { - *(.kernel) - *(.text.startup) - *(.text) - *(.rodata*) *(.strings) - *(.data) *(COMMON) - }> sdram AT> flash - _sdram_image_end = . ; - .bss : { - *(.bss) - _bss_image_end = . ; - } > sdram - _top_of_heap = .; -} Index: trunk/bench/cpp/helloworld.c =================================================================== --- trunk/bench/cpp/helloworld.c (revision 204) +++ trunk/bench/cpp/helloworld.c (nonexistent) @@ -1,42 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Filename: helloworld.c -// -// Project: Zip CPU -- a small, lightweight, RISC CPU soft core -// -// Purpose: The original Helllo World program. If everything works, this -// will print Hello World to the UART, and then halt the CPU--if -// run with no O/S. -// -// -// Creator: Dan Gisselquist, Ph.D. -// Gisselquist Technology, LLC -// -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2015-2016, Gisselquist Technology, LLC -// -// This program is free software (firmware): you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published -// by the Free Software Foundation, either version 3 of the License, or (at -// your option) any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// License: GPL, v3, as defined and found on www.gnu.org, -// http://www.gnu.org/licenses/gpl.html -// -// -//////////////////////////////////////////////////////////////////////////////// -// -// -#include - -int main(int argc, char **argv) { - printf("Hello, World!\r\n"); - return 0; -} -

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.