├── Makefile ├── README.md ├── doc ├── PLATFORMS ├── README └── interconnection.txt ├── fsf └── newlib-cvs │ ├── checkout.sh │ ├── login.sh │ └── update.sh ├── regression-tests ├── Makefile ├── include │ ├── plain.mmconfig │ └── rules.mk ├── test-add │ ├── Makefile │ └── test-add.mms └── test-div │ ├── Makefile │ ├── test-div-kernel.mms │ ├── test-div.mms │ ├── test-divu-kernel.mms │ ├── test-mor-kernel.mms │ └── test-mxor-kernel.mms ├── rtl ├── Icarus │ ├── Makefile │ ├── datamem.v │ ├── fileio-test.v │ ├── icarus_toplevel.v │ ├── idt71v416s10.v │ ├── info_flags.data │ ├── progmem.v │ ├── readmoto.c │ └── regfile.v ├── NiosDevKit-EP1C20 │ ├── Makefile │ ├── fpgammix-EP2C35.qsf │ ├── fpgammix-cur.cdf │ ├── fpgammix-cur.qsf │ ├── fpgammix.cdf │ ├── fpgammix.qpf │ ├── fpgammix.qws │ ├── mega │ │ ├── pll1.v │ │ └── regfile.v │ ├── src │ │ └── fpgammix.v │ └── stable-for-demo │ │ └── fpgammix-cur.sof ├── core.v ├── filter.v ├── info_flags.mif ├── interconnect.v ├── memory_interface.v ├── mmix_opcodes.v ├── pdm.v ├── rs232.v ├── rs232in.v ├── rs232out.v ├── system.v └── vga.v ├── tools └── data2mif.sh └── workloads ├── Makefile ├── Tetris ├── Makefile ├── tetris.c ├── tetris.c.52.mach └── tromp.bsd.c ├── audio ├── Makefile ├── encodeblob.c ├── newgame-sound.c ├── newgame.ub ├── newgame.wav └── test-audio.c ├── chars.c ├── common ├── Rules.mk ├── fb-io.c ├── fb-io.h ├── font-fixed-6x13.h ├── interrupts.S ├── mmix-iospace.h ├── plain.mmconfig ├── serial-io.c ├── stdio.c └── stdio.h ├── default.mmconfig ├── div.c ├── dyncodegen.mms ├── empty.c ├── emulation ├── Makefile ├── nodiv.mmconfig ├── test-divu.S ├── test-divu2.mmo.lst ├── test-divu2.mms └── test-emulation.c ├── faster-lg.c ├── fill.c ├── fun.c ├── hilbert.c ├── hw.c ├── hwfb-real.c ├── hwfb.c ├── hwfb2.c ├── keyboard ├── Makefile ├── draw.c └── test-keyboard.c ├── ledfun.mms ├── loader.mms ├── mmix.xbm ├── mmixlogo.c ├── myfib-interrupted.mms ├── myfib-verbose.mms ├── myfib.mms ├── noio.c ├── overflow.s ├── overflow2.mms ├── overflow3.S ├── overflow3.mmconfig ├── p43errata.mms ├── readmoto.c ├── readmoto.mms ├── terminal.mms ├── test-interval ├── Makefile ├── data-annotated.s ├── data.c ├── data.s └── test-interval.S ├── test-stdio ├── Makefile └── test-stdio.c ├── testldX.mms ├── testldst.mms ├── testmem.c ├── testmul.c ├── tinymon ├── Makefile ├── start.c ├── tinymon.c ├── tinymon.data └── tinymon.test ├── triptester.mms ├── xmodem.zip ├── xmodem ├── Makefile ├── crc16.c ├── crc16.h ├── host.h ├── main.c ├── xmodem.c └── xmodem.h └── xx.mms /Makefile: -------------------------------------------------------------------------------- 1 | simulate: 2 | $(MAKE) -C rtl/Icarus 3 | 4 | clean: 5 | rm -f *.rpt *.pin *.summary *.txt *.done *.qdf *.pof *.smsg 6 | 7 | realclean: clean 8 | rm -f *~ *.qws 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | fpgammix 2 | ======== 3 | 4 | Partial implementation of Knuth's MMIX processor (FPGA softcore) 5 | 6 | This is a quick and dirty hack, but complete enough to run various 7 | graphics demos. 8 | 9 | The motivation behind this was to evaluate MMIX as a softcore. My 10 | preliminary conclusion is that it's not ideal and my effort is better 11 | directed at other targets, such as RISC-V. I made simple pipelined 12 | 32-bit RISC-V softcore [YARVI](https://github.com/tommythorn/yari). 13 | 14 | The implementation is left here for posterity, but there are bits and 15 | pieces that may be useful. 16 | 17 | ## The problem with MMIX 18 | 19 | The current implementation is a classic sequenced implementation, that 20 | is, we iterate a state machine through the states like fetch 21 | instruction, read register arguments, calculate load address, 22 | writeback result, etc. That is probably the easiest possible way to 23 | implement any processor and usually results in reasonably good cycle 24 | time (frequency), but it means taking multiple cycles per instructions 25 | which is pretty far from peak performance. 26 | 27 | The first step in improving performance is overlapping these stages, 28 | that is, pipelining. This requires speculation as we won't know the 29 | full effect of an instruction until it completes (say, a conditional 30 | branch). Recovering from mispeculation requires restarting the 31 | pipeline (some limited issues can also be handled by stalling part of 32 | the pipeline). In MMIX there is a lot of implicit state that makes 33 | this speculation less fruitful. 34 | 35 | MMIX is also pretty heavyweight. For instance, the registers are 36 | fetched from a window into a large register file. This requires an 37 | adder in the decode stage (and some conditional logic for globals). 38 | Also, the larger register file is slower to access than a smaller one 39 | (like in a typical RISC). The worse problem is that the windowing 40 | semantics is rather involved; writing to a register outside the 41 | current window, grows the window, clearing all the new registers. The 42 | naive implementation of this (which I use) is a multi-cycle operation 43 | (unacceptable for performance). Any more performant option 44 | necessarily would migrate some of the burden to the register fetch 45 | (eg. using a bitmap of cleared registers and overwriting read results 46 | with zero). This doesn't even discuss the semantics involved with 47 | register file over- and underflow. 48 | 49 | The register fetch is an important issue, but there are many other 50 | issues like these. The cheer size of the MMIX definition translates 51 | into a longer implemementation time (annyoing, but fine) and far 52 | worse, a larger design. If programs compiled to MMIX were 53 | substaintally more efficient then this might be an acceptable 54 | trade-off, but I haven't found that to be the case. 55 | 56 | Finally, all the problems complicating a pipelined design, becomes 57 | even bigger issues for a superscalar or out-of-order execution 58 | implementation. 59 | 60 | A related and possibly even more serious issue: the ISA appears a 61 | challenging code generation target -- GCC has now dropped support 62 | for MMIX, but the version that did support it reveal a surprising 63 | amount of overhead that isn't apparent in hand-written examples. 64 | 65 | ## Conclusion 66 | At the end of the day, the value of a processor comes from the 67 | software it executes. Once we have that, we care about 68 | performance, which ends up being a question of efficiency; 69 | how efficiently we can turn power, area, design-time, etc into 70 | faster execution. This exercise concluded that the MMIX ISA 71 | includes a lot of complexity that doesn't contribute significantly 72 | to the performance of common programs. 73 | -------------------------------------------------------------------------------- /doc/PLATFORMS: -------------------------------------------------------------------------------- 1 | 2 | PLATFORMS 3 | Last update: 2006-10-27 4 | 5 | 6 | Besides frequent simulations with Icarus Verilog, FpgaMMIX has been 7 | developed on and currently only support this (slightly old) FPGA 8 | development kit: 9 | 10 | Altera's Nios Dev Kit, Cyclone Edition + Lancelot ($1200) [HAVE THIS] 11 | (URL no longer available) 12 | 13 | FPGA: Cyclone EP1C20 (20,060 LUT4) 14 | Memory: 16 MiB SDRAM (32b), 1 MiB SRAM (32b) 15 | Flash: CompactFlash, 8 MiB linear flash (8b) 16 | Other: Ethernet 100, 24b VGA, dual PS/2, audio out, RS-232 17 | 18 | Expensive and dated -- small FPGA and memory. 19 | 20 | I still need to support the SDRAM, CompactFlash, the linear 21 | flash, and the Ethernet, but the FPGA is already getting full. 22 | 23 | However it is a pricy option and has a few limitation (notably the 24 | amount of available main memory). Hopefully before too long, FpgaMMIX 25 | will be extended to support other development boards. Here is a list 26 | of interesting candidates: 27 | 28 | * Xilix's Virtex-4 ML401 Evaluation Platform ($500) [HAVE THIS] 29 | http://www.xilinx.com/ml401 30 | 31 | FPGA: Virtex-4 XC4LX25 (21,504 LUT4) 32 | Memory: 64 MiB(*) DDR SDRAM 266 MHz (32b), 1.125 MiB ZBT SRAM (36b) 33 | Flash: CompactFlash, 8 MiB Flash (32b) 34 | Other: Ethernet 1000, 24b VGA, dual PS/2, USB H&P, RS-232, 35 | lots of audio 36 | 37 | Good value. 38 | 39 | (*) Documentation claims it can be reworked to 256 MiB, but AFAICT, 40 | there is only one extra pin thus enabling only 128 MiB. 41 | 42 | 43 | * Digilentinc's Spartan 3E-1600 Development Board ($300) [ORDERED THIS] 44 | http://www.digilentinc.com/Products/Detail.cfm?Prod=S3E1600&Nav1=Products&Nav2=Programmable 45 | 46 | FPGA: Spartan-3E 1600E (33,192 LUT4) 47 | Memory: 32 MiB(**) DDR SDRAM (16b) 48 | Flash: 16 MiB parallel flash 49 | Other: Ethernet 100, 3b VGA, RS-232, D/A & A/D converters, 50 | DS2432 (EEPROM+SHA1) 51 | 52 | Great value. Apart from FPGA and SDRAM, idential to the 53 | Spartan-3E Starter Kit below. 54 | 55 | The FPGA is 50% bigger than the ML401, but the latter have 56 | more peripherals. No audio. No flash card. VGA wimpy. Narrow 57 | SDRAM. 58 | 59 | (**) The PCB supports a 64 MiB DDR with a rework, but even 60 | more and wider would have been nice. 61 | 62 | 63 | 64 | Runner up: 65 | 66 | * Xilix's Virtex-5 ML501 Evaluation & Development Platform ($1000) 67 | http://www.xilinx.com/ml501 68 | 69 | FPGA: Virtex-5 XC5VLX50 (28,800 LUT6 ~= 46,080 LUT4) 70 | Memory: 256 MiB(***) DDR2 SODIMM (64b?), 1 MiB ZBT SRAM (32b?) 71 | Flash: CompactFlash, 32 MiB Flash 72 | Other: Ethernet 1000, DVI, dual PS/2, USB H&P, RS-232, lots of audio 73 | 74 | Ideal platform, but not supported by ISE WebPACK :( 75 | (DDR2 DIMM => faster, wider, but more complicated) 76 | 77 | (***) Supports larger SODIMMs (up to 1 GiB?) 78 | 79 | 80 | * Xilinx's Spartan-3E Starter Kit ($150) 81 | http://www.xilinx.com/xlnx/xebiz/designResources/ip_product_details.jsp?key=HW-SPAR3E-SK-US 82 | 83 | FPGA: Spartan-3E 500E (10,476 LUT4) 84 | Memory: 64 MiB DDR SDRAM (16b) 85 | Flash: 16 MiB parallel flash 86 | Other: Ethernet 100, 3b VGA, PS/2, RS-232, D/A & A/D converters, 87 | DS2432 (EEPROM+SHA1) 88 | 89 | Good value, but FPGA is too small. No audio. No flash 90 | card. VGA wimpy. Narrow SDRAM. 91 | 92 | FpgaMMIX is obviously highly un-optimized currently, but just 93 | the core is 14,000+ LUT4, unlikely to be shrunk to 50%. 94 | 95 | 96 | * Altera's DE2 Development & Education Board ($150) 97 | http://www.altera.com/products/devkits/altera/kit-cyc2-2C20N.html 98 | 99 | FPGA: Cyclone-II EP2C20 (18,752 LUT4) 100 | Memory: 8 MiB SDRAM (16b?), 512 KiB SRAM (?b) 101 | Flash: SD memory card, 4 MiB Flash 102 | Other: 12b VGA, PS/2, Audio, Video in 103 | 104 | Good value, but too little main memory, too small FPGA, and no 105 | ethernet. 106 | 107 | 108 | * Altera's Video Development Kit, Cyclone II Edition ($1100) 109 | http://www.altera.com/products/devkits/altera/kit-video-cyclone2.html 110 | 111 | FPGA: Cyclone-II EP2C70 (68,416 LUT4) 112 | Memory: 256 MiB DDR2 SODIMM (64b?), 1 MiB synchronous SRAM (32b?) 113 | Flash: none? 114 | Other: 24b VGA, audio 115 | 116 | Expensive. FPGA and memory is great, but almost everything 117 | else is missing. 118 | -------------------------------------------------------------------------------- /doc/README: -------------------------------------------------------------------------------- 1 | 2 | FpgaMMIX Computer 3 | 4 | Phase 1: microcoded 5 | 6 | Version 0.0 7 | 8 | Copyright (C) 2006 Tommy Thorn 9 | 10 | This is the first hardware implementation of Professor Knuth's MMIX 11 | architecture. More than just the CPU core, this is a full computer 12 | with an assortment of peripherals. 13 | 14 | The present version is a micro-sequenced implementation which 15 | primary purpose is an experiment to verify my understanding of the 16 | architecture, a tool for learning, and a vehicle for building the 17 | infrastructure (notably software) for the higher performance version 18 | to follow. 19 | 20 | Performance specifically been a *non-goal* for this implementation, 21 | as long as it was sufficient fast for the purpose mentioned above 22 | and small enough to fit my development FPGA (Altera Cyclone 23 | EP1C20). For practical reasons FpgaMMIX, as of this writing, runs 24 | with a clock frequency of 25 MHz and takes at least 10 cycles per 25 | instruction. 26 | 27 | Performance goal for the pipelined implementation (FpgaMMIX v1) is 28 | one cycle execution for most instructions and a frequency in the 29 | range of 100 to 200 MHz on the same hardware, thus 40-80X faster. 30 | 31 | CONFORMANCE 32 | 33 | Any deviation from the specification given by Knuth should be 34 | considered a bug (please report), unless explicitly stated. The TLB 35 | is likely to implement only a subset of the specification. 36 | 37 | The current implementation is fast approaching Milestone 1, that is 38 | full RTL implementation of the integer subset. DIV[U] and all 39 | floating point instructions will be emulated by the firmware. The 40 | extend of hardware floating point support is TBD, particularly 41 | depending on available logic resources. FpgaMMIX v1 is expected to 42 | get basic hardware support for floating point arithmetic. 43 | 44 | 45 | 46 | ACKNOWLEDGMENT 47 | 48 | Big thanks to H. Peter Anvin for showing how to interface much of 49 | the peripherals on the Nios Development Kit, Cyclone Ed. as well as 50 | the Lancelot daughter card. 51 | 52 | 53 | TASKS 54 | 55 | - Porting to cheaper or more capable platforms. 56 | -------------------------------------------------------------------------------- /doc/interconnection.txt: -------------------------------------------------------------------------------- 1 | I've rejected WISHBONE as being too low performance. Altera's Avalon 2 | represents the golden standard for me, but it's _very_ general and 3 | would take much effort to replicate. 4 | 5 | For my needs I only need: 6 | - all reads are pipelined with variable latency 7 | - multi master support 8 | - burst support 9 | 10 | 11 | Basics 12 | ~~~~~~ 13 | 14 | Master raises transfer_request to initial a transfer. Slave 15 | asynchronously raises wait_request when it's not ready. The master is 16 | expected to hold the request and associated parameters stable until 17 | wait goes down. 18 | 19 | Example, a master side state machine issuing two requests (no bust) 20 | will look like: 21 | 22 | always @(posedge clock) case (state) 23 | S1: begin 24 | ... ... <= .... params for 1st req .... 25 | transfer_request <= 1; 26 | state <= S2; 27 | end 28 | 29 | S2: if (~wait_request) begin 30 | ... ... <= .... params for 1st req .... 31 | state <= S3; 32 | end 33 | 34 | S3: if (~wait_request) begin 35 | transfer_request <= 0; 36 | .... 37 | end 38 | 39 | 40 | Pipelined Reading 41 | ~~~~~~~~~~~~~~~~~ 42 | 43 | Read requests are just like write requests, except that one or more 44 | cycles in the future replies will arrive, in the order issued, raising 45 | data_valid for one cycle for each reply. 46 | 47 | Extending the above example, we need a separate state machine 48 | collecting the data as we can't assume anything about how long we will 49 | have to wait in S2. 50 | 51 | always @(posedge clock) begin 52 | if (data_valid) 53 | if (waiting_for_1st) begin 54 | first <= port_read_data; 55 | waiting_for_1st <= 0; 56 | end else begin 57 | second <= port_read_data; 58 | waiting_for_2nd <= 0; 59 | end 60 | 61 | case (state) 62 | S1: begin 63 | ... ... <= .... params for 1st req .... 64 | transfer_request <= 1; 65 | waiting_for_1st <= 1; 66 | state <= S2; 67 | end 68 | 69 | S2: if (~wait_request) begin 70 | ... ... <= .... params for 2nd req .... 71 | waiting_for_2nd <= 1; 72 | state <= S3; 73 | end 74 | 75 | S3: if (~wait_request) begin 76 | transfer_request <= 0; 77 | state <= S4; 78 | end 79 | 80 | S4: if (~waiting_for_1st & ~waiting_for_2nd) begin 81 | ... process data 82 | end 83 | end 84 | 85 | 86 | In many cases burst transfers can replace the need for multiple 87 | issues. 88 | 89 | 90 | Multi Master 91 | ~~~~~~~~~~~~ 92 | 93 | I really like the shared based approach to arbitration that Avalon 94 | has. Let's see if we can replicate it. 95 | 96 | Constants 97 | A_SHARES, B_SHARES 98 | 99 | if (transfer_request_a & (shares_left_for_a | ~transfer_request_b)) 100 | go ahead and let A get access 101 | if (shares_left_for_a == 0) 102 | shares_left_for_a = A_SHARES 103 | else 104 | --shares_left_for_a 105 | else if (transfer_request_b & (shares_left_for_b | ~transfer_request_a)) 106 | go ahead and let B get access 107 | if (shares_left_for_b == 0) 108 | shares_left_for_b = A_SHARES 109 | else 110 | --shares_left_for_b 111 | else /* ~transfer_request_a & ~transfer_request_b */ 112 | shares_left_for_a = A_SHARES 113 | shares_left_for_b = A_SHARES 114 | do nothing else 115 | 116 | Puh, not tooo complicated? Just wait until we throw burst support into the mix. 117 | 118 | Also, I failed to show how to support routing the read data back to 119 | theirs masters. A simple 1-bit FIFO of length A_SHARES + B_SHARES 120 | (??) should be sufficient. (Careful about the latency of the FIFO 121 | itself.) However, the arbitration must know which requests will 122 | result in a reply. (Should simply all requests result in a reply to 123 | simplify?) 124 | 125 | 126 | Burst support 127 | ~~~~~~~~~~~~~ 128 | 129 | I haven't found documentation for how Avalon handles this, but it 130 | seems that simply extending the basic strategy with a burst count 131 | should suffice. 132 | 133 | Example: lets show the client side for a change (as the master looks 134 | almost exactly the same as for a single request). This simple client 135 | can only handle one outstanding request at a time, but it does support 136 | bursts. 137 | 138 | wire wait_request = count != 0; 139 | 140 | always @(posedge clock) begin 141 | pipeline[N:1] <= pipeline[N-1:0]; 142 | pipeline[0] <= 0; 143 | if (count) begin 144 | addr <= addr + 1; 145 | pipeline[0] <= 1; 146 | count <= count - 1; 147 | else if (transfer_request) begin 148 | count <= burst_length; 149 | addr <= request_addr 150 | end 151 | end 152 | 153 | (Of course the counting down to -1 and using the sign bit would be 154 | better). 155 | 156 | 157 | The only extension needed for the arbitration is knowing about the 158 | burst size. 159 | 160 | -------------------------------------------------------------------------------- /fsf/newlib-cvs/checkout.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd src;cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src co newlib 3 | -------------------------------------------------------------------------------- /fsf/newlib-cvs/login.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src login 3 | -------------------------------------------------------------------------------- /fsf/newlib-cvs/update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd src;cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src update -d newlib 3 | -------------------------------------------------------------------------------- /regression-tests/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=mmix 2 | 3 | QUIET=@ 4 | MAKE_OPT=--quiet --no-print-directory 5 | 6 | TESTS=test-add 7 | 8 | usage: 9 | @echo "Usage: make test-all TARGET={mmix,mmmix,fpgammix-sim,fpgammix-hw}" 10 | 11 | test-all: $(TESTS:%=%.run) 12 | 13 | %.run: % 14 | $(QUIET)$(MAKE) $(MAKE_OPT) -C $< run TARGET=$(TARGET) 15 | -------------------------------------------------------------------------------- /regression-tests/include/plain.mmconfig: -------------------------------------------------------------------------------- 1 | % example configuration for basic tests 2 | memaddresstime 3 3 | memreadtime 10 memwritetime 10 4 | membusbytes 16 5 | branchpredictbits 2 6 | branchaddressbits 1 7 | branchhistorybits 1 8 | branchdualbits 1 9 | memchunksmax 100 10 | hashprime 127 11 | Scache blocksize 64 12 | Scache setsize 512 13 | Scache associativity 4 pseudolru 14 | Scache accesstime 2 15 | Dcache blocksize 32 16 | Dcache setsize 256 17 | Dcache victimsize 2 18 | Icache blocksize 32 19 | Icache setsize 256 20 | Icache victimsize 2 21 | DTcache associativity 4 lru 22 | unit ALU1 00000000ffffffffffffffffffffffff0000000300000003fffffffffffffffe 23 | unit ALU2 00000000ffffffffffffffffffffffff0000000300000003fffffffffffffffe 24 | unit LSU1 00000000000000000000000000000000fffffffcfffffffc0000000000000000 25 | unit LSU2 00000000000000000000000000000000fffffffcfffffffc0000000000000000 26 | unit MUL1 000080f000000000000000000000000000000000000000000000000000000000 27 | unit DIV1 00000c0f00000000000000000000000000000000000000000000000000000000 28 | unit FPU1 7fff730000000000000000000000000000000000000000000000000000000000 29 | memslots 4 30 | renameregs 10 31 | reorderbuffer 20 32 | Dcache writeallocate 1 33 | Scache writeallocate 1 34 | Dcache writeback 1 35 | Scache writeback 1 36 | Dcache ports 2 37 | DTcache ports 2 38 | writebuffer 4 39 | writeholdingtime 5 40 | mul0 1 41 | mul1 2 42 | mul2 5 43 | -------------------------------------------------------------------------------- /regression-tests/include/rules.mk: -------------------------------------------------------------------------------- 1 | MMIX_TOOLS_BIN=/opt/mmix/bin 2 | 3 | %.mmo: %.mms 4 | mmixal -l $@.lst -o $@ $< 5 | 6 | %.mmb: %.mmo 7 | mmix -D$@ $< 8 | 9 | %.run-mmix: %.mmo 10 | @-echo `basename $< .mmo` '-->' `mmix $<` 11 | 12 | %.run-mmix-verbose: %.mmo 13 | mmix -t9999 $< 14 | 15 | %.run-mmmix: %.mmb 16 | @-echo `basename $< .mmb` '-->' \ 17 | `(echo 999999;echo q) | mmmix ../include/plain.mmconfig $< |tail +2|head -1` 18 | 19 | %.run-fpgammix-sim: %.data 20 | cp $< ../../rtl/Icarus/initmem.data 21 | $(MAKE) -C $(FPGAMMIX_DIR)/rtl/Icarus; 22 | 23 | %.run-fpgammix-hw: %.txt 24 | @echo "Alas, fpgaMMIX isn't supported yet on real hardware." 25 | @sz $< 26 | 27 | %.run-clean: 28 | -rm *.mmo *.lst *.mmb 29 | 30 | %.data: %.elf 31 | $(MMIX_TOOLS_BIN)/mmix-objdump -s $< | grep '^ '|cut -d' ' -f3-6|tr ' ' '\n' | grep -v '^$$' > $@ 32 | 33 | %.dis: %.elf 34 | $(MMIX_TOOLS_BIN)/mmix-objdump -d $< 35 | 36 | %.elf: %.mmo 37 | $(MMIX_TOOLS_BIN)/mmix-objcopy -O elf64-mmix -I mmo $< $@ 38 | -------------------------------------------------------------------------------- /regression-tests/test-add/Makefile: -------------------------------------------------------------------------------- 1 | include ../include/rules.mk 2 | 3 | run: test-add.run-$(TARGET) 4 | 5 | -------------------------------------------------------------------------------- /regression-tests/test-add/test-add.mms: -------------------------------------------------------------------------------- 1 | % This is almost "hello world" simple 2 | 3 | % This depends on working TRAP, SETL, CMP, BZ 4 | 5 | LOC #100 6 | 7 | Main SETL $0,17 8 | ADDU $0,$0,34 9 | CMP $0,$0,51 10 | BZ $0,2F 11 | 12 | GETA $255,Fail 13 | 1H TRAP 0,Fputs,StdOut 14 | TRAP 0,Halt,0 15 | 16 | 2H GETA $255,Pass 17 | BZ $0,1B 18 | 19 | Pass BYTE "Passed",#a,0 20 | Fail BYTE "Failed!",#a,0 21 | -------------------------------------------------------------------------------- /regression-tests/test-div/Makefile: -------------------------------------------------------------------------------- 1 | FPGAMMIX_DIR=/home/tommy/fpgammix 2 | TARGET=fpgammix-sim 3 | 4 | include ../include/rules.mk 5 | 6 | #all: test-div-kernel.dis test-div-kernel.run-fpgammix-sim 7 | #all: test-divu-kernel.run-fpgammix-sim test-divu-kernel.dis 8 | 9 | run: test-$(WHAT)-kernel.run-$(TARGET) 10 | 11 | 12 | -------------------------------------------------------------------------------- /regression-tests/test-div/test-div-kernel.mms: -------------------------------------------------------------------------------- 1 | % Run some simple tests on DIV (signed) 2 | 3 | % This depends on working GETA, LDOU, PUT 4 | % TRAP, SETL, CMP, BZ 5 | 6 | LOC #80000000 7 | 8 | Main GETA $255,Traphandler 9 | BNN $255,1F 10 | PUT rT,$255 % We only try this in supervisor mode 11 | 1H GETA $255,FailMsg 12 | GETA $0,Numbers 13 | Loop PUT rA,0 % clear current exception 14 | LDOU $1,$0,0 % Quotent 15 | LDOU $2,$0,8 % Divisor 16 | LDOU $3,$0,16 % Expected result 17 | LDOU $4,$0,24 % Expected remainder 18 | LDOU $7,$0,32 % Expected exception 19 | 20 | DIV $5,$1,$2 % check result 21 | CMPU $6,$5,$3 22 | BNZ $6,Done 23 | 24 | GET $5,rR % check remainder 25 | CMPU $6,$5,$4 26 | BNZ $6,Done 27 | 28 | GET $5,rA % check current exception 29 | AND $5,$5,(1<<6)|(1<<7) % keep only DV bits 30 | CMPU $6,$5,$7 31 | BNZ $6,Done 32 | 33 | ADDU $0,$0,40 % move to next data tuple 34 | GETA $1,End 35 | CMP $1,$0,$1 36 | BNZ $1,Loop 37 | 38 | GETA $255,PassMsg 39 | 40 | Done TRAP 0,Fputs,StdOut 41 | TRAP 0,Halt,0 42 | 43 | PassMsg BYTE "Passed",#a,0 44 | FailMsg BYTE "Failed!",#a,0 45 | 46 | Numbers OCTA -17092006 47 | OCTA 2020 48 | OCTA -8462 49 | OCTA 1234 50 | OCTA #0 51 | 52 | OCTA 17092006 53 | OCTA -2020 54 | OCTA -8462 55 | OCTA -1234 56 | OCTA #0 57 | 58 | 59 | OCTA #8000000000000017 60 | OCTA #0 61 | OCTA #0 62 | OCTA #8000000000000017 63 | OCTA 1<<7 % expect the D divide exception 64 | 65 | OCTA 20060917 66 | OCTA 1646 67 | OCTA 12187 68 | OCTA 1115 69 | OCTA 0 70 | 71 | OCTA -17092006 72 | OCTA -2020 73 | OCTA 8461 74 | OCTA -786 75 | OCTA #0 76 | 77 | OCTA #8000000000000000 78 | OCTA #FFFFFFFFFFFFFFFF 79 | OCTA #8000000000000000 80 | OCTA #0 81 | OCTA 1<<6 % expect the V integer overflow exception 82 | 83 | OCTA #8000000000000017 84 | OCTA #0 85 | OCTA #0 86 | OCTA #8000000000000017 87 | OCTA 1<<7 % expect the D divide exception 88 | 89 | End OCTA 0 90 | 91 | % XXX This should be a separate module prefixed to .txt files 92 | % XXX I just need to pick a good address for the Traphandler 93 | % This has no impact on mmix simulation, but is for RTL 94 | Traphandler GET $255,rBB 95 | LDBU $0,$255 96 | SETH $1,1 97 | 1H LDO $2,$1 98 | PBOD $2,1B 99 | STO $0,$1 100 | PUT 255,255 101 | -------------------------------------------------------------------------------- /regression-tests/test-div/test-div.mms: -------------------------------------------------------------------------------- 1 | % This is almost "hello world" simple 2 | 3 | % This depends on working GETA, LDOU, PUT 4 | % TRAP, SETL, CMP, BZ 5 | 6 | LOC #100 7 | 8 | Main GETA $255,FailMsg 9 | GETA $0,Numbers 10 | Loop PUT rD,0 11 | LDOU $1,$0,0 % Quotent 12 | LDOU $2,$0,8 % Divisor 13 | LDOU $3,$0,16 % Expected result 14 | LDOU $4,$0,24 % Expected remainder 15 | DIVU $5,$1,$2 16 | 17 | CMPU $6,$5,$3 18 | BNZ $6,Done 19 | 20 | GET $5,rR 21 | CMPU $6,$5,$4 22 | BNZ $6,Done 23 | 24 | ADDU $0,$0,32 25 | GETA $1,End 26 | CMP $1,$0,$1 27 | BNZ $1,Loop 28 | 29 | GETA $255,PassMsg 30 | 31 | Done TRAP 0,Fputs,StdOut 32 | TRAP 0,Halt,0 33 | 34 | PassMsg BYTE "Passed",#a,0 35 | FailMsg BYTE "Failed!",#a,0 36 | 37 | Numbers OCTA 20060917 38 | OCTA 1646 39 | OCTA 12187 40 | OCTA 1115 41 | 42 | OCTA #8000000000000000 43 | OCTA #FFFFFFFFFFFFFFFF 44 | OCTA #0 45 | OCTA #8000000000000000 46 | 47 | OCTA #8000000000000017 48 | OCTA #0 49 | OCTA #0 50 | OCTA #8000000000000017 51 | 52 | End OCTA 0 -------------------------------------------------------------------------------- /regression-tests/test-div/test-divu-kernel.mms: -------------------------------------------------------------------------------- 1 | % Run some simple tests on DIVU (unsigned) 2 | 3 | % This depends on working GETA, LDOU, PUT 4 | % TRAP, SETL, CMP, BZ 5 | 6 | LOC #80000000 7 | 8 | Main GETA $255,Traphandler 9 | BNN $255,1F 10 | PUT rT,$255 % We only try this in supervisor mode 11 | 1H GETA $255,FailMsg 12 | GETA $0,Numbers 13 | Loop PUT rA,0 % clear current exception 14 | LDOU $8,$0,0 % Upper quotient 15 | LDOU $1,$0,8 % Quotient 16 | LDOU $2,$0,16 % Divisor 17 | LDOU $3,$0,24 % Expected result 18 | LDOU $4,$0,32 % Expected remainder 19 | LDOU $7,$0,40 % Expected exception 20 | 21 | PUT rD,$8 22 | DIVU $5,$1,$2 23 | CMPU $6,$5,$3 % check result 24 | BNZ $6,Done 25 | 26 | GET $5,rR % check remainder 27 | CMPU $6,$5,$4 28 | BNZ $6,Done 29 | 30 | GET $5,rA % check current exception 31 | AND $5,$5,(1<<6)|(1<<7) % keep only DV bits 32 | CMPU $6,$5,$7 33 | BNZ $6,Done 34 | 35 | ADDU $0,$0,48 % move to next data tuple 36 | GETA $1,End 37 | CMP $1,$0,$1 38 | BNZ $1,Loop 39 | 40 | GETA $255,PassMsg 41 | 42 | Done TRAP 0,Fputs,StdOut 43 | TRAP 0,Halt,0 44 | 45 | PassMsg BYTE "Passed",#a,0 46 | FailMsg BYTE "Failed!",#a,0 47 | 48 | Numbers OCTA 0 49 | OCTA -17092006 50 | OCTA -2020 51 | OCTA 0 52 | OCTA -17092006 53 | OCTA 0 54 | 55 | OCTA 1233 56 | OCTA 17092006 57 | OCTA 0 58 | OCTA 1233 59 | OCTA 17092006 60 | OCTA 0 61 | 62 | OCTA #1 63 | OCTA #1 64 | OCTA #1 65 | OCTA #1 66 | OCTA #1 67 | OCTA 0 68 | 69 | OCTA #FFFFFFFFFFFFFFF 70 | OCTA #FFFFFFFFFFFFFFF 71 | OCTA #FFFFFFFFFFFFFFF 72 | OCTA #FFFFFFFFFFFFFFF 73 | OCTA #FFFFFFFFFFFFFFF 74 | OCTA 0 75 | 76 | OCTA #FFFFFFFFFFFFFFFF 77 | OCTA #FFFFFFFFFFFFFFFF 78 | OCTA #FFFFFFFFFFFFFFFF 79 | OCTA #FFFFFFFFFFFFFFFF 80 | OCTA #FFFFFFFFFFFFFFFF 81 | OCTA 0 82 | 83 | OCTA 0 84 | OCTA -17092006 85 | OCTA 2020 86 | OCTA #20718d6f046eea 87 | OCTA #3f2 88 | OCTA 0 89 | 90 | OCTA 0 91 | OCTA 17092006 92 | OCTA -2020 93 | OCTA 0 94 | OCTA #104cda6 95 | OCTA 0 96 | 97 | OCTA 0 98 | OCTA #8000000000000017 99 | OCTA #0 100 | OCTA #0 101 | OCTA #8000000000000017 102 | OCTA 0 103 | 104 | OCTA 0 105 | OCTA 20060917 106 | OCTA 1646 107 | OCTA 12187 108 | OCTA 1115 109 | OCTA 0 110 | 111 | OCTA 0 112 | OCTA #8000000000000000 113 | OCTA #FFFFFFFFFFFFFFFF 114 | OCTA 0 115 | OCTA #8000000000000000 116 | OCTA 0 117 | 118 | OCTA 0 119 | OCTA -17092006 120 | OCTA -2020 121 | OCTA 0 122 | OCTA #fffffffffefb325a 123 | OCTA 0 124 | 125 | OCTA 123456 126 | OCTA 17092006 127 | OCTA 2020 128 | OCTA #1e240 129 | OCTA #104cda6 130 | OCTA 0 131 | 132 | OCTA 2020 133 | OCTA 17092006 134 | OCTA 2020 135 | OCTA #7e4 136 | OCTA #104cda6 137 | OCTA 0 138 | 139 | 140 | 141 | End OCTA 0 142 | 143 | 144 | % This has no impact on mmix simulation, but is for RTL 145 | Traphandler GET $255,rBB 146 | LDBU $0,$255 147 | SETH $1,1 148 | 1H LDO $2,$1 149 | PBOD $2,1B 150 | STO $0,$1 151 | PUT 255,255 152 | -------------------------------------------------------------------------------- /regression-tests/test-div/test-mor-kernel.mms: -------------------------------------------------------------------------------- 1 | % Run some simple tests on MOR 2 | 3 | % This depends on working GETA, LDOU, PUT 4 | % TRAP, SETL, CMP, BZ 5 | 6 | LOC #80000000 7 | 8 | Main GETA $255,Traphandler 9 | BNN $255,1F 10 | PUT rT,$255 % We only try this in supervisor mode 11 | 1H GETA $255,FailMsg 12 | GETA $0,Numbers 13 | Loop LDOU $1,$0,0 % Y 14 | LDOU $2,$0,8 % Z 15 | LDOU $3,$0,16 % Expected result 16 | 17 | MOR $5,$1,$2 % check result 18 | CMPU $6,$5,$3 19 | BNZ $6,Done 20 | 21 | ADDU $0,$0,24 % move to next data tuple 22 | GETA $1,End 23 | CMP $1,$0,$1 24 | BNZ $1,Loop 25 | 26 | GETA $255,PassMsg 27 | 28 | Done TRAP 0,Fputs,StdOut 29 | TRAP 0,Halt,0 30 | 31 | PassMsg BYTE "Passed",#a,0 32 | FailMsg BYTE "Failed!",#a,0 33 | 34 | Numbers OCTA #7824317821437294 35 | OCTA #9812189744372983 36 | OCTA #797a79ff67ffb5fe 37 | 38 | OCTA #1234567890ABCDEF 39 | OCTA #0000000000000001 40 | OCTA #00000000000000EF 41 | 42 | OCTA #1234567890ABCDEF 43 | OCTA #0000000000000002 44 | OCTA #00000000000000CD 45 | 46 | OCTA #1234567890ABCDEF 47 | OCTA #0000000000000100 48 | OCTA #000000000000EF00 49 | 50 | OCTA 20060917 51 | OCTA 1646 52 | OCTA #3a3b 53 | 54 | OCTA #8000000000000000 55 | OCTA #FFFFFFFFFFFFFFFF 56 | OCTA #8080808080808080 57 | 58 | OCTA #8000000000000017 59 | OCTA #0 60 | OCTA #0 61 | 62 | OCTA -17092006 63 | OCTA -2020 64 | OCTA #ffffffffffffffff 65 | 66 | OCTA -17092006 67 | OCTA 2020 68 | OCTA #fbff 69 | 70 | OCTA 17092006 71 | OCTA -2020 72 | OCTA #efefefefefef0105 73 | 74 | OCTA #8000000000000017 75 | OCTA #0 76 | OCTA #0 77 | 78 | End OCTA 0 79 | 80 | % XXX This should be a separate module prefixed to .txt files 81 | % XXX I just need to pick a good address for the Traphandler 82 | % This has no impact on mmix simulation, but is for RTL 83 | Traphandler GET $255,rBB 84 | LDBU $0,$255 85 | SETH $1,1 86 | 1H LDO $2,$1 87 | PBOD $2,1B 88 | STO $0,$1 89 | PUT 255,255 90 | -------------------------------------------------------------------------------- /regression-tests/test-div/test-mxor-kernel.mms: -------------------------------------------------------------------------------- 1 | % Run some simple tests on MXOR 2 | 3 | % This depends on working GETA, LDOU, PUT 4 | % TRAP, SETL, CMP, BZ 5 | 6 | LOC #80000000 7 | 8 | Main GETA $255,Traphandler 9 | BNN $255,1F 10 | PUT rT,$255 % We only try this in supervisor mode 11 | 1H GETA $255,FailMsg 12 | GETA $0,Numbers 13 | Loop LDOU $1,$0,0 % Y 14 | LDOU $2,$0,8 % Z 15 | LDOU $3,$0,16 % Expected result 16 | 17 | MXOR $5,$1,$2 % check result 18 | CMPU $6,$5,$3 19 | BNZ $6,Done 20 | 21 | ADDU $0,$0,24 % move to next data tuple 22 | GETA $1,End 23 | CMP $1,$0,$1 24 | BNZ $1,Loop 25 | 26 | GETA $255,PassMsg 27 | 28 | Done TRAP 0,Fputs,StdOut 29 | TRAP 0,Halt,0 30 | 31 | PassMsg BYTE "Passed",#a,0 32 | FailMsg BYTE "Failed!",#a,0 33 | 34 | Numbers OCTA #1234567890ABCDEF 35 | OCTA #0000000000000001 36 | OCTA #00000000000000EF 37 | 38 | OCTA #1234567890ABCDEF 39 | OCTA #0000000000000002 40 | OCTA #00000000000000CD 41 | 42 | OCTA #1234567890ABCDEF 43 | OCTA #0000000000000100 44 | OCTA #000000000000EF00 45 | 46 | OCTA 20060917 47 | OCTA 1646 48 | OCTA #2829 49 | 50 | OCTA #8000000000000000 51 | OCTA #FFFFFFFFFFFFFFFF 52 | OCTA #8080808080808080 53 | 54 | OCTA #8000000000000017 55 | OCTA #0 56 | OCTA #0 57 | 58 | OCTA -17092006 59 | OCTA -2020 60 | OCTA #6d6d6d6d6d6dfefa 61 | 62 | OCTA -17092006 63 | OCTA 2020 64 | OCTA #9304 65 | 66 | OCTA 17092006 67 | OCTA -2020 68 | OCTA #6e6e6e6e6e6e0105 69 | 70 | OCTA #8000000000000017 71 | OCTA #0 72 | OCTA #0 73 | 74 | End OCTA 0 75 | 76 | % XXX This should be a separate module prefixed to .txt files 77 | % XXX I just need to pick a good address for the Traphandler 78 | % This has no impact on mmix simulation, but is for RTL 79 | Traphandler GET $255,rBB 80 | LDBU $0,$255 81 | SETH $1,1 82 | 1H LDO $2,$1 83 | PBOD $2,1B 84 | STO $0,$1 85 | PUT 255,255 86 | -------------------------------------------------------------------------------- /rtl/Icarus/Makefile: -------------------------------------------------------------------------------- 1 | TOOLSDIR=../../tools 2 | 3 | SRC= icarus_toplevel.v ../core.v ../memory_interface.v ../system.v \ 4 | ../filter.v ../pdm.v \ 5 | ../rs232out.v ../rs232in.v ../vga.v ../interconnect.v \ 6 | regfile.v idt71v416s10.v 7 | 8 | run: fpgammix 9 | ./fpgammix 10 | 11 | fpgammix: initmem.data $(SRC) ../mmix_opcodes.v 12 | /opt/iverilog-0.8.2/bin/iverilog -Wimplicit -I.. $(SRC) -o fpgammix 13 | # iverilog -B/home/tommy/.lib/ivl -I.. $(SRC) -o fpgammix 14 | 15 | mifs: ../initmem.mif ../info_flags.mif 16 | 17 | ../initmem.mif: initmem.data 18 | $(TOOLSDIR)/data2mif $< > $@ 19 | 20 | ../info_flags.mif: info_flags.data 21 | $(TOOLSDIR)/data2mif -w8 -l256 $< > $@ 22 | 23 | clean: 24 | -rm *.mmo *.lst 25 | 26 | realclean: clean 27 | -rm fpgammix 28 | -------------------------------------------------------------------------------- /rtl/Icarus/datamem.v: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright 2004 Tommy Thorn - All Rights Reserved 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, Inc., 53 Temple Place Ste 330, 8 | // Bostom MA 02111-1307, USA; either version 2 of the License, or 9 | // (at your option) any later version; incorporated herein by reference. 10 | // 11 | // ----------------------------------------------------------------------- 12 | 13 | `timescale 1ns/10ps 14 | 15 | module datamem(input wire clock, 16 | input wire [ 7:0] rdaddress, 17 | output wire [63:0] q, 18 | input wire [ 7:0] wraddress, 19 | input wire [ 7:0] byteena_a, 20 | input wire wren, 21 | input wire [63:0] data); 22 | 23 | reg [ 7:0] addr_delayed; 24 | reg [ 7:0] ram0[(1<<8) - 1:0], 25 | ram1[(1<<8) - 1:0], 26 | ram2[(1<<8) - 1:0], 27 | ram3[(1<<8) - 1:0], 28 | ram4[(1<<8) - 1:0], 29 | ram5[(1<<8) - 1:0], 30 | ram6[(1<<8) - 1:0], 31 | ram7[(1<<8) - 1:0]; 32 | 33 | assign q = 34 | {ram7[addr_delayed],ram6[addr_delayed],ram5[addr_delayed],ram4[addr_delayed], 35 | ram3[addr_delayed],ram2[addr_delayed],ram1[addr_delayed],ram0[addr_delayed]}; 36 | 37 | 38 | always @(posedge clock) begin 39 | addr_delayed <= rdaddress; 40 | if (wren) begin 41 | if (byteena_a[7]) ram7[wraddress] <= data[63:56]; 42 | if (byteena_a[6]) ram6[wraddress] <= data[55:48]; 43 | if (byteena_a[5]) ram5[wraddress] <= data[47:40]; 44 | if (byteena_a[4]) ram4[wraddress] <= data[39:32]; 45 | if (byteena_a[3]) ram3[wraddress] <= data[31:24]; 46 | if (byteena_a[2]) ram2[wraddress] <= data[23:16]; 47 | if (byteena_a[1]) ram1[wraddress] <= data[15: 8]; 48 | if (byteena_a[0]) ram0[wraddress] <= data[ 7: 0]; 49 | end 50 | end 51 | 52 | reg [8:0] i; 53 | initial 54 | for (i = 0; i < 256; i = i + 1) begin 55 | ram0[i] <= 0; 56 | ram1[i] <= 0; 57 | ram2[i] <= 0; 58 | ram3[i] <= 0; 59 | ram4[i] <= 0; 60 | ram5[i] <= 0; 61 | ram6[i] <= 0; 62 | ram7[i] <= 0; 63 | end 64 | endmodule 65 | -------------------------------------------------------------------------------- /rtl/Icarus/fileio-test.v: -------------------------------------------------------------------------------- 1 | module main(); 2 | integer file, ch; 3 | reg clk = 1; 4 | 5 | 6 | always #5 clk <= ~clk; 7 | 8 | always @(posedge clk) begin 9 | $write("%05d Hello ", $time); 10 | $strobe("Testing"); 11 | 12 | $display(" foobar "); 13 | ch = $fgetc(file); 14 | $display("<%c>", ch); 15 | 16 | end 17 | 18 | 19 | initial begin 20 | file = $fopen("fileio-test.v", "r"); 21 | 22 | 23 | #100 $finish; 24 | 25 | end 26 | endmodule // main 27 | -------------------------------------------------------------------------------- /rtl/Icarus/icarus_toplevel.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/10ps 2 | 3 | module icarus_toplevel(); 4 | reg clk25MHz = 1; 5 | 6 | wire [22:0] fse_a; // Mainboard common bus address 7 | wire [31:0] fse_d; // Mainboard common bus data 8 | wire flash_cs_n; // Flash ROM CS# 9 | wire enet_aen; // Ethernet Access Enable 10 | wire sram_cs_n; // SRAM CS# 11 | wire [3:0] sram_be_n; // SRAM byte enables 12 | wire sram_oe_n; // SRAM OE# 13 | wire sram_we_n; // SRAM WE# 14 | 15 | always #5 clk25MHz <= ~clk25MHz; 16 | 17 | idt71v416s10 u35(fse_d[15: 0], fse_a[19:2], sram_we_n, sram_oe_n, sram_cs_n, 18 | sram_be_n[0], sram_be_n[1]); // Yep, strange order... 19 | idt71v416s10 u36(fse_d[31:16], fse_a[19:2], sram_we_n, sram_oe_n, sram_cs_n, 20 | sram_be_n[2], sram_be_n[3]); 21 | 22 | system tommix_system_inst 23 | ( .clk25MHz(clk25MHz) 24 | ,.reset(0) 25 | ,.fse_a(fse_a) // Mainboard common bus address 26 | ,.fse_d(fse_d) // Mainboard common bus data 27 | ,.flash_cs_n(flash_cs_n) // Flash ROM CS# 28 | ,.enet_aen(enet_aen) // Ethernet Access Enable 29 | ,.sram_cs_n(sram_cs_n) // SRAM CS# 30 | ,.sram_be_n(sram_be_n) // SRAM byte enables 31 | ,.sram_oe_n(sram_oe_n) // SRAM OE# 32 | ,.sram_we_n(sram_we_n) // SRAM WE# 33 | ); 34 | 35 | 36 | 37 | reg [31:0] i, v; 38 | reg [31:0] preload[0:262143]; 39 | initial begin 40 | $readmemh("initialsram.data", preload); 41 | for (i = 0; i <= 262143; i = i + 1) begin 42 | v = preload[i]; 43 | u36.mem2[i] = v[31:24]; 44 | u36.mem1[i] = v[23:16]; 45 | u35.mem2[i] = v[15: 8]; 46 | u35.mem1[i] = v[ 7: 0]; 47 | end 48 | end 49 | endmodule // main 50 | -------------------------------------------------------------------------------- /rtl/Icarus/info_flags.data: -------------------------------------------------------------------------------- 1 | 0a 2 | 2a 3 | 2a 4 | 2a 5 | 2a 6 | 26 7 | 2a 8 | 26 9 | 26 10 | 25 11 | 26 12 | 25 13 | 26 14 | 25 15 | 26 16 | 25 17 | 2a 18 | 2a 19 | 2a 20 | 2a 21 | 2a 22 | 26 23 | 2a 24 | 26 25 | 2a 26 | 29 27 | 2a 28 | 29 29 | 2a 30 | 29 31 | 2a 32 | 29 33 | 2a 34 | 29 35 | 2a 36 | 29 37 | 2a 38 | 29 39 | 2a 40 | 29 41 | 2a 42 | 29 43 | 2a 44 | 29 45 | 2a 46 | 29 47 | 2a 48 | 29 49 | 2a 50 | 29 51 | 2a 52 | 29 53 | 26 54 | 25 55 | 26 56 | 25 57 | 2a 58 | 29 59 | 2a 60 | 29 61 | 2a 62 | 29 63 | 2a 64 | 29 65 | 50 66 | 50 67 | 50 68 | 50 69 | 50 70 | 50 71 | 50 72 | 50 73 | 50 74 | 50 75 | 50 76 | 50 77 | 50 78 | 50 79 | 50 80 | 50 81 | 50 82 | 50 83 | 50 84 | 50 85 | 50 86 | 50 87 | 50 88 | 50 89 | 50 90 | 50 91 | 50 92 | 50 93 | 50 94 | 50 95 | 50 96 | 50 97 | 3a 98 | 39 99 | 3a 100 | 39 101 | 3a 102 | 39 103 | 3a 104 | 39 105 | 3a 106 | 39 107 | 3a 108 | 39 109 | 3a 110 | 39 111 | 3a 112 | 39 113 | 2a 114 | 29 115 | 2a 116 | 29 117 | 2a 118 | 29 119 | 2a 120 | 29 121 | 2a 122 | 29 123 | 2a 124 | 29 125 | 2a 126 | 29 127 | 2a 128 | 29 129 | 2a 130 | 29 131 | 2a 132 | 29 133 | 2a 134 | 29 135 | 2a 136 | 29 137 | 2a 138 | 29 139 | 2a 140 | 29 141 | 2a 142 | 29 143 | 2a 144 | 29 145 | 2a 146 | 29 147 | 2a 148 | 29 149 | 3a 150 | 39 151 | 2a 152 | 29 153 | 2a 154 | 29 155 | 0a 156 | 09 157 | 0a 158 | 09 159 | 2a 160 | 29 161 | 1a 162 | 19 163 | 1a 164 | 19 165 | 1a 166 | 19 167 | 1a 168 | 19 169 | 1a 170 | 19 171 | 1a 172 | 19 173 | 1a 174 | 19 175 | 1a 176 | 19 177 | 1a 178 | 19 179 | 1a 180 | 19 181 | 0a 182 | 09 183 | 1a 184 | 19 185 | 0a 186 | 09 187 | 0a 188 | 09 189 | 0a 190 | 09 191 | aa 192 | a9 193 | 2a 194 | 29 195 | 2a 196 | 29 197 | 2a 198 | 29 199 | 2a 200 | 29 201 | 2a 202 | 29 203 | 2a 204 | 29 205 | 2a 206 | 29 207 | 2a 208 | 29 209 | 2a 210 | 29 211 | 2a 212 | 29 213 | 2a 214 | 29 215 | 2a 216 | 29 217 | 2a 218 | 29 219 | 2a 220 | 29 221 | 2a 222 | 29 223 | 2a 224 | 29 225 | 20 226 | 20 227 | 20 228 | 20 229 | 30 230 | 30 231 | 30 232 | 30 233 | 30 234 | 30 235 | 30 236 | 30 237 | 30 238 | 30 239 | 30 240 | 30 241 | 40 242 | 40 243 | e0 244 | e0 245 | 60 246 | 60 247 | 02 248 | 01 249 | 80 250 | 00 251 | 20 252 | 82 253 | 01 254 | 00 255 | 20 256 | 0a 257 | -------------------------------------------------------------------------------- /rtl/Icarus/progmem.v: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright 2004 Tommy Thorn - All Rights Reserved 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, Inc., 53 Temple Place Ste 330, 8 | // Bostom MA 02111-1307, USA; either version 2 of the License, or 9 | // (at your option) any later version; incorporated herein by reference. 10 | // 11 | // ----------------------------------------------------------------------- 12 | 13 | `timescale 1ns/10ps 14 | 15 | module progmem(input wire clock, 16 | input wire rden, 17 | input wire [6:0] rdaddress, 18 | input wire [6:0] wraddress, 19 | input wire wren, 20 | input wire [31:0] data, 21 | output wire [31:0] q); 22 | 23 | reg [ 6:0] addr_delayed; 24 | reg [31:0] ram[(1<<7) - 1:0]; 25 | 26 | assign q = ram[addr_delayed]; 27 | 28 | always @(posedge clock) 29 | if (rden) 30 | addr_delayed <= rdaddress; 31 | 32 | 33 | initial 34 | $readmemh("initmem.data", ram); 35 | endmodule 36 | -------------------------------------------------------------------------------- /rtl/Icarus/readmoto.c: -------------------------------------------------------------------------------- 1 | /* 2 | I figured it would be easier to write the assembly if I had a 3 | working model in C first ... 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | // S11329300FFFFFFFFFFF0F0F0F0F0F0FFFFFFFFF33 11 | 12 | unsigned sum; 13 | 14 | void fatal(void) 15 | { 16 | printf("FAILURE\n"); 17 | exit(1); 18 | } 19 | 20 | unsigned getdigit() 21 | { 22 | unsigned c = getchar(); 23 | 24 | if ('0' <= c && c <= '9') 25 | return c - '0'; 26 | else if ('a' <= c && c <= 'f') 27 | return c - 'a' + 10; 28 | else if ('A' <= c && c <= 'F') 29 | return c - 'A' + 10; 30 | else 31 | fatal(); 32 | } 33 | 34 | unsigned get2digits() 35 | { 36 | unsigned n = getdigit(); 37 | n = n*16 + getdigit(); 38 | sum = 255 & (sum + n); 39 | return n; 40 | } 41 | 42 | unsigned get4digits() 43 | { 44 | unsigned n = get2digits(); 45 | return n*256 + get2digits(); 46 | } 47 | 48 | 49 | int 50 | main() 51 | { 52 | char buf[999]; 53 | 54 | for (;;) { 55 | unsigned type, count, address, i, data, xsum; 56 | while (getchar() != 'S'); 57 | type = getdigit(); 58 | if (type != 1 && type != 9) 59 | continue; 60 | sum = 0; 61 | count = get2digits(); 62 | address = get4digits(); 63 | printf("type %d count %d starting %x\n", type, count, address); 64 | for (i = 2; i < count - 1; ++i, ++address) { 65 | data = get2digits(); 66 | printf("%04x:%02x\n", address, data); 67 | } 68 | xsum = get2digits(); 69 | if (sum != 255) 70 | printf("Mismatch %02x =? %02x\n", sum, xsum); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /rtl/Icarus/regfile.v: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright 2004 Tommy Thorn - All Rights Reserved 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, Inc., 53 Temple Place Ste 330, 8 | // Bostom MA 02111-1307, USA; either version 2 of the License, or 9 | // (at your option) any later version; incorporated herein by reference. 10 | // 11 | // ----------------------------------------------------------------------- 12 | 13 | `timescale 1ns/10ps 14 | 15 | `define D 8 /* A parameter would be more useful */ 16 | 17 | module regfile(input wire clock, 18 | 19 | input wire rden, 20 | input wire [`D:0] rdaddress, 21 | output wire [63:0] q /* rddata would have been better */, 22 | 23 | input wire wren, 24 | input wire [`D:0] wraddress, 25 | input wire [63:0] data /* wrdata would have been better */); 26 | 27 | parameter ID = 0; 28 | parameter V = 0; 29 | 30 | reg [`D:0] addr_delayed = 0; 31 | reg [63:0] ram[(2 << `D) - 1: 0]; 32 | 33 | /* XXX Accidentally found a bug in Icarus as I had accidentally written 34 | reg [63:0] ram[(2 << `D) - 1: 0]; 35 | turning 36 | assign q = ram[addr_delayed]; 37 | into a bit extract rather than a memory lookup. 38 | 39 | turned out that for addr_delayed == ??? it would crash with a 40 | segmentation error. 41 | */ 42 | 43 | assign q = ram[addr_delayed]; 44 | 45 | always @(posedge clock) if (1) begin 46 | if(V)$display("%05d REGFILE addr_delayed=#%x q=#%x rdaddress=%x rden%x", 47 | $time, 48 | addr_delayed, q, rdaddress, rden); 49 | 50 | if (rden) begin 51 | if(V)$display("%05d REGFILE %c read from XXXXX", $time, ID); 52 | addr_delayed <= rdaddress; 53 | // $display("regfile %2x -> %x", rdaddress, ram0[rdaddress]); 54 | // for (i = 0; i < 256; i = i + 1) $display("regfile %2x -> %2x", i, ram0[i]); 55 | end 56 | if (wren) begin 57 | if(V)$display("%05d RF Writing %x -> [%x]", $time, data, wraddress); 58 | ram[wraddress] <= data; 59 | end 60 | end 61 | 62 | reg [`D+1:0] i; 63 | initial for (i = 0; i < 1 << (`D+1); i = i + 1) ram[i] = 0; 64 | endmodule 65 | -------------------------------------------------------------------------------- /rtl/NiosDevKit-EP1C20/Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | -rm *.txt *.rpt *.summary *.smsg 3 | 4 | realclean: clean 5 | -rm *~ *.qws 6 | -------------------------------------------------------------------------------- /rtl/NiosDevKit-EP1C20/fpgammix-EP2C35.qsf: -------------------------------------------------------------------------------- 1 | # Copyright (C) 1991-2006 Altera Corporation 2 | # Your use of Altera Corporation's design tools, logic functions 3 | # and other software and tools, and its AMPP partner logic 4 | # functions, and any output files any of the foregoing 5 | # (including device programming or simulation files), and any 6 | # associated documentation or information are expressly subject 7 | # to the terms and conditions of the Altera Program License 8 | # Subscription Agreement, Altera MegaCore Function License 9 | # Agreement, or other applicable license agreement, including, 10 | # without limitation, that your use is for the sole purpose of 11 | # programming logic devices manufactured by Altera and sold by 12 | # Altera or its authorized distributors. Please refer to the 13 | # applicable agreement for further details. 14 | 15 | 16 | # The default values for assignments are stored in the file 17 | # main_assignment_defaults.qdf 18 | # If this file doesn't exist, and for assignments not listed, see file 19 | # assignment_defaults.qdf 20 | 21 | # Altera recommends that you do not modify this file. This 22 | # file is updated automatically by the Quartus II software 23 | # and any changes you make may be lost or overwritten. 24 | 25 | 26 | set_global_assignment -name FAMILY "Cyclone II" 27 | set_global_assignment -name DEVICE EP2C35F484C8 28 | set_global_assignment -name TOP_LEVEL_ENTITY fpgammix 29 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 6.0 30 | set_global_assignment -name PROJECT_CREATION_TIME_DATE "19:44:06 AUGUST 27, 2006" 31 | set_global_assignment -name LAST_QUARTUS_VERSION 6.0 32 | set_global_assignment -name SIMULATION_MODE FUNCTIONAL 33 | 34 | 35 | # Pin & Location Assignments 36 | # ========================== 37 | 38 | # The board labels these 0 .. 7, but I like the 39 | # lower order bit on the left, thank you! 40 | 41 | 42 | 43 | set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED" 44 | set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON 45 | set_global_assignment -name ADV_NETLIST_OPT_SYNTH_GATE_RETIME ON 46 | set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON 47 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON 48 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON 49 | set_global_assignment -name RESERVE_ALL_UNUSED_PINS_NO_OUTPUT_GND "AS INPUT TRI-STATED" 50 | set_global_assignment -name SMART_RECOMPILE ON 51 | set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT FAST 52 | set_global_assignment -name ENABLE_DRC_SETTINGS ON 53 | set_global_assignment -name IGNORE_CLOCK_SETTINGS ON 54 | set_global_assignment -name FMAX_REQUIREMENT "500 MHz" 55 | 56 | set_global_assignment -name FITTER_EFFORT "STANDARD FIT" 57 | set_global_assignment -name VERILOG_FILE src/fpgammix.v 58 | set_global_assignment -name VERILOG_FILE ../core.v 59 | set_global_assignment -name VERILOG_FILE ../system.v 60 | set_global_assignment -name VERILOG_FILE ../interconnect.v 61 | set_global_assignment -name VERILOG_FILE ../memory_interface.v 62 | set_global_assignment -name VERILOG_FILE ../vga.v 63 | set_global_assignment -name VERILOG_FILE ../rs232in.v 64 | set_global_assignment -name VERILOG_FILE ../rs232out.v 65 | set_global_assignment -name VERILOG_FILE ../filter.v 66 | set_global_assignment -name VERILOG_FILE mega/regfile.v 67 | set_global_assignment -name VERILOG_FILE mega/pll1.v 68 | set_global_assignment -name MIF_FILE ../initmem.mif 69 | set_global_assignment -name MIF_FILE ../info_flags.mif 70 | set_global_assignment -name CDF_FILE fpgammix.cdf 71 | 72 | set_global_assignment -name DEVICE_FILTER_PACKAGE FBGA 73 | set_global_assignment -name DEVICE_FILTER_PIN_COUNT 484 74 | set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 -------------------------------------------------------------------------------- /rtl/NiosDevKit-EP1C20/fpgammix-cur.cdf: -------------------------------------------------------------------------------- 1 | /* Quartus II Version 6.0 Build 178 04/27/2006 SJ Web Edition */ 2 | JedecChain; 3 | FileRevision(JESD32A); 4 | DefaultMfr(6E); 5 | 6 | P ActionCode(Cfg) 7 | Device PartName(EP1C20F400) Path("") File("fpgammix-cur.sof") MfrSpec(OpMask(1)); 8 | 9 | ChainEnd; 10 | 11 | AlteraBegin; 12 | ChainType(JTAG); 13 | AlteraEnd; 14 | -------------------------------------------------------------------------------- /rtl/NiosDevKit-EP1C20/fpgammix.cdf: -------------------------------------------------------------------------------- 1 | /* Quartus II Version 6.0 Build 202 06/20/2006 Service Pack 1 SJ Web Edition */ 2 | JedecChain; 3 | FileRevision(JESD32A); 4 | DefaultMfr(6E); 5 | 6 | P ActionCode(Cfg) 7 | Device PartName(EP1C20F400) Path("") File("fpgammix.sof") MfrSpec(OpMask(1)); 8 | 9 | ChainEnd; 10 | 11 | AlteraBegin; 12 | ChainType(JTAG); 13 | AlteraEnd; 14 | -------------------------------------------------------------------------------- /rtl/NiosDevKit-EP1C20/fpgammix.qpf: -------------------------------------------------------------------------------- 1 | # Copyright (C) 1991-2006 Altera Corporation 2 | # Your use of Altera Corporation's design tools, logic functions 3 | # and other software and tools, and its AMPP partner logic 4 | # functions, and any output files any of the foregoing 5 | # (including device programming or simulation files), and any 6 | # associated documentation or information are expressly subject 7 | # to the terms and conditions of the Altera Program License 8 | # Subscription Agreement, Altera MegaCore Function License 9 | # Agreement, or other applicable license agreement, including, 10 | # without limitation, that your use is for the sole purpose of 11 | # programming logic devices manufactured by Altera and sold by 12 | # Altera or its authorized distributors. Please refer to the 13 | # applicable agreement for further details. 14 | 15 | 16 | 17 | QUARTUS_VERSION = "6.0" 18 | DATE = "22:29:36 August 27, 2006" 19 | 20 | 21 | # Revisions 22 | 23 | PROJECT_REVISION = "fpgammix-cur" 24 | PROJECT_REVISION = "fpgammix-EP2C35" 25 | -------------------------------------------------------------------------------- /rtl/NiosDevKit-EP1C20/fpgammix.qws: -------------------------------------------------------------------------------- 1 | [ProjectWorkspace] 2 | ptn_Child1=Frames 3 | [ProjectWorkspace.Frames] 4 | ptn_Child1=ChildFrames 5 | [ProjectWorkspace.Frames.ChildFrames] 6 | ptn_Child1=Document-0 7 | ptn_Child2=Document-1 8 | -------------------------------------------------------------------------------- /rtl/NiosDevKit-EP1C20/mega/regfile.v: -------------------------------------------------------------------------------- 1 | // megafunction wizard: %ALTSYNCRAM% 2 | // GENERATION: STANDARD 3 | // VERSION: WM1.0 4 | // MODULE: altsyncram 5 | 6 | // ============================================================ 7 | // File Name: regfile.v 8 | // Megafunction Name(s): 9 | // altsyncram 10 | // ============================================================ 11 | // ************************************************************ 12 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! 13 | // 14 | // 6.0 Build 202 06/20/2006 SP 1 SJ Web Edition 15 | // ************************************************************ 16 | 17 | 18 | //Copyright (C) 1991-2006 Altera Corporation 19 | //Your use of Altera Corporation's design tools, logic functions 20 | //and other software and tools, and its AMPP partner logic 21 | //functions, and any output files any of the foregoing 22 | //(including device programming or simulation files), and any 23 | //associated documentation or information are expressly subject 24 | //to the terms and conditions of the Altera Program License 25 | //Subscription Agreement, Altera MegaCore Function License 26 | //Agreement, or other applicable license agreement, including, 27 | //without limitation, that your use is for the sole purpose of 28 | //programming logic devices manufactured by Altera and sold by 29 | //Altera or its authorized distributors. Please refer to the 30 | //applicable agreement for further details. 31 | 32 | 33 | // synopsys translate_off 34 | `timescale 1 ps / 1 ps 35 | // synopsys translate_on 36 | module regfile ( 37 | clock, 38 | data, 39 | rdaddress, 40 | rden, 41 | wraddress, 42 | wren, 43 | q); 44 | 45 | input clock; 46 | input [63:0] data; 47 | input [8:0] rdaddress; 48 | input rden; 49 | input [8:0] wraddress; 50 | input wren; 51 | output [63:0] q; 52 | 53 | wire [63:0] sub_wire0; 54 | wire [63:0] q = sub_wire0[63:0]; 55 | 56 | altsyncram altsyncram_component ( 57 | .wren_a (wren), 58 | .clock0 (clock), 59 | .address_a (wraddress), 60 | .address_b (rdaddress), 61 | .rden_b (rden), 62 | .data_a (data), 63 | .q_b (sub_wire0), 64 | .aclr0 (1'b0), 65 | .aclr1 (1'b0), 66 | .addressstall_a (1'b0), 67 | .addressstall_b (1'b0), 68 | .byteena_a (1'b1), 69 | .byteena_b (1'b1), 70 | .clock1 (1'b1), 71 | .clocken0 (1'b1), 72 | .clocken1 (1'b1), 73 | .data_b ({64{1'b1}}), 74 | .q_a (), 75 | .wren_b (1'b0)); 76 | defparam 77 | altsyncram_component.address_aclr_a = "NONE", 78 | altsyncram_component.address_aclr_b = "NONE", 79 | altsyncram_component.address_reg_b = "CLOCK0", 80 | altsyncram_component.indata_aclr_a = "NONE", 81 | altsyncram_component.intended_device_family = "Cyclone", 82 | altsyncram_component.lpm_type = "altsyncram", 83 | altsyncram_component.numwords_a = 512, 84 | altsyncram_component.numwords_b = 512, 85 | altsyncram_component.operation_mode = "DUAL_PORT", 86 | altsyncram_component.outdata_aclr_b = "NONE", 87 | altsyncram_component.outdata_reg_b = "UNREGISTERED", 88 | altsyncram_component.power_up_uninitialized = "FALSE", 89 | altsyncram_component.rdcontrol_aclr_b = "NONE", 90 | altsyncram_component.rdcontrol_reg_b = "CLOCK0", 91 | altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE", 92 | altsyncram_component.widthad_a = 9, 93 | altsyncram_component.widthad_b = 9, 94 | altsyncram_component.width_a = 64, 95 | altsyncram_component.width_b = 64, 96 | altsyncram_component.width_byteena_a = 1, 97 | altsyncram_component.wrcontrol_aclr_a = "NONE"; 98 | 99 | 100 | endmodule 101 | 102 | // ============================================================ 103 | // CNX file retrieval info 104 | // ============================================================ 105 | // Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" 106 | // Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" 107 | // Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" 108 | // Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" 109 | // Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" 110 | // Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" 111 | // Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" 112 | // Retrieval info: PRIVATE: BlankMemory NUMERIC "1" 113 | // Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" 114 | // Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" 115 | // Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" 116 | // Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" 117 | // Retrieval info: PRIVATE: CLRdata NUMERIC "0" 118 | // Retrieval info: PRIVATE: CLRq NUMERIC "0" 119 | // Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" 120 | // Retrieval info: PRIVATE: CLRrren NUMERIC "0" 121 | // Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" 122 | // Retrieval info: PRIVATE: CLRwren NUMERIC "0" 123 | // Retrieval info: PRIVATE: Clock NUMERIC "0" 124 | // Retrieval info: PRIVATE: Clock_A NUMERIC "0" 125 | // Retrieval info: PRIVATE: Clock_B NUMERIC "0" 126 | // Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" 127 | // Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" 128 | // Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0" 129 | // Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B" 130 | // Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" 131 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone" 132 | // Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" 133 | // Retrieval info: PRIVATE: JTAG_ID STRING "NONE" 134 | // Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" 135 | // Retrieval info: PRIVATE: MEMSIZE NUMERIC "32768" 136 | // Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" 137 | // Retrieval info: PRIVATE: MIFfilename STRING "" 138 | // Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2" 139 | // Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" 140 | // Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0" 141 | // Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" 142 | // Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" 143 | // Retrieval info: PRIVATE: REGdata NUMERIC "1" 144 | // Retrieval info: PRIVATE: REGq NUMERIC "0" 145 | // Retrieval info: PRIVATE: REGrdaddress NUMERIC "1" 146 | // Retrieval info: PRIVATE: REGrren NUMERIC "1" 147 | // Retrieval info: PRIVATE: REGwraddress NUMERIC "1" 148 | // Retrieval info: PRIVATE: REGwren NUMERIC "1" 149 | // Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" 150 | // Retrieval info: PRIVATE: VarWidth NUMERIC "0" 151 | // Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "64" 152 | // Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "64" 153 | // Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "64" 154 | // Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "64" 155 | // Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" 156 | // Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0" 157 | // Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" 158 | // Retrieval info: PRIVATE: enable NUMERIC "0" 159 | // Retrieval info: PRIVATE: rden NUMERIC "1" 160 | // Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE" 161 | // Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE" 162 | // Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0" 163 | // Retrieval info: CONSTANT: INDATA_ACLR_A STRING "NONE" 164 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone" 165 | // Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" 166 | // Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "512" 167 | // Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "512" 168 | // Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT" 169 | // Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" 170 | // Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED" 171 | // Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" 172 | // Retrieval info: CONSTANT: RDCONTROL_ACLR_B STRING "NONE" 173 | // Retrieval info: CONSTANT: RDCONTROL_REG_B STRING "CLOCK0" 174 | // Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE" 175 | // Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "9" 176 | // Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "9" 177 | // Retrieval info: CONSTANT: WIDTH_A NUMERIC "64" 178 | // Retrieval info: CONSTANT: WIDTH_B NUMERIC "64" 179 | // Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" 180 | // Retrieval info: CONSTANT: WRCONTROL_ACLR_A STRING "NONE" 181 | // Retrieval info: USED_PORT: clock 0 0 0 0 INPUT NODEFVAL clock 182 | // Retrieval info: USED_PORT: data 0 0 64 0 INPUT NODEFVAL data[63..0] 183 | // Retrieval info: USED_PORT: q 0 0 64 0 OUTPUT NODEFVAL q[63..0] 184 | // Retrieval info: USED_PORT: rdaddress 0 0 9 0 INPUT NODEFVAL rdaddress[8..0] 185 | // Retrieval info: USED_PORT: rden 0 0 0 0 INPUT VCC rden 186 | // Retrieval info: USED_PORT: wraddress 0 0 9 0 INPUT NODEFVAL wraddress[8..0] 187 | // Retrieval info: USED_PORT: wren 0 0 0 0 INPUT VCC wren 188 | // Retrieval info: CONNECT: @data_a 0 0 64 0 data 0 0 64 0 189 | // Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 190 | // Retrieval info: CONNECT: q 0 0 64 0 @q_b 0 0 64 0 191 | // Retrieval info: CONNECT: @address_a 0 0 9 0 wraddress 0 0 9 0 192 | // Retrieval info: CONNECT: @address_b 0 0 9 0 rdaddress 0 0 9 0 193 | // Retrieval info: CONNECT: @rden_b 0 0 0 0 rden 0 0 0 0 194 | // Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 195 | // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all 196 | // Retrieval info: GEN_FILE: TYPE_NORMAL regfile.v TRUE 197 | // Retrieval info: GEN_FILE: TYPE_NORMAL regfile.inc FALSE 198 | // Retrieval info: GEN_FILE: TYPE_NORMAL regfile.cmp FALSE 199 | // Retrieval info: GEN_FILE: TYPE_NORMAL regfile.bsf FALSE 200 | // Retrieval info: GEN_FILE: TYPE_NORMAL regfile_inst.v TRUE 201 | // Retrieval info: GEN_FILE: TYPE_NORMAL regfile_bb.v FALSE 202 | // Retrieval info: GEN_FILE: TYPE_NORMAL regfile_waveforms.html FALSE 203 | // Retrieval info: GEN_FILE: TYPE_NORMAL regfile_wave*.jpg FALSE 204 | -------------------------------------------------------------------------------- /rtl/NiosDevKit-EP1C20/src/fpgammix.v: -------------------------------------------------------------------------------- 1 | module fpgammix(// Clock and reset 2 | input wire clkin // K5 PLL1 input clock (50 MHz) 3 | ,output wire pld_clkout // L8 Clock to zero-skew buffer Lancelot board 4 | ,input wire pld_clkfb // L14 Feedback from pld_clkout to PLL2 5 | ,input wire reset_n // C4 CPU Reset button 6 | 7 | // Push buttons LEDs 7-segments 8 | ,input wire [3:0] sw // Pushbutton switches 9 | ,output wire [7:0] led // Debugging LEDs 10 | ,output wire [7:0] s7_0 // Debugging 7-segment LEDs 11 | ,output wire [7:0] s7_1 // -- 12 | 13 | // Debug serial connection 14 | ,output wire ttyb_txd // Debug TxD 15 | ,input ttyb_rxd // Debug RxD 16 | 17 | // Flash-SRAM-Ethernet bus 18 | ,output wire [22:0] fse_a // Mainboard common bus address 19 | ,inout wire [31:0] fse_d // Mainboard common bus data 20 | ,output wire flash_cs_n // Flash ROM CS# 21 | ,output wire enet_aen // Ethernet Access Enable 22 | ,output wire sram_cs_n // SRAM CS# 23 | ,output wire [3:0] sram_be_n // SRAM byte enables 24 | ,output wire sram_oe_n // SRAM OE# 25 | ,output sram_we_n // SRAM WE# 26 | 27 | // CompactFlash slot 28 | ,output wire [10:0] cf_a // CompactFlash address bus 29 | ,inout wire [15:0] cf_d // CompactFlash data bus 30 | ,input cf_rdy // CompactFlash RDY 31 | ,input cf_wait_n // CompactFlash WAIT# 32 | ,output cf_ce1_n // CompactFlash CE1# 33 | ,output cf_ce2_n // CompactFlash CE2# 34 | ,output cf_oe_n // CompactFlash OE# 35 | ,output cf_we_n // CompactFlash WE# 36 | ,output cf_reg_n // CompactFlash REG# 37 | ,input cf_cd1_n // CompactFlash card detect 38 | 39 | // Lancelot VGA interface 40 | ,output wire [7:0] vga_r // VGA red 41 | ,output wire [7:0] vga_g // VGA green 42 | ,output wire [7:0] vga_b // VGA blue 43 | ,output wire vga_hs // VGA horz sync 44 | ,output wire vga_vs // VGA vert sync 45 | ,output wire vga_blank_n // VGA DAC force blank 46 | ,output wire vga_sync_n // VGA sync enable 47 | ,output wire vga_sync_t // VGA sync on R/G/B 48 | ,output wire vga_m1 // VGA color space config 49 | ,output wire vga_m2 // VGA color space config 50 | 51 | // Lancelot PS/2 keyboard/mouse 52 | ,output ps2_sel // PS/2 port enable 53 | ,inout ps2_kclk // PS/2 keyboard clock 54 | ,inout ps2_kdata // PS/2 keyboard data 55 | ,inout ps2_mclk // PS/2 mouse clock 56 | ,inout ps2_mdata // PS/2 mouse data 57 | 58 | // Lancelot Audio 59 | ,output wire audio_l // 1-bit Sigma-delta converter 60 | ,output wire audio_r // 1-bit Sigma-delta converter 61 | ); 62 | 63 | wire reset, 64 | reset_stb; // Dummy, not used 65 | wire clk25MHz, clk100MHz, pll1_locked; 66 | 67 | /* Filter the reset signal and synchronize it. Purists may not like 68 | the fact that a short async reset will be ignored. Whatever. */ 69 | filter filter_reset(clk25MHz, ~reset_n | ~pll1_locked, reset, reset_stb); 70 | 71 | pll1 pll1( 72 | .inclk0(clkin), // 50 MHz input clock 73 | .c0(clk100MHz), // x2/1 = 100 MHz output clock 74 | .c1(clk25MHz), // x1/2 = 25 MHz output clock 75 | .locked(pll1_locked), 76 | .e0(pld_clkout) // External only output x1/2 = 25 MHz 77 | ); 78 | 79 | system 80 | (clk25MHz // 25 MHz clock 81 | ,reset // C4 CPU Reset button 82 | 83 | ,sw // Pushbutton switches 84 | ,led // Debugging LEDs 85 | ,s7_0 // Debugging 7-segment LEDs 86 | ,s7_1 // -- 87 | 88 | ,ttyb_txd // Debug TxD 89 | ,ttyb_rxd // Debug RxD 90 | 91 | ,fse_a // Mainboard common bus address 92 | ,fse_d // Mainboard common bus data 93 | ,flash_cs_n // Flash ROM CS# 94 | ,enet_aen // Ethernet Access Enable 95 | ,sram_cs_n // SRAM CS# 96 | ,sram_be_n // SRAM byte enables 97 | ,sram_oe_n // SRAM OE# 98 | ,sram_we_n // SRAM WE# 99 | 100 | ,cf_a // CompactFlash address bus 101 | ,cf_d // CompactFlash data bus 102 | ,cf_rdy // CompactFlash RDY 103 | ,cf_wait_n // CompactFlash WAIT# 104 | ,cf_ce1_n // CompactFlash CE1# 105 | ,cf_ce2_n // CompactFlash CE2# 106 | ,cf_oe_n // CompactFlash OE# 107 | ,cf_we_n // CompactFlash WE# 108 | ,cf_reg_n // CompactFlash REG# 109 | ,cf_cd1_n // CompactFlash card detect 110 | 111 | ,vga_r // VGA red 112 | ,vga_g // VGA green 113 | ,vga_b // VGA blue 114 | ,vga_hs // VGA horz sync 115 | ,vga_vs // VGA vert sync 116 | ,vga_blank_n // VGA DAC force blank 117 | ,vga_sync_n // VGA sync enable 118 | ,vga_sync_t // VGA sync on R/G/B 119 | ,vga_m1 // VGA color space config 120 | ,vga_m2 // VGA color space config 121 | 122 | ,ps2_sel // PS/2 port input/output select 123 | ,ps2_kclk // PS/2 keyboard clock 124 | ,ps2_kdata // PS/2 keyboard data 125 | ,ps2_mclk // PS/2 mouse clock 126 | ,ps2_mdata // PS/2 mouse data 127 | 128 | 129 | ,audio_l // 1-bit Sigma-delta converter 130 | ,audio_r // 1-bit Sigma-delta converter 131 | ); 132 | endmodule // main 133 | -------------------------------------------------------------------------------- /rtl/NiosDevKit-EP1C20/stable-for-demo/fpgammix-cur.sof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tommythorn/fpgammix/ea2d962b9683a767d62735de62988f19295523da/rtl/NiosDevKit-EP1C20/stable-for-demo/fpgammix-cur.sof -------------------------------------------------------------------------------- /rtl/filter.v: -------------------------------------------------------------------------------- 1 | module filter(input clock, 2 | input in, 3 | output reg out, // out a filtered version of in 4 | output reg strobe); // true for one cycle synchronous with a change 5 | 6 | parameter freq = 25_000_000; // 25MHz 7 | parameter limit = 50_000; // 50kHz 8 | parameter dur = freq / limit; 9 | 10 | parameter N = 14; // INV: 2**N > dur; 11 | 12 | reg [N:0] countdown; 13 | 14 | // Filter out any meta stability 15 | reg in_, in__; 16 | 17 | always @(posedge clock) begin 18 | strobe <= 0; 19 | in_ <= in; 20 | in__ <= in_; 21 | if (in__ == out) 22 | countdown <= dur - 1; 23 | // Note, we depend on countdown[N] being reset here. 24 | else if (~countdown[N]) 25 | countdown <= countdown - 1; 26 | else begin 27 | out <= ~out; 28 | strobe <= 1; 29 | end 30 | end 31 | endmodule 32 | -------------------------------------------------------------------------------- /rtl/info_flags.mif: -------------------------------------------------------------------------------- 1 | WIDTH=8; 2 | DEPTH=256; 3 | ADDRESS_RADIX=UNS; 4 | DATA_RADIX=HEX; 5 | CONTENT BEGIN 6 | 0 : 0a; 7 | 1 : 2a; 8 | 2 : 2a; 9 | 3 : 2a; 10 | 4 : 2a; 11 | 5 : 26; 12 | 6 : 2a; 13 | 7 : 26; 14 | 8 : 26; 15 | 9 : 25; 16 | 10 : 26; 17 | 11 : 25; 18 | 12 : 26; 19 | 13 : 25; 20 | 14 : 26; 21 | 15 : 25; 22 | 16 : 2a; 23 | 17 : 2a; 24 | 18 : 2a; 25 | 19 : 2a; 26 | 20 : 2a; 27 | 21 : 26; 28 | 22 : 2a; 29 | 23 : 26; 30 | 24 : 2a; 31 | 25 : 29; 32 | 26 : 2a; 33 | 27 : 29; 34 | 28 : 2a; 35 | 29 : 29; 36 | 30 : 2a; 37 | 31 : 29; 38 | 32 : 2a; 39 | 33 : 29; 40 | 34 : 2a; 41 | 35 : 29; 42 | 36 : 2a; 43 | 37 : 29; 44 | 38 : 2a; 45 | 39 : 29; 46 | 40 : 2a; 47 | 41 : 29; 48 | 42 : 2a; 49 | 43 : 29; 50 | 44 : 2a; 51 | 45 : 29; 52 | 46 : 2a; 53 | 47 : 29; 54 | 48 : 2a; 55 | 49 : 29; 56 | 50 : 2a; 57 | 51 : 29; 58 | 52 : 26; 59 | 53 : 25; 60 | 54 : 26; 61 | 55 : 25; 62 | 56 : 2a; 63 | 57 : 29; 64 | 58 : 2a; 65 | 59 : 29; 66 | 60 : 2a; 67 | 61 : 29; 68 | 62 : 2a; 69 | 63 : 29; 70 | 64 : 50; 71 | 65 : 50; 72 | 66 : 50; 73 | 67 : 50; 74 | 68 : 50; 75 | 69 : 50; 76 | 70 : 50; 77 | 71 : 50; 78 | 72 : 50; 79 | 73 : 50; 80 | 74 : 50; 81 | 75 : 50; 82 | 76 : 50; 83 | 77 : 50; 84 | 78 : 50; 85 | 79 : 50; 86 | 80 : 50; 87 | 81 : 50; 88 | 82 : 50; 89 | 83 : 50; 90 | 84 : 50; 91 | 85 : 50; 92 | 86 : 50; 93 | 87 : 50; 94 | 88 : 50; 95 | 89 : 50; 96 | 90 : 50; 97 | 91 : 50; 98 | 92 : 50; 99 | 93 : 50; 100 | 94 : 50; 101 | 95 : 50; 102 | 96 : 3a; 103 | 97 : 39; 104 | 98 : 3a; 105 | 99 : 39; 106 | 100 : 3a; 107 | 101 : 39; 108 | 102 : 3a; 109 | 103 : 39; 110 | 104 : 3a; 111 | 105 : 39; 112 | 106 : 3a; 113 | 107 : 39; 114 | 108 : 3a; 115 | 109 : 39; 116 | 110 : 3a; 117 | 111 : 39; 118 | 112 : 2a; 119 | 113 : 29; 120 | 114 : 2a; 121 | 115 : 29; 122 | 116 : 2a; 123 | 117 : 29; 124 | 118 : 2a; 125 | 119 : 29; 126 | 120 : 2a; 127 | 121 : 29; 128 | 122 : 2a; 129 | 123 : 29; 130 | 124 : 2a; 131 | 125 : 29; 132 | 126 : 2a; 133 | 127 : 29; 134 | 128 : 2a; 135 | 129 : 29; 136 | 130 : 2a; 137 | 131 : 29; 138 | 132 : 2a; 139 | 133 : 29; 140 | 134 : 2a; 141 | 135 : 29; 142 | 136 : 2a; 143 | 137 : 29; 144 | 138 : 2a; 145 | 139 : 29; 146 | 140 : 2a; 147 | 141 : 29; 148 | 142 : 2a; 149 | 143 : 29; 150 | 144 : 2a; 151 | 145 : 29; 152 | 146 : 2a; 153 | 147 : 29; 154 | 148 : 3a; 155 | 149 : 39; 156 | 150 : 2a; 157 | 151 : 29; 158 | 152 : 2a; 159 | 153 : 29; 160 | 154 : 0a; 161 | 155 : 09; 162 | 156 : 0a; 163 | 157 : 09; 164 | 158 : 2a; 165 | 159 : 29; 166 | 160 : 1a; 167 | 161 : 19; 168 | 162 : 1a; 169 | 163 : 19; 170 | 164 : 1a; 171 | 165 : 19; 172 | 166 : 1a; 173 | 167 : 19; 174 | 168 : 1a; 175 | 169 : 19; 176 | 170 : 1a; 177 | 171 : 19; 178 | 172 : 1a; 179 | 173 : 19; 180 | 174 : 1a; 181 | 175 : 19; 182 | 176 : 1a; 183 | 177 : 19; 184 | 178 : 1a; 185 | 179 : 19; 186 | 180 : 0a; 187 | 181 : 09; 188 | 182 : 1a; 189 | 183 : 19; 190 | 184 : 0a; 191 | 185 : 09; 192 | 186 : 0a; 193 | 187 : 09; 194 | 188 : 0a; 195 | 189 : 09; 196 | 190 : aa; 197 | 191 : a9; 198 | 192 : 2a; 199 | 193 : 29; 200 | 194 : 2a; 201 | 195 : 29; 202 | 196 : 2a; 203 | 197 : 29; 204 | 198 : 2a; 205 | 199 : 29; 206 | 200 : 2a; 207 | 201 : 29; 208 | 202 : 2a; 209 | 203 : 29; 210 | 204 : 2a; 211 | 205 : 29; 212 | 206 : 2a; 213 | 207 : 29; 214 | 208 : 2a; 215 | 209 : 29; 216 | 210 : 2a; 217 | 211 : 29; 218 | 212 : 2a; 219 | 213 : 29; 220 | 214 : 2a; 221 | 215 : 29; 222 | 216 : 2a; 223 | 217 : 29; 224 | 218 : 2a; 225 | 219 : 29; 226 | 220 : 2a; 227 | 221 : 29; 228 | 222 : 2a; 229 | 223 : 29; 230 | 224 : 20; 231 | 225 : 20; 232 | 226 : 20; 233 | 227 : 20; 234 | 228 : 30; 235 | 229 : 30; 236 | 230 : 30; 237 | 231 : 30; 238 | 232 : 30; 239 | 233 : 30; 240 | 234 : 30; 241 | 235 : 30; 242 | 236 : 30; 243 | 237 : 30; 244 | 238 : 30; 245 | 239 : 30; 246 | 240 : 40; 247 | 241 : 40; 248 | 242 : e0; 249 | 243 : e0; 250 | 244 : 60; 251 | 245 : 60; 252 | 246 : 02; 253 | 247 : 01; 254 | 248 : 80; 255 | 249 : 00; 256 | 250 : 20; 257 | 251 : 82; 258 | 252 : 01; 259 | 253 : 00; 260 | 254 : 20; 261 | 255 : 0a; 262 | END; 263 | -------------------------------------------------------------------------------- /rtl/memory_interface.v: -------------------------------------------------------------------------------- 1 | /* 2 | * TODO: optimize for multiple writes in sequence 3 | */ 4 | 5 | module memory_interface 6 | (clkin, 7 | fse_a, fse_d, 8 | flash_cs_n, enet_aen, 9 | sram_cs_n, sram_be_n, sram_oe_n, sram_we_n, 10 | 11 | transfer_request, 12 | address, 13 | wren, 14 | wrdata, 15 | wrmask, 16 | wait_request, 17 | read_data_valid, 18 | read_data); 19 | 20 | parameter debug = 0; 21 | 22 | input wire clkin; 23 | 24 | // Flash-SRAM-Ethernet bus 25 | output reg [22:0] fse_a; // Mainboard common bus address 26 | inout wire [31:0] fse_d; // Mainboard common bus data 27 | output wire flash_cs_n; // Flash ROM CS# 28 | output wire enet_aen; // Ethernet Access Enable 29 | output wire sram_cs_n; // SRAM CS# 30 | output reg [3:0] sram_be_n; // SRAM byte enables 31 | output wire sram_oe_n; // SRAM OE# 32 | output wire sram_we_n; // SRAM WE# 33 | 34 | // Interface 35 | input wire transfer_request; 36 | input wire [31:0] address; 37 | input wire wren; 38 | input wire [31:0] wrdata; 39 | input wire [ 3:0] wrmask; 40 | 41 | output wire wait_request; 42 | output wire read_data_valid; 43 | // output reg [31:0] read_data; 44 | output wire [31:0] read_data; // XXX a bit reckless! 45 | 46 | parameter N = 4; // 0 1 2 3 4 5 47 | parameter MAX_CYCLES = (1 << (N - 1)) - 1; // X 0 1 3 7 15 48 | 49 | /* 50 | * @ 200MHz/5ns the address must be asserted for two cycles but 51 | * apparently that isn't enough... 52 | */ 53 | parameter READ_CYCLES = 0; // 25MHz 54 | parameter LATENCY = 1; // data is ready LATENCY cycles from accepted request 55 | 56 | /* How many cycles to assert the data and address 57 | * *while* writing, that is, not counting setup and teardown 58 | */ 59 | parameter WRITE_CYCLES = 1; // 25MHz 60 | 61 | parameter IDLE = 0; 62 | parameter READ = 1; 63 | parameter WRITE_PREPARE = 2; 64 | parameter WRITE_DO = 3; 65 | parameter DELAY_WRITE = 4; 66 | 67 | // Encode {cs_n,oe_n,we_n} as a command 68 | parameter SRAM_CMD_READ = 3'b001; // 'h1 69 | parameter SRAM_CMD_WRITE = 3'b010; // 'h2 70 | parameter SRAM_CMD_PRE_WRITE= 3'b011; // 'h3 71 | parameter SRAM_CMD_NOP = 3'b111; // 'h7 72 | 73 | reg [31:0] state = IDLE; 74 | reg [31:0] fse_d_out; 75 | reg [ N:0] countdown; 76 | reg [ 2:0] sram_cmd; 77 | reg [LATENCY:0] read_data_pipeline; 78 | /* XXX really should be LATENCY-1 but then the read_data_pipeline assignment 79 | * below fails for LATENCY == 1 It doesn't really affect anything 80 | */ 81 | 82 | assign flash_cs_n = 1'b1; // Disable flash ROM 83 | assign enet_aen = 1'b1; // Disable Ethernet 84 | assign {sram_cs_n,sram_oe_n,sram_we_n} = sram_cmd; 85 | assign fse_d = sram_oe_n ? fse_d_out : 32'hZZZZZZZZ; 86 | 87 | assign wait_request = state != IDLE; 88 | assign read_data_valid = read_data_pipeline[LATENCY-1]; 89 | assign read_data = fse_d; 90 | 91 | integer i; 92 | always @(posedge clkin) begin 93 | //read_data <= fse_d; 94 | //if(debug)$display("%06d MI: fse_d %x", $time, fse_d); 95 | countdown <= countdown - 1; 96 | read_data_pipeline <= {read_data_pipeline[LATENCY-1:0], 1'b0}; 97 | 98 | if (read_data_valid) 99 | if(debug)$display("%06d MI: read data %x", $time, read_data); 100 | 101 | case (state) 102 | IDLE: begin 103 | sram_cmd <= SRAM_CMD_READ; 104 | 105 | if (transfer_request) 106 | if (~wren) begin 107 | if(debug)$display("%06d MI: got a read command for address %x", $time, address); 108 | fse_a <= address; // XXX Notice, only 20-bit are valid for SRAM (18 if aligned) 109 | sram_be_n <= 0; 110 | if (READ_CYCLES) begin 111 | countdown <= READ_CYCLES - 2; // These underflow downcounters always use T - 2 112 | state <= READ; 113 | end else begin 114 | // I _can_ run @100+ MHz with a ~ 25 ns latency (strange) 115 | read_data_pipeline[0] <= 1; 116 | end 117 | end else begin 118 | if(debug)$display("%06d MI: got a write command for address %x <- %x mask %x", $time, address, wrdata, wrmask); 119 | fse_a <= address; // Notice, only 18-bit are valid for SRAM 120 | fse_d_out <= wrdata; 121 | sram_be_n <= ~wrmask; 122 | if (|read_data_pipeline) begin 123 | /* If there is an outstanding read command we have to wait 124 | for it to finish */ 125 | state <= DELAY_WRITE; 126 | end else begin 127 | sram_cmd <= SRAM_CMD_PRE_WRITE; 128 | state <= WRITE_PREPARE; 129 | end 130 | end 131 | end // case: IDLE 132 | 133 | READ: if (countdown[N]) begin 134 | read_data_pipeline[0] <= 1; 135 | state <= IDLE; 136 | end 137 | 138 | DELAY_WRITE: if (~|read_data_pipeline) begin 139 | sram_cmd <= SRAM_CMD_PRE_WRITE; 140 | state <= WRITE_PREPARE; 141 | end 142 | 143 | WRITE_PREPARE: begin 144 | sram_cmd <= SRAM_CMD_WRITE; 145 | countdown <= WRITE_CYCLES - 2;// These underflow downcounters always use T - 2 146 | state <= WRITE_DO; 147 | end 148 | 149 | WRITE_DO: if (countdown[N]) begin 150 | if(debug)$display("%06d MI: done writing", $time); 151 | sram_cmd <= SRAM_CMD_PRE_WRITE; 152 | state <= IDLE; 153 | end 154 | endcase 155 | end 156 | endmodule 157 | -------------------------------------------------------------------------------- /rtl/mmix_opcodes.v: -------------------------------------------------------------------------------- 1 | /* 2 | (let ((i 0)) 3 | (while (< i 256) 4 | (insert-string (format "parameter I_ = 8'h%02x;\n" i)) 5 | (setq i (+ i 1)))) 6 | */ 7 | parameter I_TRAP = 8'h00; 8 | parameter I_FCMP = 8'h01; 9 | parameter I_FUN = 8'h02; 10 | parameter I_FEQL = 8'h03; 11 | parameter I_FADD = 8'h04; 12 | parameter I_FIX = 8'h05; 13 | parameter I_FSUB = 8'h06; 14 | parameter I_FIXU = 8'h07; 15 | parameter I_FLOT = 8'h08; 16 | parameter I_FLOTI = 8'h09; 17 | parameter I_FLOTU = 8'h0a; 18 | parameter I_FLOTUI = 8'h0b; 19 | parameter I_SFLOT = 8'h0c; 20 | parameter I_SFLOTI = 8'h0d; 21 | parameter I_SFLOTU = 8'h0e; 22 | parameter I_SFLOTUI = 8'h0f; 23 | parameter I_FMUL = 8'h10; 24 | parameter I_FCMPE = 8'h11; 25 | parameter I_FUNE = 8'h12; 26 | parameter I_FEQLE = 8'h13; 27 | parameter I_FDIV = 8'h14; 28 | parameter I_FSQRT = 8'h15; 29 | parameter I_FREM = 8'h16; 30 | parameter I_FINT = 8'h17; 31 | parameter I_MUL = 8'h18; 32 | parameter I_MULI = 8'h19; 33 | parameter I_MULU = 8'h1a; 34 | parameter I_MULUI = 8'h1b; 35 | parameter I_DIV = 8'h1c; 36 | parameter I_DIVI = 8'h1d; 37 | parameter I_DIVU = 8'h1e; 38 | parameter I_DIVUI = 8'h1f; 39 | parameter I_ADD = 8'h20; 40 | parameter I_ADDI = 8'h21; 41 | parameter I_ADDU = 8'h22; 42 | parameter I_ADDUI = 8'h23; 43 | parameter I_SUB = 8'h24; 44 | parameter I_SUBI = 8'h25; 45 | parameter I_SUBU = 8'h26; 46 | parameter I_SUBUI = 8'h27; 47 | parameter I_2ADDU = 8'h28; 48 | parameter I_2ADDUI = 8'h29; 49 | parameter I_4ADDU = 8'h2a; 50 | parameter I_4ADDUI = 8'h2b; 51 | parameter I_8ADDU = 8'h2c; 52 | parameter I_8ADDUI = 8'h2d; 53 | parameter I_16ADDU = 8'h2e; 54 | parameter I_16ADDUI = 8'h2f; 55 | parameter I_CMP = 8'h30; 56 | parameter I_CMPI = 8'h31; 57 | parameter I_CMPU = 8'h32; 58 | parameter I_CMPUI = 8'h33; 59 | parameter I_NEG = 8'h34; 60 | parameter I_NEGI = 8'h35; 61 | parameter I_NEGU = 8'h36; 62 | parameter I_NEGUI = 8'h37; 63 | parameter I_SL = 8'h38; 64 | parameter I_SLI = 8'h39; 65 | parameter I_SLU = 8'h3a; 66 | parameter I_SLUI = 8'h3b; 67 | parameter I_SR = 8'h3c; 68 | parameter I_SRI = 8'h3d; 69 | parameter I_SRU = 8'h3e; 70 | parameter I_SRUI = 8'h3f; 71 | parameter I_BN = 8'h40; 72 | parameter I_BNB = 8'h41; 73 | parameter I_BZ = 8'h42; 74 | parameter I_BZB = 8'h43; 75 | parameter I_BP = 8'h44; 76 | parameter I_BPB = 8'h45; 77 | parameter I_BOD = 8'h46; 78 | parameter I_BODB = 8'h47; 79 | parameter I_BNN = 8'h48; 80 | parameter I_BNNB = 8'h49; 81 | parameter I_BNZ = 8'h4a; 82 | parameter I_BNZB = 8'h4b; 83 | parameter I_BNP = 8'h4c; 84 | parameter I_BNPB = 8'h4d; 85 | parameter I_BNOD = 8'h4e; // == EVEN 86 | parameter I_BNODB = 8'h4f; // == EVEN 87 | parameter I_PBN = 8'h50; 88 | parameter I_PBNB = 8'h51; 89 | parameter I_PBZ = 8'h52; 90 | parameter I_PBZB = 8'h53; 91 | parameter I_PBP = 8'h54; 92 | parameter I_PBPB = 8'h55; 93 | parameter I_PBOD = 8'h56; 94 | parameter I_PBODB = 8'h57; 95 | parameter I_PBNN = 8'h58; 96 | parameter I_PBNNB = 8'h59; 97 | parameter I_PBNZ = 8'h5a; 98 | parameter I_PBNZB = 8'h5b; 99 | parameter I_PBNP = 8'h5c; 100 | parameter I_PBNPB = 8'h5d; 101 | parameter I_PBNOD = 8'h5e; // == EVEN 102 | parameter I_PBNODB = 8'h5f; // == EVEN 103 | parameter I_CSN = 8'h60; 104 | parameter I_CSNI = 8'h61; 105 | parameter I_CSZ = 8'h62; 106 | parameter I_CSZI = 8'h63; 107 | parameter I_CSP = 8'h64; 108 | parameter I_CSPI = 8'h65; 109 | parameter I_CSOD = 8'h66; 110 | parameter I_CSODI = 8'h67; 111 | parameter I_CSNN = 8'h68; 112 | parameter I_CSNNI = 8'h69; 113 | parameter I_CSNZ = 8'h6a; 114 | parameter I_CSNZI = 8'h6b; 115 | parameter I_CSNP = 8'h6c; 116 | parameter I_CSNPI = 8'h6d; 117 | parameter I_CSEV = 8'h6e; 118 | parameter I_CSEVI = 8'h6f; 119 | parameter I_ZSN = 8'h70; 120 | parameter I_ZSNI = 8'h71; 121 | parameter I_ZSZ = 8'h72; 122 | parameter I_ZSZI = 8'h73; 123 | parameter I_ZSP = 8'h74; 124 | parameter I_ZSPI = 8'h75; 125 | parameter I_ZSOD = 8'h76; 126 | parameter I_ZSODI = 8'h77; 127 | parameter I_ZSNN = 8'h78; 128 | parameter I_ZSNNI = 8'h79; 129 | parameter I_ZSNZ = 8'h7a; 130 | parameter I_ZSNZI = 8'h7b; 131 | parameter I_ZSNP = 8'h7c; 132 | parameter I_ZSNPI = 8'h7d; 133 | parameter I_ZSEV = 8'h7e; 134 | parameter I_ZSEVI = 8'h7f; 135 | parameter I_LDB = 8'h80; 136 | parameter I_LDBI = 8'h81; 137 | parameter I_LDBU = 8'h82; 138 | parameter I_LDBUI = 8'h83; 139 | parameter I_LDW = 8'h84; 140 | parameter I_LDWI = 8'h85; 141 | parameter I_LDWU = 8'h86; 142 | parameter I_LDWUI = 8'h87; 143 | parameter I_LDT = 8'h88; 144 | parameter I_LDTI = 8'h89; 145 | parameter I_LDTU = 8'h8a; 146 | parameter I_LDTUI = 8'h8b; 147 | parameter I_LDO = 8'h8c; 148 | parameter I_LDOI = 8'h8d; 149 | parameter I_LDOU = 8'h8e; 150 | parameter I_LDOUI = 8'h8f; 151 | parameter I_LDSF = 8'h90; 152 | parameter I_LDSFI = 8'h91; 153 | parameter I_LDHT = 8'h92; 154 | parameter I_LDHTI = 8'h93; 155 | parameter I_CSWAP = 8'h94; 156 | parameter I_CSWAPI = 8'h95; 157 | parameter I_LDUNC = 8'h96; 158 | parameter I_LDUNCI = 8'h97; 159 | parameter I_LDVTS = 8'h98; 160 | parameter I_LDVTSI = 8'h99; 161 | parameter I_PRELD = 8'h9a; 162 | parameter I_PRELDI = 8'h9b; 163 | parameter I_PREGO = 8'h9c; 164 | parameter I_PREGOI = 8'h9d; 165 | parameter I_GO = 8'h9e; 166 | parameter I_GOI = 8'h9f; 167 | parameter I_STB = 8'ha0; 168 | parameter I_STBI = 8'ha1; 169 | parameter I_STBU = 8'ha2; 170 | parameter I_STBUI = 8'ha3; 171 | parameter I_STW = 8'ha4; 172 | parameter I_STWI = 8'ha5; 173 | parameter I_STWU = 8'ha6; 174 | parameter I_STWUI = 8'ha7; 175 | parameter I_STT = 8'ha8; 176 | parameter I_STTI = 8'ha9; 177 | parameter I_STTU = 8'haa; 178 | parameter I_STTUI = 8'hab; 179 | parameter I_STO = 8'hac; 180 | parameter I_STOI = 8'had; 181 | parameter I_STOU = 8'hae; 182 | parameter I_STOUI = 8'haf; 183 | parameter I_STSF = 8'hb0; 184 | parameter I_STSFI = 8'hb1; 185 | parameter I_STHT = 8'hb2; 186 | parameter I_STHTI = 8'hb3; 187 | parameter I_STCO = 8'hb4; 188 | parameter I_STCOI = 8'hb5; 189 | parameter I_STUNC = 8'hb6; 190 | parameter I_STUNCI = 8'hb7; 191 | parameter I_SYNCD = 8'hb8; 192 | parameter I_SYNCDI = 8'hb9; 193 | parameter I_PREST = 8'hba; 194 | parameter I_PRESTI = 8'hbb; 195 | parameter I_SYNCID = 8'hbc; 196 | parameter I_SYNCIDI = 8'hbd; 197 | parameter I_PUSHGO = 8'hbe; 198 | parameter I_PUSHGOI = 8'hbf; 199 | parameter I_OR = 8'hc0; 200 | parameter I_ORI = 8'hc1; 201 | parameter I_ORN = 8'hc2; 202 | parameter I_ORNI = 8'hc3; 203 | parameter I_NOR = 8'hc4; 204 | parameter I_NORI = 8'hc5; 205 | parameter I_XOR = 8'hc6; 206 | parameter I_XORI = 8'hc7; 207 | parameter I_AND = 8'hc8; 208 | parameter I_ANDI = 8'hc9; 209 | parameter I_ANDN = 8'hca; 210 | parameter I_ANDNI = 8'hcb; 211 | parameter I_NAND = 8'hcc; 212 | parameter I_NANDI = 8'hcd; 213 | parameter I_NXOR = 8'hce; 214 | parameter I_NXORI = 8'hcf; 215 | parameter I_BDIF = 8'hd0; 216 | parameter I_BDIFI = 8'hd1; 217 | parameter I_WDIF = 8'hd2; 218 | parameter I_WDIFI = 8'hd3; 219 | parameter I_TDIF = 8'hd4; 220 | parameter I_TDIFI = 8'hd5; 221 | parameter I_ODIF = 8'hd6; 222 | parameter I_ODIFI = 8'hd7; 223 | parameter I_MUX = 8'hd8; 224 | parameter I_MUXI = 8'hd9; 225 | parameter I_SADD = 8'hda; 226 | parameter I_SADDI = 8'hdb; 227 | parameter I_MOR = 8'hdc; 228 | parameter I_MORI = 8'hdd; 229 | parameter I_MXOR = 8'hde; 230 | parameter I_MXORI = 8'hdf; 231 | parameter I_SETH = 8'he0; 232 | parameter I_SETMH = 8'he1; 233 | parameter I_SETML = 8'he2; 234 | parameter I_SETL = 8'he3; 235 | parameter I_INCH = 8'he4; 236 | parameter I_INCMH = 8'he5; 237 | parameter I_INCML = 8'he6; 238 | parameter I_INCL = 8'he7; 239 | parameter I_ORH = 8'he8; 240 | parameter I_ORMH = 8'he9; 241 | parameter I_ORML = 8'hea; 242 | parameter I_ORL = 8'heb; 243 | parameter I_ANDNH = 8'hec; 244 | parameter I_ANDNMH = 8'hed; 245 | parameter I_ANDNML = 8'hee; 246 | parameter I_ANDNL = 8'hef; 247 | parameter I_JMP = 8'hf0; 248 | parameter I_JMPB = 8'hf1; 249 | parameter I_PUSHJ = 8'hf2; 250 | parameter I_PUSHJB = 8'hf3; 251 | parameter I_GETA = 8'hf4; 252 | parameter I_GETAB = 8'hf5; 253 | parameter I_PUT = 8'hf6; 254 | parameter I_PUTI = 8'hf7; 255 | parameter I_POP = 8'hf8; 256 | parameter I_RESUME = 8'hf9; 257 | parameter I_SAVE = 8'hfa; 258 | parameter I_UNSAVE = 8'hfb; 259 | parameter I_SYNC = 8'hfc; 260 | parameter I_SWYM = 8'hfd; 261 | parameter I_GET = 8'hfe; 262 | parameter I_TRIP = 8'hff; 263 | 264 | /* Special registers */ 265 | parameter REG_B = 0; 266 | parameter REG_D = 1; 267 | parameter REG_E = 2; 268 | parameter REG_H = 3; 269 | parameter REG_J = 4; 270 | parameter REG_M = 5; 271 | parameter REG_R = 6; 272 | parameter REG_BB = 7; 273 | parameter REG_C = 8; 274 | parameter REG_N = 9; 275 | parameter REG_O = 10; 276 | parameter REG_S = 11; 277 | parameter REG_I = 12; // Priviledged vvvvvvvv 278 | parameter REG_T = 13; 279 | parameter REG_TT = 14; 280 | parameter REG_K = 15; 281 | parameter REG_Q = 16; 282 | parameter REG_U = 17; 283 | parameter REG_V = 18; // ^^^^^^^^^^^^^^^^^^^^ 284 | parameter REG_G = 19; 285 | parameter REG_L = 20; 286 | parameter REG_A = 21; 287 | parameter REG_F = 22; 288 | parameter REG_P = 23; 289 | parameter REG_W = 24; 290 | parameter REG_X = 25; 291 | parameter REG_Y = 26; 292 | parameter REG_Z = 27; 293 | parameter REG_WW = 28; 294 | parameter REG_XX = 29; 295 | parameter REG_YY = 30; 296 | parameter REG_ZZ = 31; 297 | -------------------------------------------------------------------------------- /rtl/pdm.v: -------------------------------------------------------------------------------- 1 | module pdm(clk, level, O); 2 | 3 | parameter N = 16; /* The resolution in bits */ 4 | 5 | 6 | input wire clk; 7 | input wire [N-1:0] level; 8 | output wire O; 9 | 10 | /* 11 | * A completely ridiculous side project. Pulse Density Modulation 12 | * for controlling led intensity. The theory is pretty simple: 13 | * given a desired target level 0 <= T <= 1, control the output O 14 | * in {1,0}, such that O on on average is T. Do this by 15 | * integrating the error T - O over time and switching O such that 16 | * the sum of (T - O) is finite. 17 | * 18 | * S = 0, O = 0 19 | * forever 20 | * S = S + (T - O) 21 | * if (S >= 0) 22 | * O = 1 23 | * else 24 | * O = 0 25 | * 26 | * Check: T=0, O is never turned on; T=1, O is always on; T=0.5, O toggles 27 | * 28 | * In fixed point arithmetic this becomes even simpler (assume N-bit arith) 29 | * S = Sf * 2^N = Sf << N. As |S| <= 1, N+2 bits is sufficient 30 | * 31 | * S = 0, O = 0 32 | * forever 33 | * D = T + (~O + 1) << N === T + (O << N) + (O << (N+1)) 34 | * S = S + D 35 | * O = 1 & ~(S >> (N+1)) 36 | */ 37 | 38 | reg [N+1:0] sigma = 0; 39 | assign O = ~sigma[N+1]; 40 | always @(posedge clk) sigma <= sigma + {O,O,level}; 41 | endmodule // pdm 42 | -------------------------------------------------------------------------------- /rtl/rs232.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/10ps 2 | module rs232(input wire clk, 3 | input wire rst, 4 | 5 | // Master connections 6 | input wire `REQ rs232_req, 7 | output wire `RES rs232_res, 8 | 9 | input wire rs232in_attention, 10 | input wire [7:0] rs232in_data, 11 | 12 | input wire rs232out_busy, 13 | output wire rs232out_w, 14 | output wire [7:0] rs232out_d); 15 | 16 | parameter debug = 1; 17 | 18 | reg [31:0] tsc = 0; // A free running counter.... 19 | reg [ 7:0] rs232in_cnt = 0; 20 | 21 | wire [31:0] addr = rs232_req`A; 22 | reg [31:0] rd_data = 0; 23 | assign rs232_res`RD = rd_data; 24 | assign rs232_res`HOLD = 0; 25 | 26 | always @(posedge clk) 27 | if (rst) begin 28 | rd_data <= 0; 29 | tsc <= 0; 30 | rs232in_cnt <= 0; 31 | end else begin 32 | rd_data <= 0; 33 | tsc <= tsc + 1; 34 | if (rs232in_attention) 35 | rs232in_cnt <= rs232in_cnt + 1'h1; 36 | 37 | if (rs232_req`R) 38 | case (addr[3:2]) 39 | 0: rd_data <= {31'h0,rs232out_busy};// 0 40 | 1: rd_data <= {24'h0,rs232in_data}; // 4 41 | 2: rd_data <= {24'h0,rs232in_cnt}; // 8 42 | 3: rd_data <= tsc; // 12 43 | endcase 44 | end 45 | 46 | // wire rs232en = (peri_ctrl_req`A & 'hFFF0) == 'h0000; 47 | assign rs232out_d = rs232_req`WD; 48 | assign rs232out_w = rs232_req`W & addr[3:0] == 0; 49 | 50 | /* 51 | always @* 52 | if (debug) 53 | $display("%5d RS232: rs232out_w %d rs232out_busy %d (addr %x)", $time, 54 | rs232out_w, rs232out_busy, 55 | addr); 56 | */ 57 | endmodule 58 | -------------------------------------------------------------------------------- /rtl/rs232in.v: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright 2004 Tommy Thorn - All Rights Reserved 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, Inc., 53 Temple Place Ste 330, 8 | // Bostom MA 02111-1307, USA; either version 2 of the License, or 9 | // (at your option) any later version; incorporated herein by reference. 10 | // 11 | // ----------------------------------------------------------------------- 12 | 13 | `timescale 1ns/10ps 14 | 15 | module rs232in(// Control 16 | input wire clk25MHz, 17 | input wire reset, 18 | 19 | // Serial line 20 | input wire serial_rxd, 21 | output reg attention = 0, 22 | output reg [7:0] data = 0); 23 | 24 | //parameter bps = 9_600; 25 | parameter bps = 115_200; 26 | parameter frequency = 25_000_000; 27 | parameter period = frequency / bps - 1; 28 | 29 | reg [16:0] ttyclk = 0; 30 | reg [7:0] shift_in = 0; 31 | reg [4:0] count = 0; 32 | 33 | reg rxd = 0; 34 | reg rxd2 = 0; 35 | 36 | /* 37 | * The theory: look for a negedge, then wait 1.5 bit period to skip 38 | * start bit and center in first bit. Keep shifting bits until a full 39 | * byte is collected. 40 | * 41 | * Start Stop 42 | * data ~\__ B0 B1 B2 B3 B4 B5 B6 B7 ~~ 43 | * count 8 7 6 5 4 3 2 1 44 | */ 45 | always @(posedge clk25MHz) 46 | if (reset) begin 47 | shift_in <= 0; 48 | ttyclk <= 0; 49 | count <= 0; 50 | attention <= 0; 51 | rxd2 <= ~0; 52 | rxd <= ~0; 53 | end else begin 54 | attention <= 0; 55 | 56 | // Get rid of meta stability. 57 | {rxd2,rxd} <= {rxd,serial_rxd}; 58 | 59 | if (~ttyclk[16]) begin 60 | ttyclk <= ttyclk - 1; 61 | end else if (count) begin 62 | if (count == 1) begin 63 | data <= {rxd2, shift_in[7:1]}; 64 | attention <= 1; 65 | end 66 | 67 | count <= count - 1; 68 | shift_in <= {rxd2, shift_in[7:1]}; // Shift in from the left 69 | ttyclk <= period - 2; 70 | end else if (~rxd2) begin 71 | // Just saw the negedge of the start bit 72 | ttyclk <= (3 * period) / 2 - 2; 73 | count <= 8; 74 | end 75 | end 76 | endmodule 77 | -------------------------------------------------------------------------------- /rtl/rs232out.v: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright 2004,2006 Tommy Thorn - All Rights Reserved 4 | // 5 | // This program is free software; you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, Inc., 53 Temple Place Ste 330, 8 | // Bostom MA 02111-1307, USA; either version 2 of the License, or 9 | // (at your option) any later version; incorporated herein by reference. 10 | // 11 | // ----------------------------------------------------------------------- 12 | 13 | `timescale 1ns/10ps 14 | 15 | module rs232out(// Control 16 | input wire clk25MHz, 17 | input wire rst, 18 | 19 | // Serial line 20 | output wire serial_txd, 21 | 22 | // Wishbone Interface 23 | input wire [7:0] data, 24 | input wire we, 25 | output wire busy); 26 | 27 | //parameter bps = 9_600; 28 | parameter bps = 115_200; 29 | parameter frequency = 25_000_000; 30 | `ifndef __ICARUS__ 31 | parameter period = frequency / bps; 32 | `else 33 | // One of the very few simulation artifacts we have to deal with at the source level. 34 | parameter period = 0; 35 | `endif 36 | parameter TTYCLK_SIGN = 12; // 2^TTYCLK_SIGN > period * 2 37 | parameter COUNT_SIGN = 4; 38 | 39 | reg [TTYCLK_SIGN:0] ttyclk = 0; // [-4096; 4095] 40 | reg [8:0] shift_out = 0; 41 | reg [COUNT_SIGN:0] count = 0; // [-16; 15] 42 | 43 | assign serial_txd = shift_out[0]; 44 | assign busy = ~count[COUNT_SIGN] | ~ttyclk[TTYCLK_SIGN]; 45 | 46 | always @(posedge clk25MHz) 47 | if (rst) begin 48 | shift_out <= 9'h1F; 49 | ttyclk <= ~0; 50 | count <= ~0; 51 | end else if (~ttyclk[TTYCLK_SIGN]) begin 52 | ttyclk <= ttyclk - 1; 53 | end else if (~count[COUNT_SIGN]) begin 54 | ttyclk <= period - 2; 55 | count <= count - 1; 56 | shift_out <= {1'b1, shift_out[8:1]}; 57 | end else if (we) begin 58 | ttyclk <= period - 2; 59 | count <= 9; // 1 start bit + 8 data + 1 stop - 1 due to SIGN trick 60 | shift_out <= {data, 1'b0}; 61 | end 62 | endmodule 63 | -------------------------------------------------------------------------------- /tools/data2mif.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | depth=256 4 | 5 | printf "WIDTH=32;\n" 6 | printf "DEPTH=%d;\n" $depth 7 | printf "ADDRESS_RADIX=HEX;\n" 8 | printf "DATA_RADIX=HEX;\n" 9 | printf "CONTENT BEGIN\n" 10 | a=0 11 | while read v 12 | do 13 | printf " %02x : %08x ;\n" $a 0x$v 14 | a=$(($a + 1)) 15 | done < $1 16 | printf " [%02x..%x] : 00000000;\n" $a $((depth - 1)) 17 | printf "END;\n" 18 | -------------------------------------------------------------------------------- /workloads/Makefile: -------------------------------------------------------------------------------- 1 | FPGAMMIX_DIR=/home/tommy/fpgammix 2 | MMIX_TOOLS_BIN=/opt/mmix/bin 3 | 4 | # XXX -mno-base-addresses should be the default! -mbase-addresses is 5 | # completely unscalable, running out of globals within 30 uses. 6 | 7 | all: readmoto.mmo hwfb.elf #myfib-verbose.sim 8 | 9 | #CFLAGS=-mno-base-addresses -O2 -fomit-frame-pointer 10 | CC=$(MMIX_TOOLS_BIN)/mmix-gcc 11 | CFLAGS=-O -fomit-frame-pointer -std=gnu99 12 | LDOPTS= 13 | #LDOPTS=-Ttext=80000000 14 | T=1 15 | 16 | %.run-fpgammix-sim: %.txt # $(FPGAMMIX_DIR)/rtl/Icarus/initmem.data 17 | $(MAKE) -C $(FPGAMMIX_DIR)/workloads/tinymon 18 | cp $< $(FPGAMMIX_DIR)/rtl/Icarus/input.txt 19 | $(MAKE) -C $(FPGAMMIX_DIR)/rtl/Icarus; 20 | 21 | %.mmo: %.elf 22 | mmix-objcopy -I elf64-mmix -O mmo $< $@ 23 | 24 | overflow3.elf: overflow3.o 25 | $(MMIX_TOOLS_BIN)/mmix-ld -Ttext=0 -melf64mmix $< -o $@ 26 | $(MMIX_TOOLS_BIN)/mmix-objdump -d $@ 27 | 28 | 29 | 30 | %.mmosim: %.mmo 31 | mmix -l -t$(T) $< 32 | 33 | %.elfsim: %.elf 34 | mmix -t$(T) $< 35 | 36 | %.mmo: %.mms 37 | mmixal -l $@.lst -o $@ $< 38 | 39 | #%.o: %.mmo 40 | # $(MMIX_TOOLS_BIN)/mmix-objcopy -I mmo -O elf64-mmix $< $@ 41 | 42 | %.o: %.c Makefile 43 | $(CC) $(CFLAGS) -c $< -o $@ 44 | 45 | %.o: %.s Makefile 46 | $(CC) $(CFLAGS) -c $< -o $@ 47 | 48 | %.o: %.S Makefile 49 | $(CC) $(CFLAGS) -c $< -o $@ 50 | 51 | %.elf.lite: %.o Makefile 52 | $(MMIX_TOOLS_BIN)/mmix-ld -Ttext=800 -melf64mmix $< -o $@ 53 | $(MMIX_TOOLS_BIN)/mmix-objdump -d $@ 54 | 55 | %.elf: %.o 56 | $(CC) $(CFLAGS) -Ttext=800 -melf $< -o $@ 57 | $(MMIX_TOOLS_BIN)/mmix-objdump -d $@ 58 | 59 | # Sigh, SREC doesn't cover 64-bit addresses. 60 | %.data.lite: %.elf.lite 61 | $(MMIX_TOOLS_BIN)/mmix-objdump -s $< | grep '^ '|cut -d' ' -f3-6|tr ' ' '\n' | grep -v '^$$' > $@ 62 | 63 | %.data: %.elf 64 | $(MMIX_TOOLS_BIN)/mmix-objdump -s $< | grep '^ '|cut -d' ' -f3-6|tr ' ' '\n' | grep -v '^$$' > $@ 65 | 66 | %.mif: %.data 67 | $(FPGAMMIX_DIR)/tools/data2mif.sh $< > $@ 68 | 69 | %.txt.lite: %.elf.lite 70 | $(MMIX_TOOLS_BIN)/mmix-objdump -s $<|cut -d' ' -f-6 > $@ 71 | $(MMIX_TOOLS_BIN)/mmix-nm $< |grep 'T main'|(read x y;echo " $$x"G) >> $@ 72 | 73 | # $(MMIX_TOOLS_BIN)/mmix-strip $< 74 | 75 | %.txt: %.elf 76 | $(MMIX_TOOLS_BIN)/mmix-strip $< -o $<.stripped 77 | $(MMIX_TOOLS_BIN)/mmix-objdump -s $<.stripped|cut -d' ' -f-6 > $@ 78 | $(MMIX_TOOLS_BIN)/mmix-nm $< |grep 'T Main'|(read x y;echo " $$x"G) >> $@ 79 | 80 | 81 | %.dis: %.elf 82 | $(MMIX_TOOLS_BIN)/mmix-objdump -d $< 83 | 84 | %.emu: %.txt 85 | cp $< $(FPGAMMIX_DIR)/rtl/Icarus/input.txt 86 | cd $(FPGAMMIX_DIR)/rtl/Icarus; make 87 | 88 | clean: 89 | -rm *.elf *.elf.stripped *.o *.txt 90 | -------------------------------------------------------------------------------- /workloads/Tetris/Makefile: -------------------------------------------------------------------------------- 1 | target: tetris.txt 2 | 3 | include ../Makefile 4 | -------------------------------------------------------------------------------- /workloads/Tetris/tetris.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | //extern void setitimer(int, long *, int), system(char *), sigvec(), srand(int), exit(int); 4 | //extern int atoi(char *), rand(void), getpid(void); 5 | 6 | #ifndef __mmix__ 7 | long h[4]; 8 | 9 | int t(void) 10 | { 11 | h[3] -= h[3] / 3000; 12 | 13 | setitimer(0, h, 0); 14 | } 15 | #endif 16 | 17 | int key, d, level; 18 | 19 | int v[] = {(int)t, 0, 2}; 20 | 21 | int w, s, I, K = 0, i = 276, j, k, q[276], Q[276], *n = q, *m, x = 17; 22 | 23 | int shape[] = { 24 | 7, -13, -12, 1, // 0 0 -> 7 -> 0 25 | 8, -11, -12, -1, // 1 1 -> 8 -> 1 26 | 9, -1, 1, 12, // 2 2 -> 9 -> 10 -> 11 -> 2 27 | 3, -13, -12, -1, // 3 Square block! 28 | 12, -1, 11, 1, // 4 4 -> 12 -> 13 -> 14 -> 4 29 | 15, -1, 13, 1, // 5 5 -> 15 -> 16 -> 17 -> 5 30 | 18, -1, 1, 2, // 6 6 -> 18 -> 6 31 | 0, -12, -1, 11, // 7 32 | 1, -12, 1, 13, // 8 33 | 10, -12, 1, 12, // 9 34 | 11, -12, -1, 1, // 10 35 | 2, -12, -1, 12, // 11 36 | 13, -12, 12, 13, // 12 37 | 14, -11, -1, 1, // 13 38 | 4, -13, -12, 12, // 14 39 | 16, -11,-12, 12, // 15 40 | 17, -13, 1, -1, // 16 41 | 5, -12, 12, 11, // 17 42 | 6, -12, 12, 24 // 18 43 | }; 44 | 45 | // Lazy screen refresh 46 | int update(void) 47 | { 48 | for (i = 11; ++i < 264;) 49 | if ((k = q[i]) - Q[i]) { 50 | Q[i] = k; 51 | if (i - ++I || i % 12 < 1) { 52 | I = i; 53 | #ifdef __mmix__ 54 | gotoxy(i % 12 * 2 + 28, i / 12); 55 | #else 56 | printf("\033[%d;%dH", 57 | i / 12, 58 | i % 12 * 2 + 28); 59 | #endif 60 | } 61 | #ifdef __mmix__ 62 | mmix_putchar("# "[!k]); 63 | #else 64 | printf("\033[%dm " + (K - k ? 0 : 5), k); 65 | K = k; 66 | #endif 67 | } 68 | Q[263] = key = getchar(); 69 | } 70 | 71 | // Test position 72 | int test_brick(long newpos) 73 | { 74 | long i; 75 | 76 | for (i = 4; --i;) 77 | if (q[newpos + n[i]]) 78 | return 0; 79 | 80 | if (q[newpos]) 81 | return 0; 82 | 83 | return 1; 84 | } 85 | 86 | // Move 87 | int draw_brick(long color) 88 | { 89 | long i; 90 | for (i = 4; --i;) 91 | q[x + n[i]] = color; 92 | q[x] = color; 93 | } 94 | 95 | int main(long argc, char **argv) 96 | { 97 | char *a; 98 | 99 | h[3] = 1000000 / (level = argc > 1 ? atoi(argv[1]) : 2); 100 | 101 | a = argc > 2 ? argv[2] : "jkl pq"; 102 | 103 | /* Draw the board */ 104 | for (i = 276; i; --i) 105 | *n++ = i < 25 || i % 12 < 2 ? 7 : 0; 106 | 107 | #ifndef __mmix__ 108 | srand(getpid()); 109 | system("stty cbreak -echo stop u"); 110 | sigvec(14, v, 0); 111 | #endif 112 | 113 | t(); 114 | 115 | #ifdef __mmix__ 116 | stdout = 1; 117 | fb_clear(); 118 | #else 119 | puts("\033[H\033[J"); 120 | #endif 121 | 122 | for (n = shape + rand() % 7 * 4;; draw_brick(7), update(), draw_brick(0)) { 123 | if (key < 0) { 124 | if (test_brick(x + 12)) 125 | x += 12; 126 | else { 127 | draw_brick(7); 128 | ++w; 129 | for (j = 0; j < 252; j = 12 * (j / 12 + 1)) 130 | for (; q[++j];) 131 | if (j % 12 == 10) { 132 | for (; j % 12; q[j--] = 0) 133 | ; 134 | update(); 135 | for (; --j; q[j + 12] = q[j]) 136 | ; 137 | update(); 138 | } 139 | n = shape + rand() % 7 * 4; 140 | test_brick(x = 17) || (key = a[5]); 141 | } 142 | } 143 | 144 | // Move left 145 | if (key == a[0]) 146 | test_brick(--x) || ++x; 147 | 148 | // Rotate 149 | if (key == a[1]) 150 | n = shape + 4 * *(m = n), test_brick(x) || (n = m); 151 | 152 | // Move Right 153 | if (key == a[2]) 154 | test_brick(++x) || --x; 155 | 156 | // Drop 157 | if (key == a[3]) 158 | for (; test_brick(x + 12); ++w) 159 | x += 12; 160 | 161 | if (key == a[4] || key == a[5]) { 162 | #ifndef __mmix__ 163 | s = sigblock(8192); 164 | printf("\033[H\033[J\033[0m%d\n", w); 165 | if (key == a[5]) 166 | break; 167 | for (j = 264; j--; Q[j] = 0); 168 | while (getchar() - a[4]) 169 | ; 170 | puts("\033[H\033[J\033[7m"); 171 | sigsetmask(s); 172 | #else 173 | exit(0); 174 | #endif 175 | } 176 | } 177 | #ifndef __mmix__ 178 | d = popen("stty -cbreak echo stop \023;cat - HI|sort -rn|head -20>/tmp/$$;mv /tmp/$$ HI;cat HI", "w"); 179 | fprintf(d, "%4d on level %1d by %s\n", w, level, getlogin()); 180 | pclose(d); 181 | #endif 182 | } 183 | -------------------------------------------------------------------------------- /workloads/Tetris/tetris.c.52.mach: -------------------------------------------------------------------------------- 1 | 2 | ;; Function t (t) 3 | 4 | (note 2 0 5 NOTE_INSN_DELETED) 5 | 6 | (note 5 2 37 [bb 0] NOTE_INSN_BASIC_BLOCK) 7 | 8 | (insn/f 37 5 38 (set (reg/f:DI 254 $254) 9 | (plus:DI (reg/f:DI 254 $254) 10 | (const_int -8 [0xfffffffffffffff8]))) -1 (nil) 11 | (nil)) 12 | 13 | (insn/f 38 37 39 (set (mem:DI (reg/f:DI 254 $254) [0 S8 A64]) 14 | (reg/f:DI 253 $253)) -1 (nil) 15 | (nil)) 16 | 17 | (insn/f 39 38 40 (set (reg/f:DI 253 $253) 18 | (plus:DI (reg/f:DI 254 $254) 19 | (const_int 8 [0x8]))) -1 (nil) 20 | (nil)) 21 | 22 | (note 40 39 33 NOTE_INSN_PROLOGUE_END) 23 | 24 | (insn 33 40 3 (set (reg:DI 3 $3 [274]) 25 | (reg:DI 259 rJ)) 3 {movdi} (nil) 26 | (nil)) 27 | 28 | (note 3 33 8 NOTE_INSN_FUNCTION_BEG) 29 | 30 | (insn 8 3 9 (set (reg:DI 2 $2 [orig:271 D.1867 ] [271]) 31 | (mem/s/j:DI (const:DI (plus:DI (symbol_ref:DI ("h") ) 32 | (const_int 24 [0x18]))) [0 h+24 S8 A64])) 3 {movdi} (nil) 33 | (nil)) 34 | 35 | (insn 9 8 10 (set (reg:DI 1 $1 [orig:270 D.1868 ] [270]) 36 | (mem/s/j:DI (const:DI (plus:DI (symbol_ref:DI ("h") ) 37 | (const_int 24 [0x18]))) [0 h+24 S8 A64])) 3 {movdi} (nil) 38 | (nil)) 39 | 40 | (insn 10 9 35 (set (reg:DI 0 $0 [273]) 41 | (const_int 3000 [0xbb8])) 3 {movdi} (nil) 42 | (nil)) 43 | 44 | (insn 35 10 36 (set (reg:DI 4 $4) 45 | (reg:DI 1 $1 [orig:270 D.1868 ] [270])) 3 {movdi} (nil) 46 | (nil)) 47 | 48 | (insn 36 35 11 (set (reg:DI 5 $5) 49 | (reg:DI 0 $0 [273])) 3 {movdi} (nil) 50 | (nil)) 51 | 52 | (insn 11 36 12 (parallel [ 53 | (set (reg:DI 0 $0 [orig:269 D.1869 ] [269]) 54 | (div:DI (reg:DI 4 $4) 55 | (reg:DI 5 $5))) 56 | (clobber (reg:DI 4 $4)) 57 | (clobber (reg:DI 5 $5)) 58 | (clobber (reg:DI 260 rR)) 59 | ]) 20 {*divdi3_nonknuth} (nil) 60 | (nil)) 61 | 62 | (insn 12 11 13 (set (reg:DI 0 $0 [orig:268 D.1870 ] [268]) 63 | (minus:DI (reg:DI 2 $2 [orig:271 D.1867 ] [271]) 64 | (reg:DI 0 $0 [orig:269 D.1869 ] [269]))) 9 {subdi3} (nil) 65 | (nil)) 66 | 67 | (insn 13 12 15 (set (mem/s/j:DI (const:DI (plus:DI (symbol_ref:DI ("h") ) 68 | (const_int 24 [0x18]))) [0 h+24 S8 A64]) 69 | (reg:DI 0 $0 [orig:268 D.1870 ] [268])) 3 {movdi} (nil) 70 | (nil)) 71 | 72 | (insn 15 13 16 (set (reg:DI 16 $16) 73 | (const_int 0 [0x0])) 3 {movdi} (nil) 74 | (nil)) 75 | 76 | (insn 16 15 17 (set (reg:DI 17 $17) 77 | (symbol_ref:DI ("h") )) 3 {movdi} (nil) 78 | (nil)) 79 | 80 | (insn 17 16 18 (set (reg:DI 18 $18) 81 | (const_int 0 [0x0])) 3 {movdi} (nil) 82 | (nil)) 83 | 84 | (call_insn 18 17 19 (parallel [ 85 | (set (reg:SI 15 $15) 86 | (call (mem:QI (symbol_ref/v:DI ("setitimer") ) [0 S1 A8]) 87 | (const_int 0 [0x0]))) 88 | (use (reg 19 $19)) 89 | (clobber (reg:DI 259 rJ)) 90 | ]) 56 {*call_value_real} (nil) 91 | (nil) 92 | (expr_list:REG_DEP_TRUE (use (reg:DI 18 $18)) 93 | (expr_list:REG_DEP_TRUE (use (reg:DI 17 $17)) 94 | (expr_list:REG_DEP_TRUE (use (reg:DI 16 $16)) 95 | (nil))))) 96 | 97 | (insn 19 18 20 (set (reg:DI 259 rJ) 98 | (reg:DI 3 $3 [274])) 3 {movdi} (nil) 99 | (nil)) 100 | 101 | (note 20 19 24 NOTE_INSN_FUNCTION_END) 102 | 103 | (insn 24 20 29 (clobber (reg/i:SI 0 $0)) -1 (nil) 104 | (nil)) 105 | 106 | (insn 29 24 41 (use (reg/i:SI 0 $0)) -1 (nil) 107 | (nil)) 108 | 109 | (note 41 29 42 NOTE_INSN_EPILOGUE_BEG) 110 | 111 | (insn 42 41 43 (set (reg/f:DI 253 $253) 112 | (mem:DI (reg/f:DI 254 $254) [0 S8 A64])) -1 (nil) 113 | (nil)) 114 | 115 | (insn 43 42 44 (set (reg/f:DI 254 $254) 116 | (plus:DI (reg/f:DI 254 $254) 117 | (const_int 8 [0x8]))) -1 (nil) 118 | (nil)) 119 | 120 | (jump_insn 44 43 45 (return) -1 (nil) 121 | (nil)) 122 | 123 | (barrier 45 44 34) 124 | 125 | (note 34 45 0 NOTE_INSN_DELETED) 126 | -------------------------------------------------------------------------------- /workloads/Tetris/tromp.bsd.c: -------------------------------------------------------------------------------- 1 | long h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}c,d,l,v[]={(int)t,0,2},w,s,I,K 2 | =0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9,-1,1, 3 | 12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,10,-12, 4 | 1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-11,-12, 5 | 12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=q[i])-Q[i] 6 | ){Q[i]=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);printf( 7 | "\033[%dm "+(K-k?0:5),k);K=k;}Q[263]=c=getchar();}G(b){for(i=4;i--;)if(q[i?b+ 8 | n[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char* 9 | *V,*a;{h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i< 10 | 25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo stop u");sigvec(14,v, 11 | 0);t();puts("\033[H\033[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c<0){if(G(x+ 12 | 12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)if(j%12==10){ 13 | for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G(x=17)||(c 14 | =a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if(c==a[2])G 15 | (++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){s=sigblock( 16 | 8192);printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]= 17 | 0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}d=popen( 18 | "stty -cbreak echo stop \023;cat - HI|sort -rn|head -20>/tmp/$$;mv /tmp/$$ HI\ 19 | ;cat HI","w");fprintf(d,"%4d on level %1d by %s\n",w,l,getlogin());pclose(d);} 20 | -------------------------------------------------------------------------------- /workloads/audio/Makefile: -------------------------------------------------------------------------------- 1 | target: test-audio.txt 2 | 3 | include ../Makefile 4 | 5 | CFLAGS=-Wall -O -fomit-frame-pointer -I../common 6 | test-audio.elf: test-audio.o stdio.o fb-io.o interrupts.o 7 | $(CC) $^ -Ttext=1000 -o $@ 8 | 9 | stdio.o: ../common/stdio.c 10 | $(CC) $(CFLAGS) -c $< -o $@ 11 | 12 | interrupts.o: ../common/interrupts.S Makefile 13 | $(CC) -c $< -o $@ 14 | 15 | fb-io.o: ../common/fb-io.c Makefile 16 | $(CC) $(CFLAGS) -c $< -o $@ 17 | -------------------------------------------------------------------------------- /workloads/audio/encodeblob.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main(int argc, char **argv) 3 | { 4 | int ch; 5 | int i = 0; 6 | printf("unsigned char blob[] = {\n\t"); 7 | while ((ch = getchar()) >= 0) 8 | printf("0x%02x,%s", (unsigned char) ch, ++i == 16 ? i = 0, "\n\t" : ""); 9 | printf("%s};\n", i != 0 ? "\n" : ""); 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /workloads/audio/newgame.ub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tommythorn/fpgammix/ea2d962b9683a767d62735de62988f19295523da/workloads/audio/newgame.ub -------------------------------------------------------------------------------- /workloads/audio/newgame.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tommythorn/fpgammix/ea2d962b9683a767d62735de62988f19295523da/workloads/audio/newgame.wav -------------------------------------------------------------------------------- /workloads/audio/test-audio.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | 3 | #define RATE 11250 4 | #include "newgame-sound.c" 5 | 6 | unsigned char *next_sample; 7 | unsigned char *stop_sound; 8 | 9 | extern void interruptvector(void); 10 | 11 | long time_at_last_run = 0; 12 | long delta = 0; 13 | 14 | 15 | void 16 | interrupthandler(long unsigned interrupt_source) 17 | { 18 | setInterval(FREQUENCY / 11250 - 100); 19 | 20 | long time = now(); 21 | 22 | if (next_sample != stop_sound) { 23 | DAC_both = *next_sample++ << 6; 24 | } 25 | 26 | delta = time - time_at_last_run; 27 | time_at_last_run = time; 28 | } 29 | 30 | int 31 | main() 32 | { 33 | fb_clear(); 34 | 35 | mmix_fprintf(1, "Hello?", 0); 36 | 37 | next_sample = stop_sound = blob + sizeof blob; 38 | 39 | /* 40 | * XXX 8 and even 7 distorts the sound. Why? AAhh, it's only 41 | * when on head phones. Amplified it sounds great 42 | */ 43 | unsigned scale = 6; 44 | unsigned sw; 45 | 46 | for (;;) { 47 | unsigned char *p; 48 | long unsigned my_sample, time_for_next; 49 | 50 | mmix_printf("Starting sound. Scale is %d\n", scale); 51 | 52 | time_for_next = now() + (FREQUENCY / RATE); 53 | for (p = blob; p != blob + sizeof blob; ++p) { 54 | MMIX_IOSPACE[11] = (long) p >> 8; 55 | my_sample = *p; 56 | my_sample = my_sample << scale; 57 | time_for_next += (FREQUENCY / RATE); 58 | while (now() < time_for_next) 59 | ; 60 | DAC_both = my_sample; 61 | } 62 | 63 | while ((sw = get_switches()) == 0); 64 | if (sw & (SW2|SW3)) 65 | scale += (sw & SW3) ? 1 : -1; 66 | else if (sw & SW1) 67 | stdout = !stdout; 68 | else if (sw & SW0) 69 | break; 70 | } 71 | 72 | mmix_printf("Trying interrupts!\n", 0); 73 | 74 | setInterruptVector(interruptvector); 75 | setIntrMask(1 << 7); // Enable interval 76 | 77 | for (;;) { 78 | mmix_printf("Starting sound\n", 0); 79 | next_sample = blob; 80 | 81 | setInterval(FREQUENCY / RATE); 82 | 83 | while ((get_switches() & SW3) == 0) 84 | mmix_printf("delta %d\n", delta); 85 | while ((get_switches() & SW3) != 0); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /workloads/common/Rules.mk: -------------------------------------------------------------------------------- 1 | FPGAMMIX_DIR=/home/tommy/fpgammix 2 | MMIX_TOOLS_BIN=/opt/mmix/bin 3 | 4 | # XXX -mno-base-addresses should be the default! -mbase-addresses is 5 | # completely unscalable, running out of globals within 30 uses. 6 | 7 | #CFLAGS=-mno-base-addresses -O2 -fomit-frame-pointer 8 | MMIXCC=$(MMIX_TOOLS_BIN)/mmix-gcc 9 | CFLAGS=-O -fomit-frame-pointer -std=gnu99 10 | LDOPTS= 11 | #LDOPTS=-Ttext=80000000 12 | T=1 13 | 14 | # Four ways to run %: 15 | # - via the mmix userlevel simuator: %.mmixsim 16 | # - via the mmmix pipeline simuator: %.mmmixsim 17 | # - via the RTL implementation: %.rtlsim 18 | # - uploaded to tinymon on FPGA: %.txt + manual upload (for now) 19 | # 20 | # In future possible pushed via z-modem or even UDP broadcasts 21 | 22 | %.mmixsim: %.mmo 23 | mmix -l -t$(T) $< 24 | 25 | %.mmmixsim: %.mmb 26 | (echo v1;echo @8000000000005000;echo 999999) | mmmix ../common/plain.mmconfig $< 27 | 28 | %.rtlsim: %.txt $(FPGAMMIX_DIR)/rtl/Icarus/initmem.data 29 | cp $< $(FPGAMMIX_DIR)/rtl/Icarus/input.txt 30 | $(MAKE) -C $(FPGAMMIX_DIR)/rtl/Icarus; 31 | 32 | #### 33 | 34 | %.mmo: %.mms 35 | mmixal -l $@.lst -o $@ $< 36 | 37 | %.mmo: %.elf 38 | $(MMIX_TOOLS_BIN)/mmix-objcopy -I elf64-mmix -O mmo $< $@ 39 | 40 | %.mmb: %.mmo 41 | mmix -D$@ $< 42 | 43 | %.txt: %.elf 44 | $(MMIX_TOOLS_BIN)/mmix-strip $< -o $<.stripped 45 | $(MMIX_TOOLS_BIN)/mmix-objdump -s $<.stripped|cut -d' ' -f-6 > $@ 46 | $(MMIX_TOOLS_BIN)/mmix-nm $< |grep 'T Main'|(read x y;echo " $$x"G) >> $@ 47 | 48 | # The default .elf rule only applies to the most trivial of examples 49 | # XXX To improve in future 50 | %.elf: %.o 51 | $(MMIXCC) $(CFLAGS) -Ttext=800 -melf $< -o $@ 52 | $(MMIX_TOOLS_BIN)/mmix-objdump -d $@ 53 | 54 | %.o: %.c Makefile 55 | $(MMIXCC) $(CFLAGS) -c $< -o $@ 56 | 57 | %.o: %.s Makefile 58 | $(MMIXCC) $(CFLAGS) -c $< -o $@ 59 | 60 | %.o: %.S Makefile 61 | $(MMIXCC) $(CFLAGS) -c $< -o $@ 62 | 63 | %.o: %.mmo 64 | $(MMIX_TOOLS_BIN)/mmix-objcopy -I mmo -O elf64-mmix $< $@ 65 | 66 | %.data: %.elf 67 | $(MMIX_TOOLS_BIN)/mmix-objdump -s $< | grep '^ '|cut -d' ' -f3-6|tr ' ' '\n' | grep -v '^$$' > $@ 68 | 69 | %.dis: %.elf 70 | $(MMIX_TOOLS_BIN)/mmix-objdump -d $< 71 | 72 | clean: 73 | -rm *.elf *.elf.stripped *.o *.txt *.mmo *.mmb *.data *.dis 74 | -------------------------------------------------------------------------------- /workloads/common/fb-io.c: -------------------------------------------------------------------------------- 1 | #include "mmix-iospace.h" 2 | #include "fb-io.h" 3 | #include "font-fixed-6x13.h" 4 | 5 | #define W (640 / 8) 6 | 7 | // As long as we stay in the first segment, we won't have to deal with the crazy segments. 8 | static unsigned char *fb = (unsigned char *) (128 * 1024); 9 | unsigned long fb_io_x = 0; 10 | unsigned long fb_io_y = 0; 11 | static unsigned long cursor_is_on = 0; 12 | 13 | /*static*/ void cursor_flip(void) { 14 | unsigned char *d = fb + (6*fb_io_x) / 8 + 13 * W * fb_io_y; 15 | unsigned sh = (fb_io_x * 6) & 7; 16 | unsigned mask = ~ (((1 << 6) - 1) >> sh); 17 | unsigned k; 18 | 19 | for (k = 0; k < 13; d += W, ++k) *d ^= 0xFC >> sh; 20 | 21 | if (sh > 2) { 22 | d = fb + (6*fb_io_x) / 8 + 13 * W * fb_io_y + 1; 23 | sh = 8 - sh; 24 | mask = ~ (((1 << 6) - 1) << sh); 25 | 26 | for (k = 0; k < 13; d += W, ++k) *d ^= 0xFC << sh; 27 | } 28 | cursor_is_on ^= 1; 29 | } 30 | 31 | void fb_cursor_off(void) { if (cursor_is_on) cursor_flip(); } 32 | void fb_cursor_on(void) { if (!cursor_is_on) cursor_flip(); } 33 | 34 | /* 35 | * Ways to speed this up: 36 | * 37 | * 0. Use tetra access to the frame buffer to reduce how often we need to 38 | * handle to overlapping case. (Octa access are twice as expensive as tetra 39 | * thus unlikely a win). 40 | * 41 | * 1. Move the begining of the framebuffer rather than copying it. If 42 | * used with a mask such that the framebuffer loops around, we'd never have to 43 | * copy, otherwise we'd have to copy whenever we loop around. 44 | * 45 | * 2. Enhance the SRAM controller with smarts [such at some top address 46 | * bits pick mode]. Modes we need here are read-modify-write modes, 47 | * like 48 | * *dest_addr = (*dest_addr & mask_register) | ((wrdata << shift) >> 32) 49 | * 50 | * (It's not hard to imagine a lot of useful *d = COMBINE(*d, *s) operations) 51 | * 52 | * However, shifters in the SRAM controller are expensive and the 53 | * whole approach increasingly looses relevance as the number of 54 | * bits pr pixel goes up. (The core actually could play tricks at 55 | * the byte level by exploring the byte enables, hmm). 56 | */ 57 | 58 | void fb_write(char *buf, int n) 59 | { 60 | long unsigned i; 61 | // Internal versions for speed, can't trust GCC for this 62 | long unsigned x = fb_io_x; 63 | long unsigned y = fb_io_y; 64 | 65 | for (; n; ++buf, --n) { 66 | long unsigned ch = *(unsigned char *)buf; 67 | 68 | if (ch != '\n') { 69 | unsigned char *d = fb + (6*x) / 8 + 13 * W * y; 70 | unsigned char *s = font_fixed_6x13 + 16*ch; 71 | unsigned sh = (x * 6) & 7; 72 | unsigned mask = ~ ((((1 << 6) - 1) << 2) >> sh); 73 | unsigned char *s_stop = s + 13; 74 | 75 | for (; s != s_stop; d += W, ++s) { 76 | *d = (*s >> sh) | (*d & mask); 77 | // *d = *s; 78 | // printf("%x\n", p[i]); 79 | } 80 | if (sh > 2) { 81 | d = fb + (6*x) / 8 + 13 * W * y + 1; 82 | s = font_fixed_6x13 + 16*(unsigned char)ch; 83 | sh = 8 - sh; 84 | mask = ~ ((((1 << 6) - 1) << 2) << sh); 85 | 86 | for (; s != s_stop; d += W, ++s) { 87 | *d = (*s << sh) | (*d & mask); 88 | // *d = *s; 89 | // printf("%x\n", p[i]); 90 | } 91 | } 92 | ++x; 93 | } 94 | 95 | if (x == (640/6) || ch == '\n') { 96 | x = 0; 97 | ++y; 98 | if (y == (480/13)) { 99 | // Scroll up 100 | --y; 101 | for (i = 0; i < (640 / 64) * 13*(480/13 - 1); ++i) 102 | ((long *)fb)[i] = ((long *)fb)[i + 13 * (640 / 64)]; 103 | for (; i < (640 / 64) * 480; ++i) 104 | ((long *)fb)[i] = 0; 105 | } 106 | } 107 | } 108 | 109 | // Copy back 110 | fb_io_x = x; 111 | fb_io_y = y; 112 | } 113 | 114 | void fb_clear(void) { 115 | unsigned long *p = (unsigned long *)fb; 116 | unsigned long *end = p + 4800; 117 | 118 | set_mmix_fbaddr0(fb); 119 | 120 | fb_io_x = fb_io_y = cursor_is_on = 0; 121 | 122 | for (; p != end; p += 10) 123 | p[9] = p[8] = p[7] = p[6] = p[5] = p[4] = p[3] = p[2] = p[1] = p[0] = 0; 124 | } 125 | 126 | void fb_gotoxy(unsigned long _x, unsigned long _y) 127 | { 128 | fb_io_x = _x, fb_io_y = _y; 129 | } 130 | -------------------------------------------------------------------------------- /workloads/common/fb-io.h: -------------------------------------------------------------------------------- 1 | #ifndef _FB_IO_H_ 2 | #define _FB_IO_H_ 1 3 | 4 | extern unsigned long fb_io_x; 5 | extern unsigned long fb_io_y; 6 | 7 | void fb_write(char *buf, int); 8 | void fb_cursor_off(void); 9 | void fb_cursor_on(void); 10 | void fb_clear(void); 11 | void fb_gotoxy(unsigned long x, unsigned long y); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /workloads/common/interrupts.S: -------------------------------------------------------------------------------- 1 | .text 2 | 3 | /* Handler for TRIP #0 */ 4 | pushj 255,triphandler 5 | put rJ,$255 6 | get $255,rB 7 | resume 8 | /* Handler for exception D #10 integer Divide check */ 9 | pushj 255,excdhandler 10 | put rJ,$255 11 | get $255,rB 12 | resume 13 | /* Handler for exception V #20 integer oVerflow */ 14 | pushj 255,excvhandler 15 | put rJ,$255 16 | get $255,rB 17 | resume 18 | /* Handler for exception W #30 float-to-fix overfloW */ 19 | pushj 255,excwhandler 20 | put rJ,$255 21 | get $255,rB 22 | resume 23 | /* Handler for exception I #40 Invalid operation */ 24 | pushj 255,excihandler 25 | put rJ,$255 26 | get $255,rB 27 | resume 28 | /* Handler for exception O #50 floating Overflow */ 29 | pushj 255,excohandler 30 | put rJ,$255 31 | get $255,rB 32 | resume 33 | /* Handler for exception U #60 floating Underflow */ 34 | pushj 255,excuhandler 35 | put rJ,$255 36 | get $255,rB 37 | resume 38 | /* Handler for exception Z #70 floating division by Zero */ 39 | pushj 255,exczhandler 40 | put rJ,$255 41 | get $255,rB 42 | resume 43 | /* Handler for exception X #80 floating ineXact */ 44 | pushj 255,excxhandler 45 | put rJ,$255 46 | get $255,rB 47 | resume 48 | 49 | /* LOC #10000 */ 50 | 51 | .p2align 2 52 | .global interruptvector 53 | 54 | interruptvector: 55 | pushj 255,1F/* To allocate some free variables */ 56 | put rJ,$255 /* Restore rJ */ 57 | nxor $255,$0,$0 /* Set up new interrupt mask (enable all) */ 58 | resume 1 59 | 60 | /* Must preserve $255 */ 61 | 1H get $0,rQ /* Get all pending interrupts */ 62 | subu $1,$0,1 63 | and $2,$0,$1 /* Clears just the highest priority one */ 64 | put rQ,$2 65 | 66 | /* Calculate the index of the highest priority and pass it to the interrupt handler */ 67 | sadd $0,$1,$0 68 | jmp interrupthandler 69 | 70 | triphandler get $250,rA 71 | get $251,rX 72 | get $252,rY 73 | get $253,rZ 74 | addu $250,$251,$252 75 | pop 0,0 76 | excdhandler get $250,rA 77 | pop 0,0 78 | excvhandler get $250,rA 79 | pop 0,0 80 | excwhandler get $250,rA 81 | pop 0,0 82 | excihandler get $250,rA 83 | pop 0,0 84 | excohandler get $250,rA 85 | pop 0,0 86 | excuhandler get $250,rA 87 | pop 0,0 88 | exczhandler get $250,rA 89 | pop 0,0 90 | excxhandler get $250,rA 91 | pop 0,0 92 | 93 | trapvector pushj 255,traphandler 94 | put rJ,$255 95 | get $255,rBB 96 | resume 1 97 | 98 | 99 | #ifndef USER_TRAPHANDLER 100 | traphandler pop 0,0 101 | #endif 102 | -------------------------------------------------------------------------------- /workloads/common/mmix-iospace.h: -------------------------------------------------------------------------------- 1 | #ifndef _MMIX_IOSPACE_H_ 2 | #define _MMIX_IOSPACE_H_ 1 3 | 4 | // XXX Don't belong here I know. 5 | typedef long int64_t; 6 | typedef long unsigned uint64_t; 7 | typedef int int32_t; 8 | typedef int unsigned uint32_t; 9 | typedef short int16_t; 10 | typedef short unsigned uint16_t; 11 | typedef char int8_t; 12 | typedef char unsigned uint8_t; 13 | 14 | #define MMIX_IOSPACE ((volatile int *) 0x1000000000000ULL) 15 | 16 | #define MMIX_IO_PS2_RAW 23 17 | #define MMIX_IO_KEYBOARD 25 18 | #define MMIX_IO_MOUSE 27 19 | 20 | #define MMIX_IO_RS232_OUT 1 21 | #define MMIX_IO_RS232_BUSY_IN 1 22 | 23 | #define MMIX_IO_RS232_RDDATA_IN 3 24 | 25 | #define MMIX_IO_S7_0_OUT 9 26 | #define MMIX_IO_S7_1_OUT 11 27 | 28 | #define set_mmix_fbaddr0(x) MMIX_IOSPACE[21] = (int) (unsigned long) (x) 29 | 30 | 31 | void wait(unsigned long ms); 32 | void wait_us(long unsigned us); 33 | 34 | static inline long unsigned now(void) { 35 | long unsigned rC; 36 | 37 | asm volatile("GET %0,rC" : "=r" (rC)); 38 | 39 | return rC; 40 | } 41 | 42 | 43 | static inline long unsigned getEvents(void) { 44 | long unsigned rC; 45 | 46 | asm volatile("GET %0,rQ" : "=r" (rC)); 47 | 48 | return rC; 49 | } 50 | 51 | static inline long unsigned getIntrMask(void) { 52 | long unsigned rC; 53 | 54 | asm volatile("GET %0,rK" : "=r" (rC)); 55 | 56 | return rC; 57 | } 58 | 59 | 60 | static inline void setIntrMask(long unsigned mask) { 61 | asm volatile("PUT rK,%0" :: "r" (mask));} 62 | 63 | static inline void setInterruptVector(long unsigned addr) { 64 | asm volatile("PUT rTT,%0" :: "r" (addr)); } 65 | 66 | static inline void setInterval(long unsigned v) { 67 | asm volatile("PUT rI,%0" :: "r" (v)); } 68 | 69 | 70 | #define get_switches() MMIX_IOSPACE[5] 71 | #define SW0 1 72 | #define SW1 2 73 | #define SW2 4 74 | #define SW3 8 75 | 76 | 77 | #define DAC_both MMIX_IOSPACE[17] 78 | 79 | #define FREQUENCY 25000000 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /workloads/common/plain.mmconfig: -------------------------------------------------------------------------------- 1 | % example configuration for basic tests 2 | memaddresstime 3 3 | memreadtime 10 memwritetime 10 4 | membusbytes 16 5 | branchpredictbits 2 6 | branchaddressbits 1 7 | branchhistorybits 1 8 | branchdualbits 1 9 | memchunksmax 100 10 | hashprime 127 11 | Scache blocksize 64 12 | Scache setsize 512 13 | Scache associativity 4 pseudolru 14 | Scache accesstime 2 15 | Dcache blocksize 32 16 | Dcache setsize 256 17 | Dcache victimsize 2 18 | Icache blocksize 32 19 | Icache setsize 256 20 | Icache victimsize 2 21 | DTcache associativity 4 lru 22 | unit ALU1 00000000ffffffffffffffffffffffff0000000300000003fffffffffffffffe 23 | unit ALU2 00000000ffffffffffffffffffffffff0000000300000003fffffffffffffffe 24 | unit LSU1 00000000000000000000000000000000fffffffcfffffffc0000000000000000 25 | unit LSU2 00000000000000000000000000000000fffffffcfffffffc0000000000000000 26 | unit MUL1 000080f000000000000000000000000000000000000000000000000000000000 27 | unit DIV1 00000c0f00000000000000000000000000000000000000000000000000000000 28 | unit FPU1 7fff730000000000000000000000000000000000000000000000000000000000 29 | memslots 4 30 | renameregs 10 31 | reorderbuffer 20 32 | Dcache writeallocate 1 33 | Scache writeallocate 1 34 | Dcache writeback 1 35 | Scache writeback 1 36 | Dcache ports 2 37 | DTcache ports 2 38 | writebuffer 4 39 | writeholdingtime 5 40 | mul0 1 41 | mul1 2 42 | mul2 5 43 | -------------------------------------------------------------------------------- /workloads/common/serial-io.c: -------------------------------------------------------------------------------- 1 | #include "mmix-iospace.h" 2 | #include "fb-io.h" 3 | #include "font-fixed-6x13.h" 4 | 5 | #define W (640 / 8) 6 | 7 | // As long as we stay in the first segment, we won't have to deal with the crazy segments. 8 | static unsigned char *fb = (unsigned char *) (128 * 1024); 9 | unsigned long x = 0; 10 | unsigned long y = 0; 11 | static unsigned long cursor_is_on = 0; 12 | 13 | static void cursor_flip(void) { 14 | unsigned char *d = fb + (6*x) / 8 + 13 * W * y; 15 | unsigned sh = (x * 6) & 7; 16 | unsigned mask = ~ (((1 << 6) - 1) >> sh); 17 | unsigned k; 18 | 19 | for (k = 0; k < 13; d += W, ++k) *d ^= 0xFC >> sh; 20 | 21 | if (sh > 2) { 22 | d = fb + (6*x) / 8 + 13 * W * y + 1; 23 | sh = 8 - sh; 24 | mask = ~ (((1 << 6) - 1) << sh); 25 | 26 | for (k = 0; k < 13; d += W, ++k) *d ^= 0xFC << sh; 27 | } 28 | cursor_is_on ^= 1; 29 | } 30 | 31 | void fb_cursor_off(void) { if (cursor_is_on) cursor_flip(); } 32 | void fb_cursor_on(void) { if (!cursor_is_on) cursor_flip(); } 33 | 34 | /* 35 | * Ways to speed this up: 36 | * 37 | * 0. Use tetra access to the frame buffer to reduce how often we need to 38 | * handle to overlapping case. (Octa access are twice as expensive as tetra 39 | * thus unlikely a win). 40 | * 41 | * 1. Move the begining of the framebuffer rather than copying it. If 42 | * used with a mask such that the framebuffer loops around, we'd never have to 43 | * copy, otherwise we'd have to copy whenever we loop around. 44 | * 45 | * 2. Enhance the SRAM controller with smarts [such at some top address 46 | * bits pick mode]. Modes we need here are read-modify-write modes, 47 | * like 48 | * *dest_addr = (*dest_addr & mask_register) | ((wrdata << shift) >> 32) 49 | * 50 | * (It's not hard to imagine a lot of useful *d = COMBINE(*d, *s) operations) 51 | * 52 | * However, shifters in the SRAM controller are expensive and the 53 | * whole approach increasingly looses relevance as the number of 54 | * bits pr pixel goes up. (The core actually could play tricks at 55 | * the byte level by exploring the byte enables, hmm). 56 | */ 57 | 58 | void fb_putchar(char ch) 59 | { 60 | long long unsigned i; 61 | 62 | if (ch != '\n') { 63 | unsigned char *d = fb + (6*x) / 8 + 13 * W * y; 64 | unsigned char *s = font_fixed_6x13 + 16*(unsigned char)ch; 65 | unsigned sh = (x * 6) & 7; 66 | unsigned mask = ~ (((1 << 6) - 1) >> sh); 67 | unsigned char *s_stop = s + 13; 68 | 69 | for (; s != s_stop; d += W, ++s) { 70 | *d = (*s >> sh) | (*d & mask); 71 | // *d = *s; 72 | // printf("%x\n", p[i]); 73 | } 74 | if (sh > 2) { 75 | d = fb + (6*x) / 8 + 13 * W * y + 1; 76 | s = font_fixed_6x13 + 16*(unsigned char)ch; 77 | sh = 8 - sh; 78 | mask = ~ (((1 << 6) - 1) << sh); 79 | 80 | for (; s != s_stop; d += W, ++s) { 81 | *d = (*s << sh) | (*d & mask); 82 | // *d = *s; 83 | // printf("%x\n", p[i]); 84 | } 85 | } 86 | ++x; 87 | } 88 | 89 | if (x == (640/6) || ch == '\n') { 90 | x = 0; 91 | ++y; 92 | if (y == (480/13)) { 93 | --y; 94 | for (i = 0; i < (640 / 64) * 13*(480/13 - 1); ++i) 95 | ((long *)fb)[i] = ((long *)fb)[i + 13 * (640 / 64)]; 96 | for (; i < (640 / 64) * 480; ++i) 97 | ((long *)fb)[i] = 0; 98 | } 99 | } 100 | } 101 | 102 | void fb_puts(char *s) 103 | { 104 | while (*s) 105 | fb_putchar(*s++); 106 | } 107 | 108 | void fb_puthex(int d, unsigned long v) 109 | { 110 | if (d > 1) fb_puthex(d - 1, v >> 4); 111 | fb_putchar("0123456789abcdef"[v & 15]); 112 | } 113 | 114 | static unsigned long 115 | putint_helper(unsigned long d, unsigned long radix) 116 | { 117 | unsigned long k; 118 | unsigned long radix10 = radix * 10; 119 | 120 | if (d >= radix10) 121 | d = putint_helper(d, radix10); 122 | 123 | for (k = 0; k < 10 && d >= radix; ++k) 124 | d -= radix; 125 | fb_putchar('0' + k); 126 | return d; 127 | } 128 | 129 | void fb_putint(long d) 130 | { 131 | if (d < 0) 132 | fb_putchar('-'), d = -d; 133 | putint_helper(d, 1); 134 | } 135 | 136 | 137 | void fb_clear(void) { 138 | unsigned long *p = (unsigned long *)fb; 139 | unsigned long *end = p + 4800; 140 | set_mmix_fbaddr0(fb); 141 | 142 | x = y = cursor_is_on = 0; 143 | 144 | for (; p != end; p += 10) 145 | p[9] = p[8] = p[7] = p[6] = p[5] = p[4] = p[3] = p[2] = p[1] = p[0] = 0; 146 | } 147 | 148 | void fb_gotoxy(unsigned long _x, unsigned long _y) 149 | { 150 | x = _x, y = _y; 151 | } 152 | 153 | void wait(long unsigned ms) { 154 | long unsigned start = now(); 155 | long cycles = 25000 * ms; 156 | 157 | while (now() - start < cycles) 158 | ; 159 | } 160 | 161 | void wait_us(long unsigned us) { 162 | long unsigned start = now(); 163 | long cycles = 25 * us; 164 | 165 | while (now() - start < cycles) 166 | ; 167 | } 168 | -------------------------------------------------------------------------------- /workloads/common/stdio.c: -------------------------------------------------------------------------------- 1 | #include "stdio.h" 2 | #include "fb-io.h" 3 | 4 | int stdout = 0; 5 | 6 | static long 7 | _putint_helper(char **dst, unsigned *size, unsigned long d, unsigned long radix) 8 | { 9 | unsigned long k; 10 | unsigned long radix10 = radix * 10; 11 | 12 | if (d >= radix10) 13 | d = _putint_helper(dst, size, d, radix10); 14 | 15 | for (k = 0; k < 10 && d >= radix; ++k) 16 | d -= radix; 17 | 18 | if (*size < 1) 19 | return -1; 20 | 21 | **dst = '0' + k; 22 | (*dst)++; 23 | (*size)--; 24 | 25 | return d; 26 | } 27 | 28 | int _putint(char **dst, unsigned *size, long d) 29 | { 30 | if (*size <= 1) 31 | return -1; 32 | 33 | if (d < 0) 34 | *(*dst)++ = '-', (*size)--, d = -d; 35 | 36 | return _putint_helper(dst, size, d, 1); 37 | } 38 | 39 | int _puthex(char **dst, unsigned *size, int d, unsigned long v) 40 | { 41 | if (d > 1 || v >> 4) 42 | if (_puthex(dst, size, d - 1, v >> 4) == -1) 43 | return -1; 44 | 45 | *(*dst)++ = "0123456789abcdef"[v & 15]; 46 | (*size)--; 47 | 48 | return 0; 49 | } 50 | 51 | int my_vsnprintf(char *str, unsigned size, char *format, long *args) 52 | { 53 | // XXX varargs anyone? 54 | char *orig_str = str; 55 | char *s; 56 | 57 | --size; // Reserve space for a terminating zero 58 | 59 | for (; *format; ++format) 60 | if (size == 0) 61 | goto finish; 62 | else if (*format != '%') { 63 | *str++ = *format; 64 | --size; 65 | } else { 66 | long unsigned fieldsize = 0; 67 | long unsigned leading_zero = 0; 68 | 69 | ++format; 70 | if (*format == '0') 71 | ++format, leading_zero = 1; 72 | 73 | while ('0' <= *format && *format <= '9') 74 | fieldsize = fieldsize * 10 + *format++ - '0'; 75 | 76 | switch (*format) { 77 | case 'd': 78 | if (args == 0) 79 | goto finish; 80 | _putint(&str, &size, *args); 81 | args = 0; 82 | break; 83 | case 'x': 84 | if (args == 0) 85 | goto finish; 86 | if (fieldsize == 0) 87 | fieldsize = 8; 88 | _puthex(&str, &size, fieldsize, *args); 89 | args = 0; 90 | break; 91 | case 's': 92 | if (args == 0) 93 | goto finish; 94 | for (s = (char *) *args; *s && size; ++s, ++str, --size) 95 | *str = *s; 96 | break; 97 | default: 98 | ; 99 | } 100 | } 101 | finish: 102 | *str = 0; 103 | return str - orig_str; 104 | } 105 | 106 | static void serial_out(int ch) 107 | { 108 | // XXX Replace this with an interrupt driven version 109 | 110 | if (ch == '\n') 111 | serial_out('\r'); 112 | 113 | while (MMIX_IOSPACE[1]) 114 | ; 115 | MMIX_IOSPACE[0] = ch; 116 | } 117 | 118 | void write(int fd, char *buf, int n) 119 | { 120 | if (fd == 0) 121 | for (; n; --n, ++buf) 122 | serial_out(*buf); 123 | else if (fd == 1) 124 | fb_write(buf, n); 125 | } 126 | 127 | int mmix_fprintf(int fd, char *format, long arg1, ...) 128 | { 129 | char buf[9999]; /// XXX use a dynamic buffer 130 | int len = my_vsnprintf(buf, sizeof buf, format, &arg1); // XXX varargs anyone? 131 | write(fd, buf, len); 132 | return len; 133 | } 134 | 135 | int mmix_printf(char *format, long arg1, ...) 136 | { 137 | char buf[9999]; /// XXX use a dynamic buffer 138 | int len = my_vsnprintf(buf, sizeof buf, format, &arg1); // XXX varargs anyone? 139 | write(stdout, buf, len); 140 | return len; 141 | } 142 | 143 | 144 | 145 | void wait_ms(long unsigned ms) { 146 | long unsigned start = now(); 147 | long cycles = 25000 * ms; 148 | 149 | while (now() - start < cycles) 150 | ; 151 | } 152 | 153 | void wait_us(long unsigned us) { 154 | long unsigned start = now(); 155 | long cycles = 25 * us; 156 | 157 | while (now() - start < cycles) 158 | ; 159 | } 160 | -------------------------------------------------------------------------------- /workloads/common/stdio.h: -------------------------------------------------------------------------------- 1 | #ifndef _STDIO_H_ 2 | #define _STDIO_H_ 1 3 | 4 | #include "mmix-iospace.h" 5 | #include "fb-io.h" 6 | 7 | extern int stdout; 8 | 9 | int mmix_fprintf(int fd, char *format, long arg1, ...); 10 | int mmix_printf(char *format, long arg1, ...); 11 | void write(int, char *, int); 12 | static inline void mmix_putchar(char ch) { write(stdout, &ch, 1); } 13 | void wait_ms(unsigned long ms); 14 | void wait_us(long unsigned us); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /workloads/default.mmconfig: -------------------------------------------------------------------------------- 1 | % FIRST CONFIGURATION TEST, goes with test1.mmix 2 | % The following erroneous lines were commented out one by one while testing: 3 | %sh*t % obscene 4 | %memaddresstime 0 % too small 5 | %memaddresstime unit % unreadable 6 | %branchpredictbits 9 % too large 7 | %membusbytes 9 % not a power of two 8 | %ITcache unit % unknown cache parameter 9 | %mul0 0 % too small 10 | %mul0 256 % too big 11 | %unit antidisestablishmentarianism % too long 12 | %unit 0 0123456789abcdef0123456789abcdef0123456789abcdef0123456789ABCDEG % eh? 13 | %unit 1 0123456789abcdef0123456789abcdef0123456789abcdef0123456789ABCDEFG % 65 14 | %unit 2 0000000000000000000000000000000000000000000000000000000000000000 % 0's 15 | %Dcache blocksize 1024 % exceeds Scache 16 | %Dcache granularity 16 % exceeds blocksize 17 | %Scache granularity 16 % differs from Dcache 18 | memaddresstime 4 19 | memreadtime 5 memwritetime 6 % don't ask why 20 | membusbytes 16 21 | branchpredictbits 2 22 | branchaddressbits 1 23 | branchhistorybits 1 24 | branchdualbits 1 25 | %branchdualbits 30 26 | memchunksmax 2 27 | hashprime 3 28 | Scache blocksize 32 29 | Scache setsize 2 30 | Scache associativity 4 lru 31 | Scache accesstime 2 32 | Icache victimsize 2 33 | unit UNI1 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 34 | unit UNI2 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 35 | sh 1 1 1 36 | disablesecurity 1 37 | -------------------------------------------------------------------------------- /workloads/div.c: -------------------------------------------------------------------------------- 1 | int foo; 2 | 3 | main() 4 | { 5 | int i; 6 | 7 | foo = 1729; 8 | 9 | for (i = 1; i < 10; ++i) 10 | foo += foo * foo; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /workloads/dyncodegen.mms: -------------------------------------------------------------------------------- 1 | * This is really just to test that we can execute code from SRAM, but 2 | * it's also self-modifying code (SMC). 3 | 4 | C GREG 5 | SRAM GREG 6 | IOSPACE GREG 7 | tmp GREG 8 | 9 | LOC #100 10 | Main SETH IOSPACE,1 11 | SETH SRAM,0 12 | 13 | * Write SETL C,#1729 (e3fe1729) 14 | 15 | SETL tmp,#1729 16 | INCML tmp,#e3ff 17 | STTU tmp,SRAM,0 18 | 19 | * Write POP 0,0 (f8000000) 20 | 21 | SETML tmp,#f800 22 | STTU tmp,SRAM,4 23 | 24 | PUSHGO $0,SRAM 25 | 26 | SETL tmp,#1729 27 | CMP tmp,tmp,$255 28 | BNZ tmp,1F 29 | 30 | SETL C,'Y'; PUSHJ $0,Putch 31 | SETL C,'E'; PUSHJ $0,Putch 32 | SETL C,'S'; PUSHJ $0,Putch 33 | SETL C,'!'; PUSHJ $0,Putch 34 | SETL C,13; PUSHJ $0,Putch 35 | SETL C,10; PUSHJ $0,Putch 36 | JMP Main 37 | 38 | 1H SETL C,'N'; PUSHJ $0,Putch 39 | SETL C,'O'; PUSHJ $0,Putch 40 | SETL C,'!'; PUSHJ $0,Putch 41 | SETL C,'!'; PUSHJ $0,Putch 42 | SETL C,13; PUSHJ $0,Putch 43 | SETL C,10; PUSHJ $0,Putch 44 | JMP Main 45 | 46 | 47 | Putch LDO tmp,IOSPACE 48 | PBOD tmp,Putch 49 | STBU C,IOSPACE 50 | POP 0,0 51 | -------------------------------------------------------------------------------- /workloads/empty.c: -------------------------------------------------------------------------------- 1 | main() 2 | { 3 | *(int*) 0x1000000000000ULL = 'T'; 4 | *(int*) 0x123456789ABC0ULL = 'S'; 5 | *(int*) 0x123456879ABC0ULL = 'S'; 6 | *(int*) 0x123546789ABC0ULL = 'S'; 7 | *(int*) 0x12345679A8BC0ULL = 'S'; 8 | *(int*) 0x123564789ABC0ULL = 'S'; 9 | *(int*) 0x213456789ABC0ULL = 'S'; 10 | *(int*) 0x213456879ABC0ULL = 'S'; 11 | *(int*) 0x213546789ABC0ULL = 'S'; 12 | *(int*) 0x21345679A8BC0ULL = 'S'; 13 | *(int*) 0x213564789ABC0ULL = 'S'; 14 | *(int*) 0x231456789ABC0ULL = 'S'; 15 | *(int*) 0x231456879ABC0ULL = 'S'; 16 | *(int*) 0x231546789ABC0ULL = 'S'; 17 | *(int*) 0x23145679A8BC0ULL = 'S'; 18 | *(int*) 0x231564789ABC0ULL = 'S'; 19 | *(int*) 0x923456789ABC0ULL = 'S'; 20 | *(int*) 0x923456879ABC0ULL = 'S'; 21 | *(int*) 0x923546789ABC0ULL = 'S'; 22 | *(int*) 0x92345679A8BC0ULL = 'S'; 23 | *(int*) 0x923564789ABC0ULL = 'S'; 24 | } 25 | -------------------------------------------------------------------------------- /workloads/emulation/Makefile: -------------------------------------------------------------------------------- 1 | target: test-emulation.txt 2 | 3 | include ../common/Rules.mk 4 | 5 | %.mmmixsim: %.mmb 6 | (echo v1;echo @8000000000005000;echo 999999) | mmmix nodiv.mmconfig $< 7 | 8 | interrupts.o test-emulation.o: ../common/fb-io.h 9 | 10 | test-emulation.elf: interrupts.o test-emulation.o stdio.o fb-io.o interrupts.o 11 | $(MMIXCC) $^ -Ttext=1000 -o $@ 12 | 13 | stdio.o: ../common/stdio.c 14 | $(MMIXCC) $(CFLAGS) -c $< -o $@ 15 | 16 | interrupts.o: ../common/interrupts.S 17 | $(MMIXCC) -DUSER_TRAPHANDLER $(CFLAGS) -c $< -o $@ 18 | 19 | fb-io.o: ../common/fb-io.c 20 | $(MMIXCC) $(CFLAGS) -c $< -o $@ 21 | 22 | test-divu.elf: test-divu.o 23 | $(MMIX_TOOLS_BIN)/mmix-ld -Ttext=5000 $< -o $@ 24 | 25 | 26 | test-divu2.elf: test-divu2.mmo 27 | $(MMIX_TOOLS_BIN)/mmix-objcopy -I mmo -O elf64-mmix $< $@ 28 | -------------------------------------------------------------------------------- /workloads/emulation/nodiv.mmconfig: -------------------------------------------------------------------------------- 1 | % example configuration for basic tests 2 | memaddresstime 3 3 | memreadtime 10 memwritetime 10 4 | membusbytes 16 5 | branchpredictbits 2 6 | branchaddressbits 1 7 | branchhistorybits 1 8 | branchdualbits 1 9 | memchunksmax 100 10 | hashprime 127 11 | Scache blocksize 64 12 | Scache setsize 512 13 | Scache associativity 4 pseudolru 14 | Scache accesstime 2 15 | Dcache blocksize 32 16 | Dcache setsize 256 17 | Dcache victimsize 2 18 | Icache blocksize 32 19 | Icache setsize 256 20 | Icache victimsize 2 21 | DTcache associativity 4 lru 22 | unit ALU1 00000000ffffffffffffffffffffffff0000000300000003fffffffffffffffe 23 | unit ALU2 00000000ffffffffffffffffffffffff0000000300000003fffffffffffffffe 24 | unit LSU1 00000000000000000000000000000000fffffffcfffffffc0000000000000000 25 | unit LSU2 00000000000000000000000000000000fffffffcfffffffc0000000000000000 26 | unit MUL1 000080f000000000000000000000000000000000000000000000000000000000 27 | unit FPU1 7fff730000000000000000000000000000000000000000000000000000000000 28 | memslots 4 29 | renameregs 10 30 | reorderbuffer 20 31 | Dcache writeallocate 1 32 | Scache writeallocate 1 33 | Dcache writeback 1 34 | Scache writeback 1 35 | Dcache ports 2 36 | DTcache ports 2 37 | writebuffer 4 38 | writeholdingtime 5 39 | mul0 1 40 | mul1 2 41 | mul2 5 42 | disablesecurity 1 43 | -------------------------------------------------------------------------------- /workloads/emulation/test-divu.S: -------------------------------------------------------------------------------- 1 | .text 2 | 3 | /* 4 | A long struggle to get the answer: Yes, my proglet is correct and this 5 | is how it's supposed to behave. 6 | 7 | Committing 8000000000005010: 1efffefd(trap) y=6c1 z=13 b=8000000000005024* x=0!g[255] a=8000000000005024!rBB int=F state=1 8 | setting rWW=8000000000005014, rXX=20000001efffefd 9 | setting rYY=6c1, rZZ=13 10 | 11 | So far so good, entering the trap handler 12 | 13 | Committing 8000000000005024: f2ff0006(st)+ y=6000000000000000 z=300000000 b=1 x=1!m[300000000] state=14 14 | Committing 8000000000005024: f2ff0006(pushj) y=8000000000005028 z=800000000000503c x=ff!l[255] a=8000000000005028!rJ rL=0!rL state=1 15 | Committing 800000000000503c: fe00001d(st)+ y=6000000000000008 z=300000008 b=4000000000000008 x=4000000000000008!m[300000008] state=14 16 | Committing 800000000000503c: fe00001d(incrl)+ x=0!l[0] rL=1!rL state=1 17 | Committing 800000000000503c: fe00001d(get) z=20000001efffefd x=20000001efffefd!l[0] state=1 18 | Committing 8000000000005040: 3f010038(st)+ y=6000000000000010 z=300000010 x=0!m[300000010] state=14 19 | Committing 8000000000005040: 3f010038(incrl)+ x=0!l[1] rL=2!rL state=1 20 | Committing 8000000000005040: 3f010038(sh) y=20000001efffefd z=38 x=2!l[1] state=3 21 | Committing 8000000000005044: 31010102(cmp) y=2 z=2 x=0!l[1] state=3 22 | Committing 8000000000005048: 4a010006(br) y=800000000000504c z=8000000000005060 b=0* x=400000003? state=1 23 | Committing 800000000000504c: 3f000018(sh) y=20000001efffefd z=18 x=20000001e!l[0] state=3 24 | Committing 8000000000005050: c90100fc(and) y=20000001e z=fc x=1c!l[1] state=3 25 | Committing 8000000000005054: 3101011c(cmp) y=1c z=1c x=0!l[1] state=3 26 | Committing 8000000000005058: 42010004(br) y=800000000000505c z=8000000000005068 b=0* x=400000000? ->8000000000005068 state=1 27 | Committing 8000000000005068: fe00001e(get) z=6c1 x=6c1!l[0] state=1 28 | Committing 800000000000506c: fe01001f(get) z=13 x=13!l[1] state=1 29 | 30 | Here's our fake patch-up 31 | 32 | Committing 8000000000005070: 20000001(add) y=6c1 z=13 rA=0 x=6d4!l[0] state=3 33 | 34 | ... which we store in rX 35 | 36 | Committing 8000000000005074: f61f0000(put) z=6d4 x=6d4!rZZ state=1 37 | Committing 8000000000005078: f8000000(ld)+ y=6000000000000010 z=300000010 x=0!l[2] state=13 38 | Committing 8000000000005078: f8000000(ld)+ y=6000000000000008 z=300000008 x=4000000000000008!l[1] state=13 39 | Committing 8000000000005078: f8000000(ld)+ y=6000000000000000 z=300000000 x=1!l[0] state=13 40 | Committing 8000000000005078: f8000000(pop) y=8000000000005028 b=8000000000005028* rL=ff!rL ->8000000000005028 rS=c00000000000000 rO=c00000000000100 state=1 41 | Committing 8000000000005028: f60400ff(put) x=0!rJ state=1 42 | Committing 800000000000502c: e3ff0000(set) x=0!g[255] state=3 43 | 44 | ... and resume 45 | 46 | Committing 8000000000005030: f9020001(resum) 47 | b=2000000e0ff0000 48 | x=8000000000005024!g[255] 49 | a=0!rK ->8000000000005014 state=1 50 | 51 | Notice how the instruction executed at #5010 isn't the DIVU above 52 | (#1efffefd) but the fake ORI inserted by the resume instruction. 53 | 54 | Committing 8000000000005010: e0ff0000(set) y=6c1 z=6d4 rA=0 x=6d4!g[255] state=3 55 | 56 | And we proceed. 57 | 58 | Committing 8000000000005014: e7ff1234(addu) y=6d4 z=1234 x=1908!g[255] state=3 59 | */ 60 | .global Main 61 | Main: geta $255,traphandler 62 | put rT,$255 63 | setl $254,1729 64 | setl $253,19 65 | divu $255,$254,$253 66 | incl $255,#1234 67 | trap 0,0,0 68 | 69 | swym 70 | swym 71 | 72 | traphandler: pushj 255,1F 73 | put rJ,$255 74 | setl $255,0 75 | resume 1 76 | 77 | swym 78 | swym 79 | 80 | 1H get $0,rXX 81 | sru $1,$0,56 82 | cmp $1,$1,#02 83 | bnz $1,2F 84 | 85 | sru $0,$0,24 86 | and $1,$0,#FC 87 | cmp $1,$1,#1C 88 | bz $1,3F 89 | 90 | % Unknown trap 91 | pop 0,0 92 | 93 | % Ordinary trap ("system call") handling 94 | 2H swym 95 | pop 0,0 96 | 97 | 98 | % Div[u][i] emulation 99 | 3H get $0,rJ 100 | get $2,rXX 101 | get $3,rYY 102 | get $4,rZZ 103 | pushj $1,div_emulation 104 | put rZZ,$1 105 | put rJ,$0 106 | pop 0,0 107 | 108 | div_emulation add $0,$1,$2 109 | pop 1,0 110 | -------------------------------------------------------------------------------- /workloads/emulation/test-divu2.mmo.lst: -------------------------------------------------------------------------------- 1 | LOC #600000000 2 | 3 | 0000000600000000: Traphandler PUSHJ 255,1F 4 | ...000: f2ffxxxx 5 | ...004: f60400ff PUT rJ,$255 6 | ...008: e3ff0000 SETL $255,0 7 | ...00c: f9000001 RESUME 1 8 | 9 | ...010: e200e300 Main SETML $0,#e300 10 | ...014: e1010006 SETMH $1,6 11 | ...018: ab000108 STTU $0,$1,8 12 | ...01c: e1ff0006 SETMH $255,6 13 | ...020: f60d00ff PUT rT,$255 14 | ...024: e3fe06c1 SETL $254,1729 15 | ...028: e3fd0013 SETL $253,19 16 | ...02c: 1efffefd DIVU $255,$254,$253 17 | ...030: e7ff1234 INCL $255,#1234 18 | ...034: 00000000 TRAP 0,0,0 19 | 20 | 21 | ...038: fe00001d 1H GET $0,rXX 22 | ...03c: 3f010038 SRU $1,$0,56 23 | ...040: 31010102 CMP $1,$1,#02 24 | ...044: 4a01xxxx BNZ $1,2F 25 | 26 | ...048: 3f000018 SRU $0,$0,24 27 | ...04c: c90100fc AND $1,$0,#FC 28 | ...050: 3101011c CMP $1,$1,#1C 29 | ...054: 4201xxxx BZ $1,3F 30 | 31 | % Unknown trap 32 | ...058: f8000000 POP 0,0 33 | 34 | % Ordinary trap ("system call") handling 35 | ...05c: fd000000 2H SWYM 36 | ...060: f8000000 POP 0,0 37 | 38 | 39 | % Div[u][i] emulation 40 | ...064: fe00001e 3H GET $0,rYY 41 | ...068: fe01001f GET $1,rZZ 42 | ...06c: 20000001 ADD $0,$0,$1 % This should be division emulation but ... 43 | ...070: f61f0000 PUT rZZ,$0 44 | ...074: f8000000 POP 0,0 45 | 46 | Symbol table: 47 | Main = #0000000600000010 (1) 48 | Traphandler = #0000000600000000 (2) 49 | -------------------------------------------------------------------------------- /workloads/emulation/test-divu2.mms: -------------------------------------------------------------------------------- 1 | LOC #600000000 2 | 3 | Traphandler PUSHJ 255,1F 4 | PUT rJ,$255 5 | SETL $255,0 6 | RESUME 1 7 | 8 | Main SETML $0,#e300 9 | SETMH $1,6 10 | STTU $0,$1,8 11 | SETMH $255,6 12 | PUT rT,$255 13 | SETL $254,1729 14 | SETL $253,19 15 | DIVU $255,$254,$253 16 | INCL $255,#1234 17 | TRAP 0,0,0 18 | 19 | 20 | 1H GET $0,rXX 21 | SRU $1,$0,56 22 | CMP $1,$1,#02 23 | BNZ $1,2F 24 | 25 | SRU $0,$0,24 26 | AND $1,$0,#FC 27 | CMP $1,$1,#1C 28 | BZ $1,3F 29 | 30 | % Unknown trap 31 | POP 0,0 32 | 33 | % Ordinary trap ("system call") handling 34 | 2H SWYM 35 | POP 0,0 36 | 37 | 38 | % Div[u][i] emulation 39 | 3H GET $0,rYY 40 | GET $1,rZZ 41 | ADD $0,$0,$1 % This should be division emulation but ... 42 | PUT rZZ,$0 43 | POP 0,0 44 | -------------------------------------------------------------------------------- /workloads/emulation/test-emulation.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | long dummy; 4 | 5 | void foo(long x) 6 | { 7 | dummy += 1729 / x; 8 | } 9 | 10 | void traphandler() 11 | { 12 | // What kind of trap, where, how to patch up? 13 | mmix_printf("Bzz, trapped in ?"); 14 | } 15 | 16 | void interrupthandler(long id) 17 | { 18 | /* do nothing */ 19 | } 20 | 21 | int main() 22 | { 23 | long i; 24 | mmix_printf("Hello, this is test emulation.\n"); 25 | 26 | for (i = 1; i < 10; ++i) 27 | foo(i); 28 | 29 | mmix_printf("And that concludes tonights programming.\n"); 30 | } 31 | -------------------------------------------------------------------------------- /workloads/faster-lg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static int orig_lg(int n) 5 | { 6 | int j, l; 7 | 8 | if (n <= 0) return -1; 9 | 10 | for (j = n, l = 0; j; j >>= 1) l++; 11 | return l - 1; 12 | } 13 | 14 | #define ARGS(a) a 15 | 16 | static int lg ARGS((int n)); 17 | static int lg(n) 18 | int n; 19 | { 20 | int j; 21 | 22 | if (n <= 0) return -1; 23 | 24 | j = 0; 25 | #if 1 26 | if (n & 0xFFFF0000) j = 16, n >>= 16; 27 | if (n & 0x0000FF00) j += 8, n >>= 8; 28 | if (n & 0x000000F0) j += 4, n >>= 4; 29 | if (n & 0x0000000C) j += 2, n >>= 2; 30 | if (n & 0x00000002) j += 1; 31 | #else 32 | if (n >> 16) j = 16, n >>= 16; 33 | if (n >> 8) j += 8, n >>= 8; 34 | if (n >> 4) j += 4, n >>= 4; 35 | if (n >> 2) j += 2, n >>= 2; 36 | if (n >> 1) j += 1; 37 | #endif 38 | 39 | return j; 40 | } 41 | 42 | int 43 | main(int argc, char **argv) 44 | { 45 | int i = 0, k, l, f; 46 | srandom(1729); 47 | 48 | int sum = 0; 49 | 50 | 51 | for (k = 0; k < 300000000; ++k) { 52 | int n = k - 10 /*random() % 60*/; 53 | 54 | #if 0 55 | sum += l = orig_lg(n); 56 | #else 57 | sum += f = lg(n); 58 | #endif 59 | 60 | #if 0 61 | if (l != f) 62 | printf("Opps, bug at lg(%d) = %d, not %d\n", n, l, f); 63 | #endif 64 | } 65 | 66 | printf("sum = %d\n", sum); 67 | } 68 | -------------------------------------------------------------------------------- /workloads/fill.c: -------------------------------------------------------------------------------- 1 | #define set_s7_0(x) IOSPACE[9] = (x) 2 | #define set_s7_1(x) IOSPACE[11] = (x) 3 | #define set_fbaddr0(x) IOSPACE[21] = (x) 4 | 5 | register volatile int *IOSPACE asm("$233"); 6 | 7 | void putch(int ch) 8 | { 9 | while (IOSPACE[1]) 10 | ; 11 | IOSPACE[0] = ch; 12 | } 13 | 14 | void puthex(unsigned v) 15 | { 16 | if (v >= 16) puthex(v >> 4); 17 | putch("0123456789abcdef"[v & 15]); 18 | } 19 | 20 | int 21 | main() 22 | { 23 | IOSPACE = (int*) 0x1000000000000ULL; 24 | unsigned fbaddr0 = 0; 25 | 26 | for (;;) { 27 | puthex(fbaddr0); 28 | putch('\r'); 29 | putch('\n'); 30 | set_fbaddr0(fbaddr0); 31 | set_s7_0(fbaddr0); 32 | set_s7_1(fbaddr0 >> 8); 33 | fbaddr0 += 640 / 8; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /workloads/hilbert.c: -------------------------------------------------------------------------------- 1 | // As long as we stay in the first segment, we won't have to deal with the crazy segments. 2 | unsigned char *fb = (unsigned char *) (128 * 1024); 3 | unsigned long cursor_x = 0; 4 | unsigned long cursor_y = 0; 5 | long int point_x, point_y; 6 | 7 | void clear(void) 8 | { 9 | unsigned i; 10 | for (i = 0; i < 10 * 480; ++i) 11 | ((long *)fb)[i] = 0; 12 | cursor_y = cursor_x = point_x = point_y = 0; 13 | } 14 | 15 | static inline void point(long int x, long int y) 16 | { 17 | unsigned char *p = fb + (x >> 3) + y * (640/8); 18 | *p |= 1 << (~x & 7); 19 | } 20 | 21 | static inline void moveto(long int x, long int y) 22 | { 23 | point_x = x; 24 | point_y = y; 25 | } 26 | 27 | void drawto(long int x, long int y) 28 | { 29 | long int i, from, to; 30 | if (x == point_x) { 31 | if (point_y > y) 32 | from = y, to = point_y; 33 | else 34 | from = point_y, to = y; 35 | 36 | for (i = from; i <= to; ++i) 37 | point(x, i); 38 | point_y = y; 39 | } else if (y == point_y) { 40 | if (point_x > x) 41 | from = x, to = point_x; 42 | else 43 | from = point_x, to = x; 44 | 45 | for (i = from; i <= to; ++i) 46 | point(i, y); 47 | point_x = x; 48 | } 49 | } 50 | 51 | void a(long int), b(long int), c(long int), d(long int); 52 | 53 | long int h0 = 8; 54 | long int h, x, y, x0, y0; 55 | 56 | void a(long int i) 57 | { 58 | if (i > 0) { 59 | d(i-1); x -= h; drawto(x,y); 60 | a(i-1); y -= h; drawto(x,y); 61 | a(i-1); x += h; drawto(x,y); 62 | b(i-1); 63 | } 64 | } 65 | 66 | void b(long int i) 67 | { 68 | if (i > 0) { 69 | c(i-1); y += h; drawto(x,y); 70 | b(i-1); x += h; drawto(x,y); 71 | b(i-1); y -= h; drawto(x,y); 72 | a(i-1); 73 | } 74 | } 75 | 76 | void c(long int i) 77 | { 78 | if (i > 0) { 79 | b(i-1); x += h; drawto(x,y); 80 | c(i-1); y += h; drawto(x,y); 81 | c(i-1); x -= h; drawto(x,y); 82 | d(i-1); 83 | } 84 | } 85 | 86 | void d(long int i) 87 | { 88 | if (i > 0) { 89 | a(i-1); y -= h; drawto(x,y); 90 | d(i-1); x -= h; drawto(x,y); 91 | d(i-1); y += h; drawto(x,y); 92 | c(i-1); 93 | } 94 | } 95 | 96 | #define IOSPACE ((volatile int *) 0x1000000000000ULL) 97 | #define set_fbaddr0(x) IOSPACE[21] = (x) 98 | 99 | int dummy; 100 | 101 | main() 102 | { 103 | int d, i; 104 | 105 | set_fbaddr0(fb); 106 | 107 | for (;;) 108 | for (d = 0; d <= 6; ++d) { 109 | clear(); 110 | 111 | h0 = 8; 112 | h = h0; x0 = h/2; y0 = x0; h = h/ 2; 113 | x0 += h/2; y0 += h/2; 114 | 115 | x = x0 + 400; y = y0 + 350; moveto(x,y); 116 | a(d); 117 | 118 | for (i = 0; i < 1000000; ++i) 119 | ++dummy; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /workloads/hw.c: -------------------------------------------------------------------------------- 1 | #define IOSPACE ((volatile int *) 0x1000000000000ULL) 2 | 3 | void putchar(char ch) 4 | { 5 | if (ch == '\n') 6 | putchar('\r'); 7 | 8 | while (IOSPACE[1]) 9 | ; 10 | IOSPACE[0] = ch; 11 | } 12 | 13 | void puts(char *s) 14 | { 15 | while (*s) 16 | putchar(*s++); 17 | } 18 | 19 | int main() 20 | { 21 | puts("Hello world!\n"); 22 | } 23 | -------------------------------------------------------------------------------- /workloads/keyboard/Makefile: -------------------------------------------------------------------------------- 1 | target: draw.txt 2 | 3 | include ../Makefile 4 | 5 | CFLAGS=-Wall -O -fomit-frame-pointer -I../common 6 | 7 | interrupts.o test-keyboard.o: ../common/fb-io.h 8 | 9 | test-keyboard.elf: interrupts.o test-keyboard.o stdio.o fb-io.o interrupts.o 10 | $(CC) $^ -Ttext=1000 -o $@ 11 | 12 | draw.elf: interrupts.o draw.o stdio.o fb-io.o interrupts.o 13 | $(CC) $^ -Ttext=1000 -o $@ 14 | 15 | stdio.o: ../common/stdio.c 16 | $(CC) $(CFLAGS) -c $< -o $@ 17 | 18 | interrupts.o: ../common/interrupts.S 19 | $(CC) $(CFLAGS) -c $< -o $@ 20 | 21 | fb-io.o: ../common/fb-io.c 22 | $(CC) $(CFLAGS) -c $< -o $@ 23 | -------------------------------------------------------------------------------- /workloads/ledfun.mms: -------------------------------------------------------------------------------- 1 | n GREG 2 | x GREG 3 | 4 | LOC #100 5 | Main SETL x,0 6 | 2H PUT 255,x 7 | INCL x,1 8 | JMP Pause 9 | 10 | Pause SETML n,1 11 | 1H SUB n,n,1 12 | BNZ n,1B 13 | JMP 2B -------------------------------------------------------------------------------- /workloads/loader.mms: -------------------------------------------------------------------------------- 1 | * Boot loader 2 | * XXXXXXXX: set the address 3 | * XXXXXXXX store datum at address & advance address 4 | * XXXXXXXXG Start executing 5 | 6 | * Basically 7 | * 8 | * readvalue -> (value, {,G,:} ) 9 | * 10 | * main 11 | * ptr = 0 12 | * loop 13 | * (value, cmd) <- readvalue 14 | * if cmd == ':' then 15 | * ptr = value 16 | * else if cmd == 'G' then 17 | * call value 18 | * else 19 | * *ptr++ = value 20 | * repeat loop 21 | 22 | IOSPACE GREG 23 | C GREG 24 | tmp GREG 25 | 26 | LOC #100 27 | Main SETH IOSPACE,1 28 | 29 | 1H PUSHJ $0,Getch 30 | SETL $2,'<'; PUSHJ $1,Putch 31 | ADD $2,$0,0; PUSHJ $1,Putch 32 | SETL $2,'>'; PUSHJ $1,Putch 33 | JMP 1B 34 | 35 | Putch LDTU tmp,IOSPACE,4 36 | PBOD tmp,Putch 37 | STBU $0,IOSPACE,7 38 | POP 1,0 39 | 40 | Getch LDTU $0,IOSPACE,12 41 | PBN $0,Getch 42 | POP 1,0 43 | 44 | Readvalue 45 | SETL -------------------------------------------------------------------------------- /workloads/myfib-interrupted.mms: -------------------------------------------------------------------------------- 1 | * Fibonacci subroutines (exercise 1.4.1--13) 2 | 3 | LOC #1000 4 | Main PUT rI,5 5 | PUSHJ $0,Fib 6 | TRAP 0,0,0 7 | 8 | Fib CMP $1,$0,2 9 | PBN $1,1F 10 | GET $1,rJ 11 | SUB $3,$0,1 12 | PUSHJ $2,Fib $2=F_{n-1} 13 | SUB $4,$0,2 14 | PUSHJ $3,Fib $3=F_{n-2} 15 | ADDU $0,$2,$3 16 | PUT rJ,$1 17 | 1H POP 1,0 18 | 19 | LOC #8000000000000000 20 | SET $1,7 21 | -------------------------------------------------------------------------------- /workloads/myfib-verbose.mms: -------------------------------------------------------------------------------- 1 | * Fibonacci subroutines (exercise 1.4.1--13) 2 | 3 | IOSPACE GREG 4 | C GREG 5 | tmp GREG 6 | 7 | LOC #100 8 | Main SETH IOSPACE,1 9 | SETL C,'B'; PUSHJ $0,Putch 10 | SETL C,'E'; PUSHJ $0,Putch 11 | SETL C,'G'; PUSHJ $0,Putch 12 | SETL C,'I'; PUSHJ $0,Putch 13 | SETL C,'N'; PUSHJ $0,Putch 14 | SETL C,13; PUSHJ $0,Putch 15 | SETL C,10; PUSHJ $0,Putch 16 | SET $1,7 17 | 18 | PUSHJ $0,Fib 19 | ADDU C,$0,'A'; PUSHJ $0,Putch 20 | TRAP 0,0 21 | 22 | Fib CMP $1,$0,2 23 | PBN $1,1F 24 | GET $1,rJ 25 | ADDU C,$0,'0'; PUSHJ $2,Putch 26 | SUB $3,$0,1 27 | PUSHJ $2,Fib $2=F_{n-1} 28 | SUB $4,$0,2 29 | PUSHJ $3,Fib $3=F_{n-2} 30 | ADDU $0,$2,$3 31 | PUT rJ,$1 32 | 1H POP 1,0 33 | 34 | Putch LDO tmp,IOSPACE 35 | PBOD tmp,Putch 36 | STBU C,IOSPACE 37 | POP 0,0 38 | -------------------------------------------------------------------------------- /workloads/myfib.mms: -------------------------------------------------------------------------------- 1 | * Fibonacci subroutines (exercise 1.4.1--13) 2 | 3 | LOC #100 4 | Main SET $1,7 5 | PUSHJ $0,Fib 6 | TRAP 0,0,0 7 | 8 | Fib CMP $1,$0,2 9 | PBN $1,1F 10 | GET $1,rJ 11 | SUB $3,$0,1 12 | PUSHJ $2,Fib $2=F_{n-1} 13 | SUB $4,$0,2 14 | PUSHJ $3,Fib $3=F_{n-2} 15 | ADDU $0,$2,$3 16 | PUT rJ,$1 17 | 1H POP 1,0 18 | 19 | -------------------------------------------------------------------------------- /workloads/noio.c: -------------------------------------------------------------------------------- 1 | int main() { ++*((unsigned *) 0x123400); } 2 | -------------------------------------------------------------------------------- /workloads/overflow.s: -------------------------------------------------------------------------------- 1 | # 1 "div.c" 2 | ! mmixal:= 8H LOC Data_Section 3 | .text ! mmixal:= 9H LOC 8B 4 | .p2align 2 5 | LOC @+(4-@)&3 6 | .global main 7 | main IS @ 8 | SETL $0,#6c1 9 | STT $0,foo 10 | SETL $3,#1 11 | SET $1,$0 12 | L:2 IS @ 13 | SL $0,$1,2 14 | ADD $2,$0,$1 15 | SET $1,$2 16 | ADD $0,$3,1 17 | SET $3,$0 18 | SL $0,$0,32 19 | SR $0,$0,32 20 | CMP $0,$0,10 21 | PBNZ $0,L:2 22 | STT $2,foo 23 | POP 1,0 24 | 25 | .comm foo,4,4 ! mmixal-incompatible COMMON 26 | .data ! mmixal:= 8H LOC 9B 27 | -------------------------------------------------------------------------------- /workloads/overflow2.mms: -------------------------------------------------------------------------------- 1 | foo GREG 2 | 3 | LOC #0 4 | ; Handler for TRIP #0 5 | PUSHJ 255,TripHandler 6 | PUT rJ,$255 7 | GET $255,rB 8 | RESUME 9 | ; Handler for exception D #10 integer Divide check 10 | PUSHJ 255,ExcDHandler 11 | PUT rJ,$255 12 | GET $255,rB 13 | RESUME 14 | ; Handler for exception V #20 integer oVerflow 15 | PUSHJ 255,ExcVHandler 16 | PUT rJ,$255 17 | GET $255,rB 18 | RESUME 19 | ; Handler for exception W #30 float-to-fix overfloW 20 | PUSHJ 255,ExcWHandler 21 | PUT rJ,$255 22 | GET $255,rB 23 | RESUME 24 | ; Handler for exception I #40 Invalid operation 25 | PUSHJ 255,ExcIHandler 26 | PUT rJ,$255 27 | GET $255,rB 28 | RESUME 29 | ; Handler for exception O #50 floating Overflow 30 | PUSHJ 255,ExcOHandler 31 | PUT rJ,$255 32 | GET $255,rB 33 | RESUME 34 | ; Handler for exception U #60 floating Underflow 35 | PUSHJ 255,ExcUHandler 36 | PUT rJ,$255 37 | GET $255,rB 38 | RESUME 39 | ; Handler for exception Z #70 floating division by Zero 40 | PUSHJ 255,ExcZHandler 41 | PUT rJ,$255 42 | GET $255,rB 43 | RESUME 44 | ; Handler for exception X #80 floating ineXact 45 | PUSHJ 255,ExcXHandler 46 | PUT rJ,$255 47 | GET $255,rB 48 | RESUME 49 | 50 | Start PUSHJ 255,Main 51 | TRIP 2,3 52 | TRAP 0,1 53 | 54 | TripHandler GET foo,rA 55 | POP 0,0 56 | ExcDHandler GET foo,rA 57 | POP 0,0 58 | ExcVHandler GET foo,rA 59 | POP 0,0 60 | ExcWHandler GET foo,rA 61 | POP 0,0 62 | ExcIHandler GET foo,rA 63 | POP 0,0 64 | ExcOHandler GET foo,rA 65 | POP 0,0 66 | ExcUHandler GET foo,rA 67 | POP 0,0 68 | ExcZHandler GET foo,rA 69 | POP 0,0 70 | ExcXHandler GET foo,rA 71 | POP 0,0 72 | 73 | 74 | LOC #10000 75 | Main SETL $0,#0000 % #3FFFF is the most ones I can use in a PUT rA instruction 76 | INCML $0,#0 77 | PUT rA,$0 78 | TRAP 79 | SETL foo,#16c1 80 | INCML foo,#7777 81 | INCMH foo,#7777 82 | INCH foo,#7777 83 | SETL $3,#1 84 | 85 | L:2 MUL $0,foo,2 86 | ADD $3,$3,1 87 | ADD foo,$0,foo 88 | CMP $0,$3,30 89 | PBNZ $0,L:2 90 | POP 1,0 91 | 92 | ; Overflow handler 93 | GET $8,rY 94 | GET $9,rX 95 | GET $10,rZ 96 | GET $11,rW 97 | ; Change the result 98 | ADDU $8,$8,$0 99 | ADDU $8,$8,$10 100 | ADDU $8,$8,$11 101 | PUT rZ,$8 102 | ANDNH $9,#FF00 103 | ORH $9,#0200 104 | SETH $9,1 105 | 106 | 1H SETL $11,'+' 107 | LDTU $10,$9,4 108 | PBOD $10,1B 109 | STBU $11,$9,7 110 | 111 | RESUME 112 | 113 | -------------------------------------------------------------------------------- /workloads/overflow3.S: -------------------------------------------------------------------------------- 1 | #define IOSPACE $250 2 | 3 | .text 4 | #if 1 5 | /* Handler for TRIP #0 */ 6 | PUSHJ 255,TripHandler 7 | PUT rJ,$255 8 | GET $255,rB 9 | RESUME 10 | /* Handler for exception D #10 integer Divide check */ 11 | PUSHJ 255,ExcDHandler 12 | PUT rJ,$255 13 | GET $255,rB 14 | RESUME 15 | /* Handler for exception V #20 integer oVerflow */ 16 | PUSHJ 255,ExcVHandler 17 | PUT rJ,$255 18 | GET $255,rB 19 | RESUME 20 | /* Handler for exception W #30 float-to-fix overfloW */ 21 | PUSHJ 255,ExcWHandler 22 | PUT rJ,$255 23 | GET $255,rB 24 | RESUME 25 | /* Handler for exception I #40 Invalid operation */ 26 | PUSHJ 255,ExcIHandler 27 | PUT rJ,$255 28 | GET $255,rB 29 | RESUME 30 | /* Handler for exception O #50 floating Overflow */ 31 | PUSHJ 255,ExcOHandler 32 | PUT rJ,$255 33 | GET $255,rB 34 | RESUME 35 | /* Handler for exception U #60 floating Underflow */ 36 | PUSHJ 255,ExcUHandler 37 | PUT rJ,$255 38 | GET $255,rB 39 | RESUME 40 | /* Handler for exception Z #70 floating division by Zero */ 41 | PUSHJ 255,ExcZHandler 42 | PUT rJ,$255 43 | GET $255,rB 44 | RESUME 45 | /* Handler for exception X #80 floating ineXact */ 46 | PUSHJ 255,ExcXHandler 47 | PUT rJ,$255 48 | GET $255,rB 49 | RESUME 50 | 51 | 52 | /* LOC #10000 */ 53 | 54 | Main SETH IOSPACE,1 /* IOSPACE pointer */ 55 | SETL $0,TrapVector 56 | PUT rT,$0 57 | /*SETL $0,1234 58 | PUT rTT,$0 59 | SETL $1,'A' 60 | PUSHJ $0,Putch*/ 61 | 62 | TRAP 3,5,'B' 63 | 64 | POP 0,0 65 | 66 | SETL $2,#23 67 | SETL $7,#7777 68 | SETL $11,#1111 69 | SETL $13,#1313 70 | TRIP 7,11,13 71 | PUSHJ 255,Start 72 | TRIP 2,3 73 | 74 | TripHandler GET $250,rA 75 | GET $251,rX 76 | GET $252,rY 77 | GET $253,rZ 78 | ADDU $250,$251,$252 79 | POP 0,0 80 | ExcDHandler GET $250,rA 81 | POP 0,0 82 | ExcVHandler GET $250,rA 83 | POP 0,0 84 | ExcWHandler GET $250,rA 85 | POP 0,0 86 | ExcIHandler GET $250,rA 87 | POP 0,0 88 | ExcOHandler GET $250,rA 89 | POP 0,0 90 | ExcUHandler GET $250,rA 91 | POP 0,0 92 | ExcZHandler GET $250,rA 93 | POP 0,0 94 | ExcXHandler GET $250,rA 95 | POP 0,0 96 | 97 | 98 | Start SETL $0,#FF00 % #3FFFF is the most ones I can use in a PUT rA instruction 99 | INCML $0,#0 100 | PUT rA,$0 101 | SETL $250,#16c1 102 | INCML $250,#7777 103 | INCMH $250,#7777 104 | INCH $250,#7777 105 | SETL $3,#1 106 | 107 | L:2 MUL $0,$250,2 108 | ADD $3,$3,1 109 | ADD $250,$0,$250 110 | CMP $0,$3,3 111 | PBNZ $0,L:2 112 | POP 1,0 113 | 114 | TrapVector PUSHJ 255,TrapHandler 115 | PUT rJ,$255 116 | GET $255,rBB 117 | RESUME 1 118 | 119 | 120 | TrapHandler GET $1,rBB 121 | GET $1,rXX 122 | GET $1,rYY 123 | GET $1,rZZ 124 | GET $0,rJ 125 | SETL $2,'T' 126 | PUSHJ $1,Putch 127 | PUT rJ,$0 128 | POP 0,0 129 | 130 | Putch LDT $1,IOSPACE,0 131 | PBOD $1,Putch 132 | STBU $0,IOSPACE 133 | POP 0,0 134 | #else 135 | 136 | Blah JMP Blah 137 | 138 | Main SETL $0,TrapVector 139 | PUT rT,$0 140 | TRAP 3,5,'B' 141 | POP 0,0 142 | SWYM 143 | 144 | TrapVector PUSHJ 255,TrapHandler 145 | PUT rJ,$255 146 | GET $255,rBB 147 | RESUME 1 148 | 149 | TrapHandler POP 0,0 150 | #endif 151 | -------------------------------------------------------------------------------- /workloads/overflow3.mmconfig: -------------------------------------------------------------------------------- 1 | % configuration for test2.mmix 2 | memaddresstime 3 3 | memreadtime 5 memwritetime 4 % don't ask why 4 | membusbytes 16 5 | writeholdingtime 5 6 | branchpredictbits 2 7 | branchaddressbits 1 8 | branchhistorybits 1 9 | branchdualbits 1 10 | memchunksmax 16 11 | hashprime 17 12 | Scache blocksize 64 13 | Scache setsize 2 14 | Scache associativity 4 pseudolru 15 | Scache accesstime 2 16 | Dcache blocksize 32 17 | Dcache setsize 8 18 | Icache setsize 2 19 | Icache victimsize 2 20 | DTcache associativity 4 pseudolru 21 | ITcache associativity 2 22 | unit UNI1 fffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 23 | unit UNI2 FFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 24 | dispatchmax 3 25 | commitmax 3 26 | fetchmax 4 27 | memslots 4 28 | Dcache writeallocate 1 29 | Scache writeallocate 1 30 | Dcache writeback 1 31 | Scache writeback 1 32 | %Dcache ports 2 33 | Icache blocksize 32 34 | %hardwarepagetable 0 % for this version, start at 8000000000000070 35 | %writebuffer 7 36 | -------------------------------------------------------------------------------- /workloads/p43errata.mms: -------------------------------------------------------------------------------- 1 | LOC #250 2 | 3 | Main SETL $10,6 4 | 5 | SET $0,$10 6 | SUBU $1,$0,1 7 | XOR $2,$0,$1 8 | ANDN $1,$0,$1 9 | SADD $2,$2,0 10 | 11 | New SET $0,$10 12 | SUBU $1,$0,1 13 | SADD $2,$1,$0 14 | ANDN $1,$0,$1 15 | 16 | -------------------------------------------------------------------------------- /workloads/readmoto.c: -------------------------------------------------------------------------------- 1 | /* 2 | I figured it would be easier to write the assembly if I had a 3 | working model in C first ... 4 | 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | // S11329300FFFFFFFFFFF0F0F0F0F0F0FFFFFFFFF33 11 | 12 | unsigned sum; 13 | 14 | void fatal(void) 15 | { 16 | printf("FAILURE\n"); 17 | exit(1); 18 | } 19 | 20 | unsigned getdigit() 21 | { 22 | unsigned c = getchar(); 23 | 24 | if ('0' <= c && c <= '9') 25 | return c - '0'; 26 | else if ('a' <= c && c <= 'f') 27 | return c - 'a' + 10; 28 | else if ('A' <= c && c <= 'F') 29 | return c - 'A' + 10; 30 | else 31 | fatal(); 32 | } 33 | 34 | unsigned get2digits() 35 | { 36 | unsigned n = getdigit(); 37 | n = n*16 + getdigit(); 38 | sum = 255 & (sum + n); 39 | return n; 40 | } 41 | 42 | unsigned get4digits() 43 | { 44 | unsigned n = get2digits(); 45 | return n*256 + get2digits(); 46 | } 47 | 48 | 49 | int 50 | main() 51 | { 52 | char buf[999]; 53 | 54 | for (;;) { 55 | unsigned type, count, address, i, data, xsum; 56 | while (getchar() != 'S'); 57 | type = getdigit(); 58 | if (type != 1 && type != 9) 59 | continue; 60 | sum = 0; 61 | count = get2digits(); 62 | address = get4digits(); 63 | printf("type %d count %d starting %x\n", type, count, address); 64 | for (i = 2; i < count - 1; ++i, ++address) { 65 | data = get2digits(); 66 | printf("%04x:%02x\n", address, data); 67 | } 68 | xsum = get2digits(); 69 | if (sum != 255) 70 | printf("Mismatch %02x =? %02x\n", sum, xsum); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /workloads/readmoto.mms: -------------------------------------------------------------------------------- 1 | ! Boot loader, reading srec 2 | 3 | !#define IOSPACE $253 4 | !#define SUM $252 5 | !#define ERROR $251 6 | 7 | IOSPACE GREG 8 | SUM GREG 9 | ERROR GREG 10 | InputText GREG 11 | 12 | .text 13 | .p2align 2 14 | .global main 15 | 16 | LOC #80000000 17 | Main IS @ 18 | SETH IOSPACE,1 19 | GETA InputText,SampleInput 20 | 21 | Loop IS @ 22 | SETL ERROR,0 23 | GETA $1,WelcomeText 24 | PUSHJ $0,Puts 25 | PUSHJ $0,Getch 26 | CMP $0,$0,'S' 27 | BNZ $0,Loop 28 | 29 | PUSHJ $0,Getdigit 30 | ! $0 is type 31 | CMP $1,$0,1 32 | BZ $1,Loop1 33 | CMP $1,$0,9 34 | BNZ $1,Loop 35 | 36 | Loop1 IS @ 37 | SETL SUM,0 38 | PUSHJ $1,Get2digits 39 | ! $1 is count 40 | PUSHJ $2,Get4digits 41 | ! $2 is address 42 | 43 | ! Adjust for the already read 2 address bytes and the final checksum 44 | SUBU $1,$1,3 45 | ! Skip if no data is expected 46 | BZ $1,Loop9 47 | 48 | ! data loop 49 | Loop2 IS @ 50 | PUSHJ $3,Get2digits 51 | BNZ ERROR,HandleError 52 | 53 | STBU $3,$2,0 54 | ADDU $2,$2,1 55 | 56 | SUBU $1,$1,1 57 | BNZ $1,Loop2 58 | 59 | ! Check the checksum 60 | Loop9 IS @ 61 | PUSHJ $3,Get2digits 62 | AND $3,$3,255 63 | CMP $3,$3,255 64 | BNZ $3,HandleChecksumError 65 | 66 | CMP $1,$0,1 67 | BZ $1,Loop11 68 | 69 | PUSHGO $0,$2 70 | 71 | Loop11 IS @ 72 | SETL $1,'.' 73 | PUSHJ $0,Putch 74 | JMP Loop 75 | 76 | HandleChecksumError IS @ 77 | GETA $1,ChecksumErrorText 78 | PUSHJ $0,Puts 79 | JMP Loop 80 | 81 | HandleError IS @ 82 | GETA $1,ErrorText 83 | PUSHJ $0,Puts 84 | JMP Loop 85 | 86 | LOC (@+3)&-4 87 | ChecksumErrorText IS @ 88 | BYTE "Checksum Error, skipping",#0D,#0A,#0 89 | 90 | LOC (@+3)&-4 91 | ErrorText IS @ 92 | BYTE "Error, skipping",#0D,#0A,#0 93 | 94 | LOC (@+3)&-4 95 | WelcomeText IS @ 96 | BYTE "$ ",#0 97 | 98 | LOC (@+3)&-4 99 | SampleInput IS @ 100 | BYTE "askldS10D299020000000000000A843002E",#0D,#0A 101 | BYTE "S90301807B",#0D,#0A 102 | 103 | LOC (@+3)&-4 104 | Putch IS @ 105 | LDTU $1,IOSPACE,4 106 | PBOD $1,Putch 107 | STBU $0,IOSPACE,7 108 | POP 0,0 109 | 110 | 111 | ! $0 address, $1 ret addr, $3 out param 112 | Puts IS @ 113 | GET $1,rJ 114 | LDBU $3,$0,0 115 | BZ $3,Puts1 116 | Puts2 IS @ 117 | PUSHJ $2,Putch 118 | ADD $0,$0,1 119 | LDBU $3,$0,0 120 | BNZ $3,Puts2 121 | Puts1 IS @ 122 | PUT rJ,$1 123 | POP 0,0 124 | 125 | 126 | Getch IS @ 127 | LDT $0,IOSPACE,12 128 | PBN $0,Getch 129 | POP 1,0 130 | 131 | ! Getch IS @ ! fake 132 | ! LDBU $0,InputText,0 133 | ! ADDU InputText,InputText,1 134 | ! POP 1,0 135 | 136 | Getdigit IS @ 137 | BNZ ERROR,Fail 138 | GET $0,rJ 139 | PUSHJ $1,Getch 140 | CMP $2,$1,'0' 141 | BN $2,Fail 142 | CMP $2,$1,'9'+1 143 | BNN $2,Getdigit1 144 | PUT rJ,$0 145 | SUB $0,$1,'0' 146 | POP 1,0 147 | Getdigit1 IS @ 148 | CMP $2,$1,'A' 149 | BN $2,Fail 150 | CMP $2,$1,'F'+1 151 | BNN $2,Fail 152 | PUT rJ,$0 153 | SUBU $0,$1,'A'-10 154 | POP 1,0 155 | Fail IS @ 156 | SETL ERROR,1 157 | PUT rJ,$0 158 | POP 0,0 159 | 160 | Get2digits IS @ 161 | GET $0,rJ 162 | PUSHJ $1,Getdigit 163 | PUSHJ $2,Getdigit 164 | PUT rJ,$0 165 | 16ADDU $0,$1,$2 166 | ADDU SUM,SUM,$0 167 | POP 1,0 168 | 169 | Get4digits IS @ 170 | GET $0,rJ 171 | PUSHJ $1,Get2digits 172 | SLU $1,$1,8 173 | PUSHJ $2,Get2digits 174 | PUT rJ,$0 175 | ADDU $0,$1,$2 176 | POP 1,0 177 | 178 | -------------------------------------------------------------------------------- /workloads/terminal.mms: -------------------------------------------------------------------------------- 1 | % Grab bytes from rs232 input, echo them and store them in the frame buffer 2 | 3 | iospace GREG 4 | p GREG 5 | c GREG 6 | t GREG 7 | 8 | LOC #100 9 | Main SETH iospace,#1 10 | SETMH p,#1 11 | 12 | 1H LDBU t,iospace,7 13 | PBOD t,1B 14 | SETL t,'O' 15 | STBU t,iospace,7 16 | 17 | 1H LDBU t,iospace,7 18 | PBOD t,1B 19 | SETL t,'k' 20 | STBU t,iospace,7 21 | 22 | 1H LDBU t,iospace,7 23 | PBOD t,1B 24 | SETL t,'$' 25 | STBU t,iospace,7 26 | 27 | GetCh LDT c,iospace,12 28 | PBN c,GetCh 29 | 30 | STBU c,p,0 31 | INCL p,#1 32 | 33 | 34 | 1H LDBU t,iospace,7 35 | PBOD t,1B 36 | SETL t,'<' 37 | STBU t,iospace,7 38 | 39 | 1H LDBU t,iospace,7 40 | PBOD t,1B 41 | STBU c,iospace,7 42 | 43 | 1H LDBU t,iospace,7 44 | PBOD t,1B 45 | SETL t,'>' 46 | STBU t,iospace,7 47 | 48 | JMP GetCh 49 | -------------------------------------------------------------------------------- /workloads/test-interval/Makefile: -------------------------------------------------------------------------------- 1 | target: test-interval.txt 2 | 3 | include ../Makefile 4 | 5 | test-interval.o: test-interval.S Makefile 6 | $(CC) $(CFLAGS) -mno-base-addresses -c $< -o $@ 7 | 8 | test-interval.elf: test-interval.o 9 | /opt/mmix/bin/mmix-ld -Ttext=0x5000 -melf64mmix $< -o $@ 10 | /opt/mmix/bin/mmix-objdump -d $@ 11 | 12 | -------------------------------------------------------------------------------- /workloads/test-interval/data-annotated.s: -------------------------------------------------------------------------------- 1 | .file "data.c" 2 | 3 | # long unsigned uninitialized; 4 | .comm uninitialized,8,8 5 | 6 | 7 | # long unsigned initialized = 27; 8 | .globl initialized 9 | .data 10 | .align 8 11 | .type initialized, @object 12 | .size initialized, 8 13 | initialized: 14 | .quad 27 15 | 16 | 17 | # static long unsigned uninitialized_static; 18 | .local uninitialized_static 19 | .comm uninitialized_static,8,8 20 | 21 | 22 | # static long unsigned initialized_static = 27; 23 | .align 8 24 | .type initialized_static, @object 25 | .size initialized_static, 8 26 | initialized_static: 27 | .quad 27 28 | 29 | 30 | .ident "GCC: (GNU) 4.0.2 20050901 (prerelease) (SUSE Linux)" 31 | .section .note.GNU-stack,"",@progbits 32 | -------------------------------------------------------------------------------- /workloads/test-interval/data.c: -------------------------------------------------------------------------------- 1 | long unsigned uninitialized; 2 | long unsigned initialized = 27; 3 | static long unsigned uninitialized_static; 4 | static long unsigned initialized_static = 27; 5 | 6 | extern long bar(long); 7 | 8 | long foo(long x) 9 | { 10 | return 2*bar(x+1); 11 | } 12 | -------------------------------------------------------------------------------- /workloads/test-interval/data.s: -------------------------------------------------------------------------------- 1 | # 1 "data.c" 2 | ! mmixal:= 8H LOC Data_Section 3 | .text ! mmixal:= 9H LOC 8B 4 | .p2align 2 5 | LOC @+(4-@)&3 6 | .global foo 7 | 8 | foo: get $1,rJ 9 | 10 | addu $3,$0,1 11 | pushj $2,bar 12 | 13 | put rJ,$1 14 | addu $0,$2,$2 15 | pop 1,0 16 | 17 | .global initialized 18 | .data ! mmixal:= 8H LOC 9B 19 | .p2align 3 20 | LOC @+(8-@)&7 21 | initialized IS @ 22 | OCTA 27 23 | .comm uninitialized,8,8 ! mmixal-incompatible COMMON 24 | -------------------------------------------------------------------------------- /workloads/test-interval/test-interval.S: -------------------------------------------------------------------------------- 1 | #define IOSPACE $250 2 | .text 3 | 4 | /* LOC #10000 */ 5 | 6 | Main: seth IOSPACE,1 /* IOSPACE pointer */ 7 | setl $0,interruptvector 8 | put rTT,$0 9 | setl $0,#FFFF 10 | put rK,$0 11 | get $0,rK 12 | 13 | setl $0,100 14 | put rI,$0 15 | 16 | loop: addu $255,$255,1 17 | jmp loop 18 | 19 | #if 0 20 | interruptvector: 21 | setl $255,0 22 | put rQ,$255 23 | setl $255,100 24 | put rI,$255 25 | nxor $255,$255,$255 26 | resume 1 27 | #else 28 | 29 | interruptvector: 30 | pushj 255,interrupthandler/* To allocate some free variables */ 31 | put rJ,$255 /* Restore rJ */ 32 | nxor $255,$0,$0 /* Set up new interrupt mask (enable all) */ 33 | resume 1 34 | 35 | /* Must preserve $255 */ 36 | interrupthandler: 37 | get $0,rQ /* All pending interrupts */ 38 | subu $1,$0,1 /* This and the following ... */ 39 | sadd $2,$1,$0 /* ... calculates the index of the highest priority */ 40 | and $0,$0,$1 /* Clears just the highest priority one */ 41 | put rQ,$0 42 | 43 | setl $0,100 44 | put rI,$0 45 | 46 | addu $2,$2,'A' 47 | stbu $2,IOSPACE /* Do something with the index */ 48 | pop 0,0 49 | #endif -------------------------------------------------------------------------------- /workloads/test-stdio/Makefile: -------------------------------------------------------------------------------- 1 | target: test-stdio.txt 2 | 3 | include ../Makefile 4 | 5 | CFLAGS=-Wall -O -fomit-frame-pointer 6 | test-stdio.elf: test-stdio.o stdio.o fb-io.o 7 | $(CC) $^ -Ttext=1000 -o $@ 8 | 9 | test-stdio.o: test-stdio.c Makefile 10 | $(CC) $(CFLAGS) -c $< -o $@ 11 | 12 | interrupts.o: ../common/interrupts.S Makefile 13 | $(CC) -c $< -o $@ 14 | 15 | fb-io.o: ../common/fb-io.c Makefile 16 | $(CC) $(CFLAGS) -c $< -o $@ 17 | 18 | stdio.o: ../common/stdio.c Makefile 19 | $(CC) $(CFLAGS) -c $< -o $@ 20 | -------------------------------------------------------------------------------- /workloads/test-stdio/test-stdio.c: -------------------------------------------------------------------------------- 1 | #include "../common/stdio.h" 2 | 3 | int main() 4 | { 5 | int fd = 0; 6 | 7 | for (fd = 0; fd <= 1; ++fd) { 8 | fprintf(fd, "Hello %s\n", "world!"); 9 | fprintf(fd, "Hex: 0x%3x\n", 0x1234); 10 | fprintf(fd, "Int: %d\n", 1234); 11 | fprintf(fd, "Int: %d\n", -1234); 12 | fprintf(fd, "Int: %d\n", 0); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /workloads/testldX.mms: -------------------------------------------------------------------------------- 1 | % Rudimentary test of LDXX instructions 2 | LOC Data_Segment 3 | Tmp OCTA 0 4 | 5 | a GREG 6 | n GREG 7 | x GREG 8 | 9 | LOC #100 10 | Main SETH n,#FEDC 11 | INCMH n,#BA98 12 | INCML n,#7654 13 | INCL n,#3210 14 | 15 | SETH a,Tmp>>48 16 | STO n,a,0 17 | LDB x,a,0 18 | LDB x,a,2 19 | LDB x,a,5 20 | LDBU x,a,0 21 | LDBU x,a,2 22 | LDBU x,a,5 23 | LDW x,a,0 24 | LDW x,a,2 25 | LDW x,a,5 26 | LDWU x,a,0 27 | LDWU x,a,2 28 | LDWU x,a,5 29 | LDT x,a,0 30 | LDT x,a,2 31 | LDT x,a,5 32 | LDTU x,a,0 33 | LDTU x,a,2 34 | LDTU x,a,5 35 | LDHT x,a,0 36 | LDHT x,a,2 37 | LDHT x,a,9 38 | TRAP 0,Halt,0 39 | -------------------------------------------------------------------------------- /workloads/testldst.mms: -------------------------------------------------------------------------------- 1 | * Testing STO and LDO 2 | 3 | Main LOC #?? 4 | SETH $253,Data_Segment>>48 5 | SETL $1, 1 6 | SETL $2, 2 7 | SETL $3, 3 8 | STO $1, $253, 0 9 | STO $2, $253, 8 10 | STO $3, $253, 16 11 | 12 | LDO $3, $253, 0 13 | LDO $1, $253, 8 14 | LDO $2, $253, 16 15 | 16 | -------------------------------------------------------------------------------- /workloads/testmem.c: -------------------------------------------------------------------------------- 1 | register volatile int * IOSPACE asm("$233"); 2 | 3 | void putch(long int ch) 4 | { 5 | if (ch == '\n') 6 | putch('\r'); 7 | while (IOSPACE[1]) 8 | ; 9 | IOSPACE[0] = ch; 10 | } 11 | 12 | void puthex(long unsigned d, long unsigned v) 13 | { 14 | if (!d) 15 | return; 16 | puthex(d - 1, v >> 4); 17 | putch("0123456789abcdef"[v & 15]); 18 | } 19 | 20 | void my_puts(char *s) 21 | { 22 | while (*s) 23 | putch(*s++); 24 | } 25 | 26 | register unsigned long g242 asm("$242"); 27 | register unsigned long g246 asm("$246"); 28 | register unsigned long g254 asm("$254"); 29 | 30 | void write(unsigned long seg, unsigned long offset, unsigned v) 31 | { 32 | seg <<= 60; 33 | seg += offset; 34 | *(unsigned *)seg = v; 35 | } 36 | 37 | void check(unsigned long seg, unsigned long offset, unsigned v) 38 | { 39 | seg <<= 60; 40 | seg += offset; 41 | if (*(unsigned *)seg != v) { 42 | my_puts("#"); 43 | puthex(16,seg); 44 | my_puts(": "); 45 | puthex(8,*(unsigned *)seg); 46 | my_puts(" Bad! Expected "); 47 | puthex(8, v); 48 | putch('\n'); 49 | } 50 | } 51 | 52 | int 53 | main() 54 | { 55 | // $254 = #60..00 56 | /* 57 | g241: 0000000000001a98 _global_impure_ptr = #1a98 (12) 58 | g242: 2000000000000000 !! 59 | g243: 2000000000001088 _impure_ptr 60 | g244: 20000000000017a8 __malloc_av_ 61 | g245: 2000000000001fb8 __malloc_trim_threshold 62 | g246: 4000000000000000 _Sbrk_high !! 63 | g247: 0 64 | g248: 0 65 | g249: 0 66 | g250: 0 67 | g251: 0 68 | g252: 0 69 | g253: 0 70 | g254: 6000000000000000 !! 71 | g255: 0000000000000180 Main 72 | */ 73 | int i; 74 | IOSPACE = (int*) 0x1000000000000ULL; 75 | unsigned long x; 76 | unsigned long y; 77 | unsigned char *fb; 78 | unsigned long k = 128; 79 | k <<= 10; 80 | 81 | g242 = 0x2000000000000000ULL; 82 | g246 = 0x4000000000000000ULL; 83 | g254 = 0x6000000000000000ULL; 84 | 85 | //fb = (unsigned char *) (256 * 1024); 86 | 87 | putch('\n'); 88 | my_puts("Hello?\n"); 89 | my_puts("MMIX is **ALIVE**!!\n"); 90 | 91 | write(2, 900, 1729); 92 | write(4, 900, 1789); 93 | write(6, 900, 666); 94 | 95 | check(2, 900, 1729); 96 | check(4, 900, 1789); 97 | check(6, 900, 666); 98 | 99 | 100 | for (x = 9000; x < 256 * 1024; x += 8) 101 | write(1, x, 999 + (x << 2) + x); 102 | 103 | for (x = 9000; x < 256 * 1024; x += 8) 104 | check(1, x, 999 + (x << 2) + x); 105 | 106 | my_puts("Ok\n"); 107 | } 108 | -------------------------------------------------------------------------------- /workloads/testmul.c: -------------------------------------------------------------------------------- 1 | int f(int a, int b) 2 | { 3 | ((int *) 0x1000000000000)[11] = a; 4 | return a * b; 5 | } 6 | 7 | int main() 8 | { 9 | return f(1729172917291729, 17291729172917291729); 10 | } 11 | -------------------------------------------------------------------------------- /workloads/tinymon/Makefile: -------------------------------------------------------------------------------- 1 | target: install 2 | 3 | include ../Makefile 4 | 5 | install: ../../rtl/initmem.mif ../../rtl/Icarus/initmem.data 6 | 7 | tinymon.elf: start.o tinymon.o 8 | /opt/mmix/bin/mmix-ld -Ttext=80000000 -m elf64mmix $^ -o $@ 9 | 10 | tinymon.o: tinymon.c Makefile 11 | $(CC) $(CFLAGS) -mno-base-addresses -c $< -o $@ 12 | 13 | ../../rtl/initmem.mif: tinymon.mif 14 | cp $< $@ 15 | 16 | ../../rtl/Icarus/initmem.data: tinymon.data 17 | cp $< $@ 18 | 19 | -------------------------------------------------------------------------------- /workloads/tinymon/start.c: -------------------------------------------------------------------------------- 1 | extern int main(int, char **); 2 | 3 | int _start(void) 4 | { 5 | main(0,0); 6 | } 7 | -------------------------------------------------------------------------------- /workloads/tinymon/tinymon.data: -------------------------------------------------------------------------------- 1 | fe000004 2 | e3020000 3 | c1030200 4 | f201000a 5 | f6040000 6 | f8010000 7 | c1030000 8 | c102f500 9 | 2301f504 10 | 89000100 11 | 5b00ffff 12 | ab030200 13 | f8000000 14 | f504fff9 15 | e0f50001 16 | e307004f 17 | bf060400 18 | e307006b 19 | bf060400 20 | e307000d 21 | bf060400 22 | e307000a 23 | bf060400 24 | 2301f50c 25 | 89000100 26 | 3b000020 27 | 3d000020 28 | c1f60000 29 | 5100fffc 30 | 3100f620 31 | 5a000094 32 | e3020000 33 | f505ffe6 34 | 2308f50c 35 | 89000800 36 | 3b060020 37 | 3d060620 38 | c1f60600 39 | 4106fffb 40 | 27010630 41 | 33000109 42 | 4c00000c 43 | 27000661 44 | 33000005 45 | 44000003 46 | 27010657 47 | f0000007 48 | 27000641 49 | 33000005 50 | 4c000003 51 | 37010001 52 | f0000007 53 | 27010637 54 | 89000800 55 | 3b000020 56 | 3d000020 57 | c1f60000 58 | 5100fffc 59 | 2706f630 60 | 33000609 61 | 4c00000a 62 | 2700f661 63 | 33000005 64 | 44000003 65 | 2706f657 66 | f0000005 67 | 2700f641 68 | 33000005 69 | 4400000b 70 | 2706f637 71 | 89000800 72 | 3b000020 73 | 3d000020 74 | c1f60000 75 | 5100fffc 76 | 40060004 77 | 3b000104 78 | 22010006 79 | f1ffffec 80 | 4a020053 81 | 3100f647 82 | 42000003 83 | c1030100 84 | f0000053 85 | e3070047 86 | bf060500 87 | e307006f 88 | bf060500 89 | e307000d 90 | bf060500 91 | e307000a 92 | bf060500 93 | e3000708 94 | 8de10000 95 | e3000710 96 | 8de20000 97 | e3000718 98 | 8de30000 99 | e3000720 100 | 8de40000 101 | e3000728 102 | 8de50000 103 | e3000730 104 | 8de60000 105 | e3000738 106 | 8de70000 107 | e3000740 108 | 8de80000 109 | e3000748 110 | 8de90000 111 | e3000750 112 | 8dea0000 113 | e3000758 114 | 8deb0000 115 | e3000760 116 | 8dec0000 117 | e3000768 118 | 8ded0000 119 | e3000770 120 | 8dee0000 121 | e3000778 122 | 8def0000 123 | e3000780 124 | 8df00000 125 | e3000788 126 | 8df10000 127 | e3000790 128 | 8df20000 129 | e3000798 130 | 8df30000 131 | e30007a0 132 | 8df40000 133 | e30007a8 134 | 8df50000 135 | e30007b0 136 | 8df60000 137 | e30007b8 138 | 8df70000 139 | e30007c0 140 | 8df80000 141 | e30007c8 142 | 8df90000 143 | e30007d0 144 | 8dfa0000 145 | e30007d8 146 | 8dfb0000 147 | e30007e0 148 | 8dfc0000 149 | e30007e8 150 | 8dfd0000 151 | e30007f0 152 | 8dfe0000 153 | e30007f8 154 | 8dff0000 155 | bf060100 156 | e0f50001 157 | e307000d 158 | bf060500 159 | e307000a 160 | bf060500 161 | c1030100 162 | f1ffff6d 163 | ab010300 164 | 23030304 165 | e3070021 166 | f306ff61 167 | 3100f620 168 | 4a00000b 169 | 23020201 170 | 31000204 171 | 5d00ff77 172 | f0000007 173 | 89000600 174 | 3b000020 175 | 3d000020 176 | c1f60000 177 | 5100fffc 178 | f0000002 179 | 2306f50c 180 | 3100f60a 181 | 5b00fff8 182 | 89000600 183 | 3b000020 184 | 3d000020 185 | c1f60000 186 | 5100fffc 187 | f1ffff63 188 | -------------------------------------------------------------------------------- /workloads/tinymon/tinymon.test: -------------------------------------------------------------------------------- 1 | 0000000000001230 11000011 2 | 2000000000001230 11222211 3 | 4000000000001230 11444411 4 | 6000000000001230 11666611 5 | 6 | 7 | hwfb.elf: file format elf64-mmix 8 | 9 | Contents of section .init: 10 | 0100 fe000004 f2010003 e3ff00ff 00000000 ................ 11 | 0110 e3011934 e6010000 e5010000 e4010000 ...4............ 12 | 0120 e3ff03a8 e6ff0000 e5ff0000 e4ff0000 ................ 13 | 0130 bf00ff00 e3ff0244 e6ff0000 e5ff0000 .......D........ 14 | 0140 e4ff0000 bf01ff00 f6040000 e3ff18f8 ................ 15 | 0150 e6ff0000 e5ff0000 e4ff0000 bf01ff00 ................ 16 | 0160 f6040000 f4ff0003 f60400ff f8000000 ................ 17 | 0170 f6040000 f8000000 ........ 18 | Contents of section .text: 19 | 0178 60000000 00000000 e3ff0020 f61300ff `.......... .... 20 | 0188 f5fffffc 8ffeff00 83ff0100 83ff0101 ................ 21 | ... 22 | 2000000000001000 00000000 00000000 00000000 00000000 ................ 23 | 2000000000001010 00000000 00000000 00000000 00000000 ................ 24 | 0100G 25 | -------------------------------------------------------------------------------- /workloads/triptester.mms: -------------------------------------------------------------------------------- 1 | foo GREG 2 | 3 | ; Overflow handler 4 | LOC #0 5 | GET $8,rY 6 | GET $9,rX 7 | GET $10,rZ 8 | GET $11,rW 9 | ; Change the result 10 | ADDU $8,$8,$0 11 | ADDU $8,$8,$10 12 | ADDU $8,$8,$11 13 | PUT rZ,$8 14 | ANDNH $9,#FF00 15 | ORH $9,#0200 16 | SETH $9,1 17 | 18 | 1H SETL $11,'+' 19 | LDTU $10,$9,4 20 | PBOD $10,1B 21 | STBU $11,$9,7 22 | 23 | RESUME 24 | 25 | LOC #250 26 | Main SETL $0,#FF00 27 | PUT rA,$0 28 | TRIP 29 | SETL foo,#16c1 30 | INCML foo,#7777 31 | INCMH foo,#7777 32 | INCH foo,#7777 33 | SETL $3,#1 34 | 35 | L:2 MUL $0,foo,2 36 | ADD $3,$3,1 37 | ADD foo,$0,foo 38 | CMP $0,$3,30 39 | PBNZ $0,L:2 40 | POP 1,0 41 | -------------------------------------------------------------------------------- /workloads/xmodem.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tommythorn/fpgammix/ea2d962b9683a767d62735de62988f19295523da/workloads/xmodem.zip -------------------------------------------------------------------------------- /workloads/xmodem/Makefile: -------------------------------------------------------------------------------- 1 | OBJS=main.o xmodem.o crc16.o 2 | #-Wl,--section-start,MMIX.reg_contents=0 3 | #CFLAGS=-mno-base-addresses -O2 -fomit-frame-pointer -Wall 4 | CFLAGS=-O2 -fomit-frame-pointer -Wall 5 | LDFLAGS=-melf -Ttext=800 #-Ttext=80000000 6 | CC=/opt/mmix/bin/mmix-gcc 7 | 8 | goal: xmodem.txt xmodem.dis 9 | 10 | include ../Makefile 11 | 12 | xmodem.elf: $(OBJS) 13 | /opt/mmix/bin/mmix-ld -Ttext=800 -melf64mmix $^ -o $@ 14 | 15 | main.o: Makefile xmodem.h 16 | xmodem.o: Makefile xmodem.h crc16.h host.h 17 | crc16.o: Makefile crc16.h 18 | 19 | %.dis: %.elf 20 | /opt/mmix/bin/mmix-objdump -d $< 21 | /opt/mmix/bin/mmix-objdump -s $< 22 | 23 | 24 | 25 | 26 | # /opt/mmix/bin/mmix-objcopy -O mmo $< /tmp/xx 27 | # mmotype /tmp/xx 28 | -------------------------------------------------------------------------------- /workloads/xmodem/crc16.c: -------------------------------------------------------------------------------- 1 | #include "crc16.h" 2 | 3 | /* CRC16 implementation acording to CCITT standards */ 4 | 5 | static const unsigned short crc16tab[256]= { 6 | 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 7 | 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, 8 | 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, 9 | 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, 10 | 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, 11 | 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, 12 | 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, 13 | 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, 14 | 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, 15 | 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, 16 | 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, 17 | 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, 18 | 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, 19 | 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, 20 | 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, 21 | 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, 22 | 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, 23 | 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, 24 | 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, 25 | 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, 26 | 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, 27 | 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, 28 | 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, 29 | 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, 30 | 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, 31 | 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, 32 | 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, 33 | 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, 34 | 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, 35 | 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, 36 | 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, 37 | 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 38 | }; 39 | 40 | unsigned short crc16_ccitt(const void *buf, int len) 41 | { 42 | register int counter; 43 | register unsigned short crc = 0; 44 | for( counter = 0; counter < len; counter++) 45 | crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *(char *)buf++)&0x00FF]; 46 | return crc; 47 | } 48 | -------------------------------------------------------------------------------- /workloads/xmodem/crc16.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRC16_H_ 2 | #define _CRC16_H_ 3 | 4 | unsigned short crc16_ccitt(const void *buf, int len); 5 | 6 | #endif /* _CRC16_H_ */ 7 | -------------------------------------------------------------------------------- /workloads/xmodem/host.h: -------------------------------------------------------------------------------- 1 | #define IOSPACE ((volatile int *) 0x1000000000000ULL) 2 | #define set_s7_0(x) IOSPACE[9] = (x) 3 | #define set_s7_1(x) IOSPACE[11] = (x) 4 | 5 | int timeout_count, read_count; 6 | 7 | static int _inbyte(unsigned short timeout) // msec timeout 8 | { 9 | long int ms; 10 | 11 | for (; timeout; --timeout) { 12 | // 25Mhz, ~ 25 CPI => 1000 inst/ms 13 | for (ms = 1000; ms; --ms) { 14 | int c = IOSPACE[3]; 15 | if (c >= 0) { 16 | set_s7_0(++read_count); 17 | return c; 18 | } 19 | } 20 | } 21 | set_s7_1(++timeout_count); 22 | return -1; 23 | } 24 | 25 | static void _outbyte(int c) 26 | { 27 | while (IOSPACE[1]) 28 | ; 29 | IOSPACE[0] = c; 30 | } 31 | 32 | static void host_memcpy(void *dest, const void *src, int n) 33 | { 34 | // XXX Very slow implementation 35 | unsigned char *d = (unsigned char *) dest; 36 | unsigned char *s = (unsigned char *) src; 37 | 38 | while (n--) 39 | *d++ = *s++; 40 | } 41 | 42 | static void host_memset(void *dest, int c, int n) 43 | { 44 | // XXX Very slow implementation 45 | unsigned char *d = (unsigned char *) dest; 46 | 47 | while (n--) 48 | *d++ = c; 49 | } 50 | 51 | #define memset host_memset 52 | #define memcpy host_memcpy 53 | -------------------------------------------------------------------------------- /workloads/xmodem/main.c: -------------------------------------------------------------------------------- 1 | #include "host.h" 2 | #include "xmodem.h" 3 | 4 | unsigned char buf[9999]; 5 | 6 | static outs(char *s) 7 | { 8 | while (*s) _outbyte(*s++); 9 | } 10 | 11 | int main() 12 | { 13 | for (;;) { 14 | outs("Start!\r\n"); 15 | set_s7_0(0x5); 16 | set_s7_1(0x5); 17 | 18 | int res = xmodemReceive(buf, sizeof buf); 19 | 20 | if (res < 0) 21 | outs("Failed!\r\n"); 22 | else 23 | outs("Success!\r\n"); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /workloads/xmodem/xmodem.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2001, 2002 Georges Menie (www.menie.org) 3 | 4 | This program is free software; you can redistribute it and/or modify 5 | it under the terms of the GNU Lesser General Public License as published by 6 | the Free Software Foundation; either version 2 of the License, or 7 | (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public License 15 | along with this program; if not, write to the Free Software 16 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 | */ 18 | 19 | /* this code needs standard functions memcpy() and memset() 20 | and input/output functions _inbyte() and _outbyte(). 21 | 22 | the prototypes of the input/output functions are: 23 | int _inbyte(unsigned short timeout); // msec timeout 24 | void _outbyte(int c); 25 | 26 | */ 27 | 28 | #include "xmodem.h" 29 | #include "crc16.h" 30 | #include "host.h" 31 | 32 | #define SOH 0x01 33 | #define STX 0x02 34 | #define EOT 0x04 35 | #define ACK 0x06 36 | #define NAK 0x15 37 | #define CAN 0x18 38 | #define CTRLZ 0x1A 39 | 40 | #define DLY_1S 1000 41 | #define MAXRETRANS 25 42 | 43 | static int check(int crc, const unsigned char *buf, int sz) 44 | { 45 | if (crc) { 46 | unsigned short crc = crc16_ccitt(buf, sz); 47 | unsigned short tcrc = (buf[sz]<<8)+buf[sz+1]; 48 | if (crc == tcrc) 49 | return 1; 50 | } else { 51 | int i; 52 | unsigned char cks = 0; 53 | for (i = 0; i < sz; ++i) { 54 | cks += buf[i]; 55 | } 56 | if (cks == buf[sz]) 57 | return 1; 58 | } 59 | 60 | return 0; 61 | } 62 | 63 | static void flushinput(void) 64 | { 65 | while (_inbyte(((DLY_1S)*3)>>1) >= 0) 66 | ; 67 | } 68 | 69 | int xmodemReceive(unsigned char *dest, int destsz) 70 | { 71 | unsigned char xbuff[1030]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */ 72 | unsigned char *p; 73 | int bufsz, crc = 0; 74 | unsigned char trychar = 'C'; 75 | unsigned char packetno = 1; 76 | int i, c, len = 0; 77 | int retry, retrans = MAXRETRANS; 78 | 79 | for (;;) { 80 | for ( retry = 0; retry < 16; ++retry) { 81 | if (trychar) _outbyte(trychar); 82 | if ((c = _inbyte((DLY_1S)<<1)) >= 0) { 83 | switch (c) { 84 | case SOH: 85 | bufsz = 128; 86 | goto start_recv; 87 | case STX: 88 | bufsz = 1024; 89 | goto start_recv; 90 | case EOT: 91 | flushinput(); 92 | _outbyte(ACK); 93 | return len; /* normal end */ 94 | case CAN: 95 | if ((c = _inbyte(DLY_1S)) == CAN) { 96 | flushinput(); 97 | _outbyte(ACK); 98 | return -1; /* canceled by remote */ 99 | } 100 | break; 101 | default: 102 | break; 103 | } 104 | } 105 | } 106 | if (trychar == 'C') { trychar = NAK; continue; } 107 | flushinput(); 108 | _outbyte(CAN); 109 | _outbyte(CAN); 110 | _outbyte(CAN); 111 | return -2; /* sync error */ 112 | 113 | start_recv: 114 | if (trychar == 'C') crc = 1; 115 | trychar = 0; 116 | p = xbuff; 117 | *p++ = c; 118 | for (i = 0; i < (bufsz+(crc?1:0)+3); ++i) { 119 | if ((c = _inbyte(DLY_1S)) < 0) goto reject; 120 | *p++ = c; 121 | } 122 | 123 | if (xbuff[1] == (unsigned char)(~xbuff[2]) && 124 | (xbuff[1] == packetno || xbuff[1] == (unsigned char)packetno-1) && 125 | check(crc, &xbuff[3], bufsz)) { 126 | if (xbuff[1] == packetno) { 127 | register int count = destsz - len; 128 | if (count > bufsz) count = bufsz; 129 | if (count > 0) { 130 | memcpy(&dest[len], &xbuff[3], count); 131 | len += count; 132 | } 133 | ++packetno; 134 | retrans = MAXRETRANS+1; 135 | } 136 | if (--retrans <= 0) { 137 | flushinput(); 138 | _outbyte(CAN); 139 | _outbyte(CAN); 140 | _outbyte(CAN); 141 | return -3; /* too many retry error */ 142 | } 143 | _outbyte(ACK); 144 | continue; 145 | } 146 | reject: 147 | flushinput(); 148 | _outbyte(NAK); 149 | } 150 | } 151 | 152 | #if 0 153 | int xmodemTransmit(unsigned char *src, int srcsz) 154 | { 155 | unsigned char xbuff[1030]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */ 156 | int bufsz, crc = -1; 157 | unsigned char packetno = 1; 158 | int i, c, len = 0; 159 | int retry; 160 | 161 | for (;;) { 162 | for ( retry = 0; retry < 16; ++retry) { 163 | if ((c = _inbyte((DLY_1S)<<1)) >= 0) { 164 | switch (c) { 165 | case 'C': 166 | crc = 1; 167 | goto start_trans; 168 | case NAK: 169 | crc = 0; 170 | goto start_trans; 171 | case CAN: 172 | if ((c = _inbyte(DLY_1S)) == CAN) { 173 | _outbyte(ACK); 174 | flushinput(); 175 | return -1; /* canceled by remote */ 176 | } 177 | break; 178 | default: 179 | break; 180 | } 181 | } 182 | } 183 | _outbyte(CAN); 184 | _outbyte(CAN); 185 | _outbyte(CAN); 186 | flushinput(); 187 | return -2; /* no sync */ 188 | 189 | for (;;) { 190 | start_trans: 191 | xbuff[0] = SOH; bufsz = 128; 192 | xbuff[1] = packetno; 193 | xbuff[2] = ~packetno; 194 | c = srcsz - len; 195 | if (c > bufsz) c = bufsz; 196 | if (c >= 0) { 197 | memset(&xbuff[3], 0, bufsz); 198 | if (c == 0) { 199 | xbuff[3] = CTRLZ; 200 | } else { 201 | memcpy(&xbuff[3], &src[len], c); 202 | if (c < bufsz) xbuff[3+c] = CTRLZ; 203 | } 204 | if (crc) { 205 | unsigned short ccrc = crc16_ccitt(&xbuff[3], bufsz); 206 | xbuff[bufsz+3] = (ccrc>>8) & 0xFF; 207 | xbuff[bufsz+4] = ccrc & 0xFF; 208 | } else { 209 | unsigned char ccks = 0; 210 | for (i = 3; i < bufsz+3; ++i) { 211 | ccks += xbuff[i]; 212 | } 213 | xbuff[bufsz+3] = ccks; 214 | } 215 | for (retry = 0; retry < MAXRETRANS; ++retry) { 216 | for (i = 0; i < bufsz+4+(crc?1:0); ++i) { 217 | _outbyte(xbuff[i]); 218 | } 219 | if ((c = _inbyte(DLY_1S)) >= 0 ) { 220 | switch (c) { 221 | case ACK: 222 | ++packetno; 223 | len += bufsz; 224 | goto start_trans; 225 | case CAN: 226 | if ((c = _inbyte(DLY_1S)) == CAN) { 227 | _outbyte(ACK); 228 | flushinput(); 229 | return -1; /* canceled by remote */ 230 | } 231 | break; 232 | case NAK: 233 | default: 234 | break; 235 | } 236 | } 237 | } 238 | _outbyte(CAN); 239 | _outbyte(CAN); 240 | _outbyte(CAN); 241 | flushinput(); 242 | return -4; /* xmit error */ 243 | } else { 244 | for (retry = 0; retry < 10; ++retry) { 245 | _outbyte(EOT); 246 | if ((c = _inbyte((DLY_1S)<<1)) == ACK) break; 247 | } 248 | flushinput(); 249 | return (c == ACK)?len:-5; 250 | } 251 | } 252 | } 253 | } 254 | #endif 255 | 256 | #ifdef TEST_XMODEM_RECEIVE 257 | int main(void) 258 | { 259 | int st; 260 | 261 | printf("Send data using the xmodem protocol from your terminal emulator now...\n"); 262 | /* the following should be changed for your environment: 263 | 0x30000 is the download address, 264 | 65536 is the maximum size to be written at this address 265 | */ 266 | st = xmodemReceive((char *)0x30000, 65536); 267 | if (st < 0) { 268 | printf("Xmodem receive error: status: %d\n", st); 269 | } else { 270 | printf("Xmodem successfully received %d bytes\n", st); 271 | } 272 | 273 | return 0; 274 | } 275 | #endif 276 | #ifdef TEST_XMODEM_SEND 277 | int main(void) 278 | { 279 | int st; 280 | 281 | printf("Prepare your terminal emulator to receive data now...\n"); 282 | /* the following should be changed for your environment: 283 | 0x30000 is the download address, 284 | 12000 is the maximum size to be send from this address 285 | */ 286 | st = xmodemTransmit((char *)0x30000, 12000); 287 | if (st < 0) { 288 | printf("Xmodem transmit error: status: %d\n", st); 289 | } else { 290 | printf("Xmodem successfully transmitted %d bytes\n", st); 291 | } 292 | 293 | return 0; 294 | } 295 | #endif 296 | -------------------------------------------------------------------------------- /workloads/xmodem/xmodem.h: -------------------------------------------------------------------------------- 1 | int xmodemReceive(unsigned char *dest, int destsz); 2 | -------------------------------------------------------------------------------- /workloads/xx.mms: -------------------------------------------------------------------------------- 1 | * Fibonacci subroutines (exercise 1.4.1--13) 2 | 3 | IOSPACE GREG 4 | C GREG 5 | tmp GREG 6 | 7 | LOC #100 8 | Main SETH IOSPACE,1 9 | SETL C,'B'; PUSHJ $0,Putch 10 | SETL C,'E'; PUSHJ $0,Putch 11 | SETL C,'G'; PUSHJ $0,Putch 12 | SETL C,'I'; PUSHJ $0,Putch 13 | SETL C,'N'; PUSHJ $0,Putch 14 | SETL C,12; PUSHJ $0,Putch 15 | JMP Main 16 | 17 | PUSHJ $0,Fib 18 | ADDU C,$0,'A'; PUSHJ $0,Putch 19 | JMP Main 20 | 21 | Fib CMP $1,$0,2 22 | PBN $1,1F 23 | GET $1,rJ 24 | ADDU C,$0,'0'; PUSHJ $2,Putch 25 | SUB $3,$0,1 26 | PUSHJ $2,Fib $2=F_{n-1} 27 | SUB $4,$0,2 28 | PUSHJ $3,Fib $3=F_{n-2} 29 | ADDU $0,$2,$3 30 | PUT rJ,$1 31 | 1H POP 1,0 32 | 33 | Putch LDT tmp,IOSPACE 34 | PBOD tmp,Putch 35 | STBU C,IOSPACE 36 | POP 0,0 37 | --------------------------------------------------------------------------------