From a76977af62010a392c16010c367185e61e856ffe Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 30 Oct 2019 20:04:56 +0100 Subject: mv to docs --- docs/j1/.gitignore | 2 + docs/j1/Makefile | 14 + docs/j1/README.md | 4 + docs/j1/build/.empty | 0 docs/j1/build/.gitignore | 2 + docs/j1/go | 5 + docs/j1/sim_main.cpp | 76 +++++ docs/j1/toolchain/basewords.fs | 92 ++++++ docs/j1/toolchain/cross.fs | 321 +++++++++++++++++++++ docs/j1/toolchain/demo1.fs | 7 + docs/j1/toolchain/dump.py | 36 +++ docs/j1/toolchain/go | 3 + docs/j1/toolchain/nuc.fs | 604 +++++++++++++++++++++++++++++++++++++++ docs/j1/toolchain/strings.fs | 25 ++ docs/j1/verilog/common.h | 3 + docs/j1/verilog/j1.v | 123 ++++++++ docs/j1/verilog/stack.v | 22 ++ docs/j1/verilog/testbench.v | 30 ++ docs/j1/verilog/top.v | 9 + docs/j1/verilog/uart.v | 180 ++++++++++++ docs/j1/verilog/xilinx-top.v | 215 ++++++++++++++ docs/j1/xilinx/.gitignore | 44 +++ docs/j1/xilinx/Makefile | 11 + docs/j1/xilinx/go | 22 ++ docs/j1/xilinx/j1-papilioduo.bmm | 24 ++ docs/j1/xilinx/j1-papilioduo.ucf | 183 ++++++++++++ docs/j1/xilinx/shell.py | 78 +++++ docs/j1/xilinx/xilinx.mk | 176 ++++++++++++ docs/j1/xilinx/xilinx.opt | 42 +++ 29 files changed, 2353 insertions(+) create mode 100644 docs/j1/.gitignore create mode 100644 docs/j1/Makefile create mode 100644 docs/j1/README.md create mode 100644 docs/j1/build/.empty create mode 100644 docs/j1/build/.gitignore create mode 100644 docs/j1/go create mode 100644 docs/j1/sim_main.cpp create mode 100644 docs/j1/toolchain/basewords.fs create mode 100644 docs/j1/toolchain/cross.fs create mode 100644 docs/j1/toolchain/demo1.fs create mode 100644 docs/j1/toolchain/dump.py create mode 100644 docs/j1/toolchain/go create mode 100644 docs/j1/toolchain/nuc.fs create mode 100644 docs/j1/toolchain/strings.fs create mode 100644 docs/j1/verilog/common.h create mode 100644 docs/j1/verilog/j1.v create mode 100644 docs/j1/verilog/stack.v create mode 100644 docs/j1/verilog/testbench.v create mode 100644 docs/j1/verilog/top.v create mode 100644 docs/j1/verilog/uart.v create mode 100644 docs/j1/verilog/xilinx-top.v create mode 100644 docs/j1/xilinx/.gitignore create mode 100644 docs/j1/xilinx/Makefile create mode 100644 docs/j1/xilinx/go create mode 100644 docs/j1/xilinx/j1-papilioduo.bmm create mode 100644 docs/j1/xilinx/j1-papilioduo.ucf create mode 100644 docs/j1/xilinx/shell.py create mode 100644 docs/j1/xilinx/xilinx.mk create mode 100644 docs/j1/xilinx/xilinx.opt (limited to 'docs/j1') diff --git a/docs/j1/.gitignore b/docs/j1/.gitignore new file mode 100644 index 0000000..f169042 --- /dev/null +++ b/docs/j1/.gitignore @@ -0,0 +1,2 @@ +a.out +test.vcd diff --git a/docs/j1/Makefile b/docs/j1/Makefile new file mode 100644 index 0000000..34f0dae --- /dev/null +++ b/docs/j1/Makefile @@ -0,0 +1,14 @@ + +$(SUBDIRS): + $(MAKE) -C $@ + +all: obj_dir/Vj1 $(SUBDIRS) + +VERILOGS=verilog/j1.v verilog/stack.v + +obj_dir/Vj1: $(VERILOGS) sim_main.cpp Makefile + verilator -Wall --cc --trace -Iverilog/ $(VERILOGS) --top-module j1 --exe sim_main.cpp + # verilator --cc --trace $(VERILOGS) --top-module j1 --exe sim_main.cpp + $(MAKE) -C obj_dir OPT_FAST="-O2" -f Vj1.mk Vj1 + +.PHONY: all diff --git a/docs/j1/README.md b/docs/j1/README.md new file mode 100644 index 0000000..9a419f5 --- /dev/null +++ b/docs/j1/README.md @@ -0,0 +1,4 @@ +j1 +== + +The J1 CPU diff --git a/docs/j1/build/.empty b/docs/j1/build/.empty new file mode 100644 index 0000000..e69de29 diff --git a/docs/j1/build/.gitignore b/docs/j1/build/.gitignore new file mode 100644 index 0000000..ebc3c15 --- /dev/null +++ b/docs/j1/build/.gitignore @@ -0,0 +1,2 @@ +firmware +quartus diff --git a/docs/j1/go b/docs/j1/go new file mode 100644 index 0000000..c0740cb --- /dev/null +++ b/docs/j1/go @@ -0,0 +1,5 @@ +(cd toolchain && sh go) || exit +iverilog -I verilog/ -g2 -s testbench verilog/testbench.v verilog/top.v verilog/j1.v verilog/stack.v || exit +./a.out + +make && obj_dir/Vj1 build/firmware/demo0.hex diff --git a/docs/j1/sim_main.cpp b/docs/j1/sim_main.cpp new file mode 100644 index 0000000..ee075ac --- /dev/null +++ b/docs/j1/sim_main.cpp @@ -0,0 +1,76 @@ +#include +#include "Vj1.h" +#include "verilated_vcd_c.h" + +int main(int argc, char **argv) +{ + Verilated::commandArgs(argc, argv); + Vj1* top = new Vj1; + int i; + + // Verilated::traceEverOn(true); + // VerilatedVcdC* tfp = new VerilatedVcdC; + // top->trace (tfp, 99); + // tfp->open ("simx.vcd"); + + if (argc != 2) { + fprintf(stderr, "usage: sim \n"); + exit(1); + } + + union { + uint32_t ram32[4096]; + uint16_t ram16[8192]; + }; + + FILE *hex = fopen(argv[1], "r"); + for (i = 0; i < 4096; i++) { + unsigned int v; + if (fscanf(hex, "%x\n", &v) != 1) { + fprintf(stderr, "invalid hex value at line %d\n", i + 1); + exit(1); + } + ram32[i] = v; + } + + FILE *log = fopen("log", "w"); + int t = 0; + + top->resetq = 0; + top->eval(); + top->resetq = 1; + top->eval(); + + for (i = 0; i < 100000000; i++) { + uint16_t a = top->mem_addr; + uint16_t b = top->code_addr; + if (top->mem_wr) + ram32[(a & 16383) / 4] = top->dout; + top->clk = 1; + top->eval(); + t += 20; + + top->mem_din = ram32[(a & 16383) / 4]; + top->insn = ram16[b]; + top->clk = 0; + top->eval(); + t += 20; + if (top->io_wr) { + putchar(top->dout); + putc(top->dout, log); + if (top->dout == '#') + break; + } +#if 0 + if (top->io_inp && (top->io_n == 2)) { + top->io_din = getchar(); + } +#endif + } + printf("\nSimulation ended after %d cycles\n", i); + delete top; + // tfp->close(); + fclose(log); + + exit(0); +} diff --git a/docs/j1/toolchain/basewords.fs b/docs/j1/toolchain/basewords.fs new file mode 100644 index 0000000..6534d2b --- /dev/null +++ b/docs/j1/toolchain/basewords.fs @@ -0,0 +1,92 @@ +( J1 base words implemented in assembler JCB 17:27 12/31/11) + +: T h# 0000 ; +: N h# 0100 ; +: T+N h# 0200 ; +: T&N h# 0300 ; +: T|N h# 0400 ; +: T^N h# 0500 ; +: ~T h# 0600 ; +: N==T h# 0700 ; +: N>T h# 0900 ; +: N<N h# 0010 or ; +: T->R h# 0020 or ; +: N->[T] h# 0030 or ; +: N->io[T] h# 0040 or ; +: RET h# 0080 or ; + +: d-1 h# 0003 or ; +: d+1 h# 0001 or ; +: r-1 h# 000c or ; +: r-2 h# 0008 or ; +: r+1 h# 0004 or ; + +: imm h# 8000 or tw, ; +: alu h# 6000 or tw, ; +: ubranch h# 0000 or tw, ; +: 0branch h# 2000 or tw, ; +: scall h# 4000 or tw, ; + + +:: noop T alu ; +:: + T+N d-1 alu ; +:: xor T^N d-1 alu ; +:: and T&N d-1 alu ; +:: or T|N d-1 alu ; +:: invert ~T alu ; +:: = N==T d-1 alu ; +:: < NN alu ; +:: dup T T->N d+1 alu ; +:: drop N d-1 alu ; +:: over N T->N d+1 alu ; +:: nip T d-1 alu ; +:: >r N T->R r+1 d-1 alu ; +:: r> rT T->N r-1 d+1 alu ; +:: r@ rT T->N d+1 alu ; +:: @ [T] alu ; +:: io@ io[T] alu ; +:: ! T N->[T] d-1 alu + N d-1 alu ; +:: io! T N->io[T] d-1 alu + N d-1 alu ; +:: rshift N>>T d-1 alu ; +:: lshift N<N d+1 alu ; +:: exit T RET r-1 alu ; + +\ Elided words +\ These words are supported by the hardware but are not +\ part of ANS Forth. They are named after the word-pair +\ that matches their effect +\ Using these elided words instead of +\ the pair saves one cycle and one instruction. + +:: 2dupand T&N T->N d+1 alu ; +:: 2dup< NN d+1 alu ; +:: 2dup= N==T T->N d+1 alu ; +:: 2dupor T|N T->N d+1 alu ; +:: 2duprshift N>>T T->N d+1 alu ; +:: 2dup+ T+N T->N d+1 alu ; +:: 2dupu< NuN d+1 alu ; +:: 2dupxor T^N T->N d+1 alu ; +:: dup>r T T->R r+1 alu ; +:: dup@ [T] T->N d+1 alu ; +:: overand T&N alu ; +:: over> N Nu[T] d-1 alu ; diff --git a/docs/j1/toolchain/cross.fs b/docs/j1/toolchain/cross.fs new file mode 100644 index 0000000..56c0025 --- /dev/null +++ b/docs/j1/toolchain/cross.fs @@ -0,0 +1,321 @@ +( J1 Cross Compiler JCB 16:55 05/02/12) + +\ Usage gforth cross.fs +\ +\ Where machine.fs defines the target machine +\ and program.fs is the target program +\ + +variable lst \ .lst output file handle + +: h# + base @ >r 16 base ! + 0. bl parse >number throw 2drop postpone literal + r> base ! ; immediate + +: tcell 2 ; +: tcells tcell * ; +: tcell+ tcell + ; + +131072 allocate throw constant tflash \ bytes, target flash +131072 allocate throw constant _tbranches \ branch targets, cells +tflash 31072 0 fill +_tbranches 131072 0 fill +: tbranches cells _tbranches + ; + +variable tdp 0 tdp ! +: there tdp @ ; +: islegal ; +: tc! islegal tflash + c! ; +: tc@ islegal tflash + c@ ; +: tw! islegal tflash + w! ; +: t! islegal tflash + l! ; +: t@ islegal tflash + uw@ ; +: twalign tdp @ 1+ -2 and tdp ! ; +: talign tdp @ 3 + -4 and tdp ! ; +: tc, there tc! 1 tdp +! ; +: t, there t! 4 tdp +! ; +: tw, there tw! tcell tdp +! ; +: org tdp ! ; + +wordlist constant target-wordlist +: add-order ( wid -- ) >r get-order r> swap 1+ set-order ; +: :: get-current >r target-wordlist set-current : r> set-current ; + +next-arg included \ include the machine.fs + +( Language basics for target JCB 19:08 05/02/12) + +warnings off +:: ( postpone ( ; +:: \ postpone \ ; + +:: org org ; +:: include include ; +:: included included ; +:: marker marker ; +:: [if] postpone [if] ; +:: [else] postpone [else] ; +:: [then] postpone [then] ; + +: literal + \ dup $f rshift over $e rshift xor 1 and throw + dup h# 8000 and if + h# ffff xor recurse + ~T alu + else + h# 8000 or tw, + then +; + +: literal + dup $80000000 and if + invert recurse + ~T alu + else + dup $ffff8000 and if + dup $F rshift recurse + $f recurse + N<in @ >r bl word count r> >in ! +; + +variable link 0 link ! + +:: header + twalign there + \ cr ." link is " link @ . + link @ tw, + link ! + bl parse + dup tc, + bounds do + i c@ tc, + loop + twalign +; + +:: : + hex + codeptr s>d + <# bl hold # # # # #> + lst @ write-file throw + wordstr lst @ write-line throw + + create codeptr , + does> @ scall +; + +:: :noname +; + +:: , + talign + t, +; + +:: allot + 0 ?do + 0 tc, + loop +; + +: shortcut ( orig -- f ) \ insn @orig precedes ;. Shortcut it. + \ call becomes jump + dup t@ h# e000 and h# 4000 = if + dup t@ h# 1fff and over tw! + true + else + dup t@ h# e00c and h# 6000 = if + dup t@ h# 0080 or r-1 over tw! + true + else + false + then + then + nip +; + +:: ; + there 2 - shortcut \ true if shortcut applied + there 0 do + i tbranches @ there = if + i tbranches @ shortcut and + then + loop + 0= if \ not all shortcuts worked + s" exit" evaluate + then +; +:: ;fallthru ; + +:: jmp + ' >body @ ubranch +; + +:: constant + create , + does> @ literal +; + +:: create + talign + create there , + does> @ literal +; + +( Switching between target and meta JCB 19:08 05/02/12) + +: target only target-wordlist add-order definitions ; +: ] target ; +:: meta forth definitions ; +:: [ forth definitions ; + +: t' bl parse target-wordlist search-wordlist 0= throw >body @ ; + +( eforth's way of handling constants JCB 13:12 09/03/10) + +: sign>number ( c-addr1 u1 -- ud2 c-addr2 u2 ) + 0. 2swap + over c@ [char] - = if + 1 /string + >number + 2swap dnegate 2swap + else + >number + then +; + +: base>number ( caddr u base -- ) + base @ >r base ! + sign>number + r> base ! + dup 0= if + 2drop drop literal + else + 1 = swap c@ [char] . = and if + drop dup literal 32 rshift literal + else + -1 abort" bad number" + then + then ; +warnings on + +:: d# bl parse 10 base>number ; +:: h# bl parse 16 base>number ; +:: ['] ' >body @ 2* literal ; +:: [char] char literal ; + +:: asm-0branch + ' >body @ + 0branch +; + +( Conditionals JCB 13:12 09/03/10) + +: resolve ( orig -- ) + there over tbranches ! \ forward reference from orig to this loc + dup t@ there 2/ or swap tw! +; + +:: if + there + 0 0branch +; + +:: then + resolve +; + +:: else + there + 0 ubranch + swap resolve +; + +:: begin there ; + +:: again ( dest -- ) + 2/ ubranch +; +:: until + 2/ 0branch +; +:: while + there + 0 0branch +; +:: repeat + swap 2/ ubranch + resolve +; + +4 org +: .trim ( a-addr u ) \ shorten string until it ends with '.' + begin + 2dup + 1- c@ [char] . <> + while + 1- + repeat +; +include strings.fs +next-arg 2dup .trim >str constant prefix. +: .suffix ( c-addr u -- c-addr u ) \ e.g. "bar" -> "foo.bar" + >str prefix. +str str@ +; +: create-output-file w/o create-file throw ; +: out-suffix ( s -- h ) \ Create an output file h with suffix s + >str + prefix. +str + s" ../build/firmware/" >str +str str@ + create-output-file +; +:noname + s" lst" out-suffix lst ! +; execute + + +target included \ include the program.fs + +[ tdp @ 0 org ] bootloader main [ org ] +meta + +decimal +0 value file +: dumpall.16 + s" hex" out-suffix to file + + hex + 1024 0 do + tflash i 2* + w@ + s>d <# # # # # #> file write-line throw + loop + file close-file +; +: dumpall.32 + s" hex" out-suffix to file + + hex + 4096 0 do + tflash i 4 * + @ + s>d <# # # # # # # # # #> file write-line throw + loop + file close-file +; + +dumpall.32 + +bye diff --git a/docs/j1/toolchain/demo1.fs b/docs/j1/toolchain/demo1.fs new file mode 100644 index 0000000..7c49af4 --- /dev/null +++ b/docs/j1/toolchain/demo1.fs @@ -0,0 +1,7 @@ +: main + begin + h# 0 io@ + d# 1 + + h# 0 io! + again +; diff --git a/docs/j1/toolchain/dump.py b/docs/j1/toolchain/dump.py new file mode 100644 index 0000000..283916b --- /dev/null +++ b/docs/j1/toolchain/dump.py @@ -0,0 +1,36 @@ +import sys +import array + +def hexdump(s): + def toprint(c): + if 32 <= ord(c) < 127: + return c + else: + return "." + def hexline(i, s): + return ("%04x: " % i + " ".join(["%02x" % ord(c) for c in s]).ljust(52) + + "|" + + "".join([toprint(c) for c in s]).ljust(16) + + "|") + return "\n".join([hexline(i, s[i:i+16]) for i in range(0, len(s), 16)]) + +pgm = array.array('H', [int(l, 16) for l in open(sys.argv[1])]) + +while pgm[-1] == 0: + pgm = pgm[:-1] +s = pgm.tostring() +print +print hexdump(s) + +link = [w for w in pgm[::-1] if w][0] +words = [] +while link: + name = s[link + 2:] + c = ord(name[0]) + name = name[1:1+c] + print "%04x %s" % (link, name) + assert not name in words + words.append(name) + link = pgm[link / 2] +print len(words), " ".join(words) +print "program size %d/%d" % (len(pgm), 1024) diff --git a/docs/j1/toolchain/go b/docs/j1/toolchain/go new file mode 100644 index 0000000..6570942 --- /dev/null +++ b/docs/j1/toolchain/go @@ -0,0 +1,3 @@ +set -e +gforth cross.fs basewords.fs nuc.fs +# python dump.py ../build/firmware/demo0.hex diff --git a/docs/j1/toolchain/nuc.fs b/docs/j1/toolchain/nuc.fs new file mode 100644 index 0000000..846db05 --- /dev/null +++ b/docs/j1/toolchain/nuc.fs @@ -0,0 +1,604 @@ +header 1+ : 1+ d# 1 + ; +header 1- : 1- d# -1 + ; +header 0= : 0= d# 0 = ; +header cell+ : cell+ d# 2 + ; + +header <> : <> = invert ; +header > : > swap < ; +header 0< : 0< d# 0 < ; +header 0> : 0> d# 0 > ; +header 0<> : 0<> d# 0 <> ; +header u> : u> swap u< ; + +: eol ( u -- u' false | true ) + d# -1 + + dup 0= dup if + ( 0 true -- ) + nip + then +; + +header ms +: ms + begin + d# 15000 begin + eol until + eol until +; + + +header key? +: key? + d# 0 io@ + d# 4 and + 0<> +; + +header key +: key + begin + key? + until + d# 0 io@ d# 8 rshift + d# 0 d# 2 io! +; + +: ready + d# 0 io@ + d# 2 and + 0= +; + +header emit +: emit + begin ready until + h# 0 io! +; + +header cr +: cr + d# 13 emit + d# 10 emit +; + +header space +: space + d# 32 emit +; + +header bl +: bl + d# 32 +; + +: hex1 + h# f and + dup d# 10 < if + [char] 0 + else + d# 55 + then + + + emit +; + +: hex2 + dup d# 4 rshift hex1 hex1 +; + +: hex4 + dup d# 8 rshift hex2 hex2 +; + +: hex8 + dup d# 16 rshift hex4 hex4 +; + +header . +: . hex8 space ; + +header false : false d# 0 ; +header true : true d# -1 ; +header rot : rot >r swap r> swap ; +header -rot : -rot swap >r swap r> ; +header tuck : tuck swap over ; +header 2drop : 2drop drop drop ; +header ?dup : ?dup dup if dup then ; + +header 2dup : 2dup over over ; +header +! : +! tuck @ + swap ! ; +header 2swap : 2swap rot >r rot r> ; + +header min : min 2dup< if drop else nip then ; +header max : max 2dup< if nip else drop then ; + +header c@ +: c@ + dup @ swap + d# 3 and d# 3 lshift rshift + d# 255 and +; + +: hi16 + d# 16 rshift d# 16 lshift +; + +: lo16 + d# 16 lshift d# 16 rshift +; + +header uw@ +: uw@ + dup @ swap + d# 2 and d# 3 lshift rshift + lo16 +; + +header w! +: w! ( u c-addr -- ) + dup>r d# 2 and if + d# 16 lshift + r@ @ lo16 + else + lo16 + r@ @ hi16 + then + or r> ! +; + +header c! +: c! ( u c-addr -- ) + dup>r d# 1 and if + d# 8 lshift + h# 00ff + else + h# 00ff and + h# ff00 + then + r@ uw@ and + or r> w! +; + +header count +: count + dup 1+ swap c@ +; + +: bounds ( a n -- a+n a ) + over + swap +; + +header type +: type + bounds + begin + 2dupxor + while + dup c@ emit + 1+ + repeat + 2drop +; + +create base $a , +create ll 0 , +create dp 0 , +create tib# 0 , +create >in 0 , +create tib 80 allot + +header words : words + ll uw@ + begin + dup + while + cr + dup . + dup cell+ + count type + space + uw@ + repeat + drop +; + +header dump : dump ( addr u -- ) + cr over hex4 + begin ( addr u ) + ?dup + while + over c@ space hex2 + 1- swap 1+ ( u' addr' ) + dup h# f and 0= if ( next line? ) + cr dup hex4 + then + swap + repeat + drop cr +; + +header negate : negate invert 1+ ; +header - : - negate + ; +header abs : abs dup 0< if negate then ; +header 2* : 2* d# 1 lshift ; +header 2/ : 2/ d# 1 rshift ; +header here : here dp @ ; +header depth : depth depths h# f and ; + +: /string + dup >r - swap r> + swap +; + +header aligned +: aligned + d# 3 + d# -4 and +; + +: d+ ( augend . addend . -- sum . ) + rot + >r ( augend addend) + over + ( augend sum) + dup rot ( sum sum augend) + u< if ( sum) + r> 1+ + else + r> + then ( sum . ) +; + +: d1+ d# 1. d+ ; + +: dnegate + invert swap invert swap + d1+ +; + +: dabs ( d -- ud ) + dup 0< if dnegate then +; + +: s>d dup 0< ; +: m+ + s>d d+ +; + +: snap + cr depth hex2 space + begin + depth + while + . + repeat + cr + [char] # emit + begin again +; + +create scratch 0 , + +header um* +: um* ( u1 u2 -- ud ) + scratch ! + d# 0. + d# 32 begin + >r + 2dup d+ + rot dup 0< if + 2* -rot + scratch @ d# 0 d+ + else + 2* -rot + then + r> eol + until + rot drop +; +: * + um* drop +; + +header accept +: accept + d# 30 emit + drop dup + begin + key + dup h# 0d xor + while + dup h# 0a = if + drop + else + over c! 1+ + then + repeat + drop swap - +; + +: 3rd >r over r> swap ; +: 3dup 3rd 3rd 3rd ; + +: sameword ( c-addr u wp -- c-addr u wp flag ) + 2dup d# 2 + c@ = if + 3dup + d# 3 + >r + bounds + begin + 2dupxor + while + dup c@ r@ c@ <> if + 2drop rdrop false exit + then + 1+ + r> 1+ >r + repeat + 2drop rdrop true + else + false + then +; + +\ lsb 0 means non-immediate, return -1 +\ 1 means immediate, return 1 +: isimmediate ( wp -- -1 | 1 ) + uw@ d# 1 and 2* 1- +; + +: sfind + ll uw@ + begin + dup + while + sameword + if + nip nip + dup + d# 2 + + count + + d# 1 + d# -2 and + swap isimmediate + exit + then + uw@ + repeat +; + +: digit? ( c -- u f ) + dup h# 39 > h# 100 and + + dup h# 140 > h# 107 and - h# 30 - + dup base @ u< +; + +: ud* ( ud1 u -- ud2 ) \ ud2 is the product of ud1 and u + tuck * >r + um* r> + +; + +: >number ( ud1 c-addr1 u1 -- ud2 c-addr2 u2 ) + begin + dup + while + over c@ digit? + 0= if drop exit then + >r 2swap base @ ud* + r> m+ 2swap + d# 1 /string + repeat +; + +header fill +: fill ( c-addr u char -- ) ( 6.1.1540 ) + >r bounds + begin + 2dupxor + while + r@ over c! 1+ + repeat + r> drop 2drop +; + +header erase +: erase + d# 0 fill +; + +header execute +: execute + >r +; + +header source +: source + tib tib# @ +; + +\ From Forth200x - public domain + +: isspace? ( c -- f ) + bl 1+ u< ; + +: isnotspace? ( c -- f ) + isspace? 0= ; + +: xt-skip ( addr1 n1 xt -- addr2 n2 ) \ gforth + \ skip all characters satisfying xt ( c -- f ) + >r + BEGIN + over c@ r@ execute + over 0<> and + WHILE + d# 1 /string + REPEAT + r> drop ; + +: parse-name ( "name" -- c-addr u ) + source >in @ /string + ['] isspace? xt-skip over >r + ['] isnotspace? xt-skip ( end-word restlen r: start-word ) + 2dup d# 1 min + source drop - >in ! + drop r> tuck - ; + +header ! :noname ! ; +header + :noname + ; +header xor :noname xor ; +header and :noname and ; +header or :noname or ; +header invert :noname invert ; +header = :noname = ; +header < :noname < ; +header u< :noname u< ; +header swap :noname swap ; +header dup :noname dup ; +header drop :noname drop ; +header over :noname over ; +header nip :noname nip ; +header @ :noname @ ; +header io! :noname io! ; +header rshift :noname rshift ; +header lshift :noname lshift ; +\ +\ \ >r +\ \ r> +\ \ r@ +\ \ exit +\ + +: xmain + cr d# 1 ms cr + d# 60 begin + [char] - emit + eol until + begin key? while key drop repeat + + cr h# ffff hex8 + + d# 0 d# 100 dump + words cr cr + + begin again + + begin + cr + tib d# 30 accept >r + d# 0. tib r> >number + 2drop hex4 space hex4 + again + + snap +; + +: route + r> + >r ; + +\ (doubleAlso) ( c-addr u -- x 1 | x x 2 ) +\ If the string is legal, leave a single or double cell number +\ and size of the number. + +: isvoid ( caddr u -- ) \ any char remains, throw -13 + nip 0<> + if [char] x emit snap then +; + +: consume1 ( caddr u ch -- caddr' u' f ) + >r over c@ r> = + over 0<> and + dup>r d# 1 and /string r> +; + +: (doubleAlso) + h# 0. 2swap + [char] - consume1 >r + >number + [char] . consume1 if + isvoid \ double number + r> if dnegate then + d# 2 exit + then + \ single number + isvoid drop + r> if negate then + d# 1 +; + +: doubleAlso + (doubleAlso) drop +; + + +: dispatch + route ;fallthru + jmp execute \ -1 0 non-immediate + jmp doubleAlso \ 0 0 number + jmp execute \ 1 0 immediate + +\ jmp compile_comma \ -1 2 non-immediate +\ jmp doubleAlso_comma \ 0 2 number +\ jmp execute \ 1 2 immediate + +: interpret + begin + parse-name dup + while + sfind + 1+ 2* dispatch + repeat + 2drop +; + +: main + 2drop + begin + tib d# 80 accept + tib# ! + \ h# 40 emit + d# 0 >in ! + source dump + \ cr parse-name sfind + \ if + \ execute + \ then + interpret + again +; + +meta + $3f80 org +target + +: b.key + begin + d# 0 io@ + d# 4 and + until + d# 0 io@ d# 8 rshift + d# 0 d# 2 io! +; + +: b.32 + b.key + b.key d# 8 lshift or + b.key d# 16 lshift or + b.key d# 24 lshift or +; + +meta + $3fc0 org +target + +: bootloader + begin + b.key d# 27 = + until + + b.32 d# 0 + begin + 2dupxor + while + b.32 over ! + d# 4 + + repeat +; + +meta + link @ t, + link @ t' ll tw! + there t' dp tw! +target diff --git a/docs/j1/toolchain/strings.fs b/docs/j1/toolchain/strings.fs new file mode 100644 index 0000000..cbd9b0e --- /dev/null +++ b/docs/j1/toolchain/strings.fs @@ -0,0 +1,25 @@ +( Strings JCB 11:57 05/18/12) + +: >str ( c-addr u -- str ) \ a new u char string from c-addr + dup cell+ allocate throw dup >r + 2dup ! cell+ \ write size into first cell + ( c-addr u saddr ) + swap cmove r> +; +: str@ dup cell+ swap @ ; +: str! ( str c-addr -- c-addr' ) \ copy str to c-addr + >r str@ r> + 2dup + >r swap + cmove r> +; +: +str ( str2 str1 -- str3 ) + over @ over @ + cell+ allocate throw >r + over @ over @ + r@ ! + r@ cell+ str! str! drop r> +; + +: example + s" sailor" >str + s" hello" >str + +str str@ type +; diff --git a/docs/j1/verilog/common.h b/docs/j1/verilog/common.h new file mode 100644 index 0000000..03da65d --- /dev/null +++ b/docs/j1/verilog/common.h @@ -0,0 +1,3 @@ +`default_nettype none +`define WIDTH 32 +`define DEPTH 4 diff --git a/docs/j1/verilog/j1.v b/docs/j1/verilog/j1.v new file mode 100644 index 0000000..d69ca20 --- /dev/null +++ b/docs/j1/verilog/j1.v @@ -0,0 +1,123 @@ +`include "common.h" + +module j1( + input wire clk, + input wire resetq, + + output wire io_wr, + output wire [15:0] mem_addr, + output wire mem_wr, + output wire [`WIDTH-1:0] dout, + input wire [`WIDTH-1:0] mem_din, + + input wire [`WIDTH-1:0] io_din, + + output wire [12:0] code_addr, + input wire [15:0] insn + ); + reg [`DEPTH-1:0] dsp; // Data stack pointer + reg [`DEPTH-1:0] dspN; + reg [`WIDTH-1:0] st0; // Top of data stack + reg [`WIDTH-1:0] st0N; + reg dstkW; // D stack write + + reg [12:0] pc, pcN; + reg [`DEPTH-1:0] rsp, rspN; + reg rstkW; // R stack write + wire [`WIDTH-1:0] rstkD; // R stack write value + reg reboot = 1; + wire [12:0] pc_plus_1 = pc + 1; + + assign mem_addr = st0N[15:0]; + assign code_addr = {pcN}; + + // The D and R stacks + wire [`WIDTH-1:0] st1, rst0; + stack #(.DEPTH(`DEPTH)) + dstack(.clk(clk), .resetq(resetq), .ra(dsp), .rd(st1), .we(dstkW), .wa(dspN), .wd(st0)); + stack #(.DEPTH(`DEPTH))rstack(.clk(clk), .resetq(resetq), .ra(rsp), .rd(rst0), .we(rstkW), .wa(rspN), .wd(rstkD)); + + always @* + begin + // Compute the new value of st0 + casez ({insn[15:8]}) + 8'b1??_?????: st0N = { {(`WIDTH - 15){1'b0}}, insn[14:0] }; // literal + 8'b000_?????: st0N = st0; // jump + 8'b010_?????: st0N = st0; // call + 8'b001_?????: st0N = st1; // conditional jump + 8'b011_?0000: st0N = st0; // ALU operations... + 8'b011_?0001: st0N = st1; + 8'b011_?0010: st0N = st0 + st1; + 8'b011_?0011: st0N = st0 & st1; + 8'b011_?0100: st0N = st0 | st1; + 8'b011_?0101: st0N = st0 ^ st1; + 8'b011_?0110: st0N = ~st0; + 8'b011_?0111: st0N = {`WIDTH{(st1 == st0)}}; + 8'b011_?1000: st0N = {`WIDTH{($signed(st1) < $signed(st0))}}; +`ifdef NOSHIFTER // `define NOSHIFTER in common.h to cut slice usage in half and shift by 1 only + 8'b011_?1001: st0N = st1 >> 1; + 8'b011_?1010: st0N = st1 << 1; +`else // otherwise shift by 1-any number of bits + 8'b011_?1001: st0N = st1 >> st0[4:0]; + 8'b011_?1010: st0N = st1 << st0[4:0]; +`endif + 8'b011_?1011: st0N = rst0; + 8'b011_?1100: st0N = mem_din; + 8'b011_?1101: st0N = io_din; + 8'b011_?1110: st0N = {{(`WIDTH - 8){1'b0}}, rsp, dsp}; + 8'b011_?1111: st0N = {`WIDTH{(st1 < st0)}}; + default: st0N = {`WIDTH{1'bx}}; + endcase + end + + wire func_T_N = (insn[6:4] == 1); + wire func_T_R = (insn[6:4] == 2); + wire func_write = (insn[6:4] == 3); + wire func_iow = (insn[6:4] == 4); + + wire is_alu = (insn[15:13] == 3'b011); + assign mem_wr = !reboot & is_alu & func_write; + assign dout = st1; + assign io_wr = !reboot & is_alu & func_iow; + + assign rstkD = (insn[13] == 1'b0) ? {{(`WIDTH - 14){1'b0}}, pc_plus_1, 1'b0} : st0; + + reg [`DEPTH-1:0] dspI, rspI; + always @* + begin + casez ({insn[15:13]}) + 3'b1??: {dstkW, dspI} = {1'b1, 4'b0001}; + 3'b001: {dstkW, dspI} = {1'b0, 4'b1111}; + 3'b011: {dstkW, dspI} = {func_T_N, {insn[1], insn[1], insn[1:0]}}; + default: {dstkW, dspI} = {1'b0, 4'b0000}; + endcase + dspN = dsp + dspI; + + casez ({insn[15:13]}) + 3'b010: {rstkW, rspI} = {1'b1, 4'b0001}; + 3'b011: {rstkW, rspI} = {func_T_R, {insn[3], insn[3], insn[3:2]}}; + default: {rstkW, rspI} = {1'b0, 4'b0000}; + endcase + rspN = rsp + rspI; + + casez ({reboot, insn[15:13], insn[7], |st0}) + 6'b1_???_?_?: pcN = 0; + 6'b0_000_?_?, + 6'b0_010_?_?, + 6'b0_001_?_0: pcN = insn[12:0]; + 6'b0_011_1_?: pcN = rst0[13:1]; + default: pcN = pc_plus_1; + endcase + end + + always @(negedge resetq or posedge clk) + begin + if (!resetq) begin + reboot <= 1'b1; + { pc, dsp, st0, rsp } <= 0; + end else begin + reboot <= 0; + { pc, dsp, st0, rsp } <= { pcN, dspN, st0N, rspN }; + end + end +endmodule diff --git a/docs/j1/verilog/stack.v b/docs/j1/verilog/stack.v new file mode 100644 index 0000000..e5cee8a --- /dev/null +++ b/docs/j1/verilog/stack.v @@ -0,0 +1,22 @@ +`include "common.h" + +module stack + #(parameter DEPTH=4) + (input wire clk, + /* verilator lint_off UNUSED */ + input wire resetq, + /* verilator lint_on UNUSED */ + input wire [DEPTH-1:0] ra, + output wire [`WIDTH-1:0] rd, + input wire we, + input wire [DEPTH-1:0] wa, + input wire [`WIDTH-1:0] wd); + + reg [`WIDTH-1:0] store[0:(2**DEPTH)-1]; + + always @(posedge clk) + if (we) + store[wa] <= wd; + + assign rd = store[ra]; +endmodule diff --git a/docs/j1/verilog/testbench.v b/docs/j1/verilog/testbench.v new file mode 100644 index 0000000..2ec2b5e --- /dev/null +++ b/docs/j1/verilog/testbench.v @@ -0,0 +1,30 @@ +`timescale 1ns/1ps +`default_nettype none + +module testbench(); + + reg clk; + reg resetq; + integer t; + + top #(.FIRMWARE("build/firmware/")) dut(.clk(clk), .resetq(resetq)); + + initial begin + clk = 1; + t = 0; + resetq = 0; + #1; + resetq = 1; + + $dumpfile("test.vcd"); + $dumpvars(0, dut); + end + + always #5.0 clk = ~clk; + + always @(posedge clk) begin + t <= t + 1; + if (t == 300) + $finish; + end +endmodule diff --git a/docs/j1/verilog/top.v b/docs/j1/verilog/top.v new file mode 100644 index 0000000..efcf297 --- /dev/null +++ b/docs/j1/verilog/top.v @@ -0,0 +1,9 @@ +module top( + input clk, + input resetq, + output [15:0] tail); + parameter FIRMWARE = ""; + + j1 _j1 (.clk(clk), .resetq(resetq)); + +endmodule diff --git a/docs/j1/verilog/uart.v b/docs/j1/verilog/uart.v new file mode 100644 index 0000000..4daac0f --- /dev/null +++ b/docs/j1/verilog/uart.v @@ -0,0 +1,180 @@ +`default_nettype none + +module baudgen( + input wire clk, + input wire resetq, + input wire [31:0] baud, + input wire restart, + output wire ser_clk); + parameter CLKFREQ = 1000000; + + wire [38:0] aclkfreq = CLKFREQ; + reg [38:0] d; + wire [38:0] dInc = d[38] ? ({4'd0, baud}) : (({4'd0, baud}) - aclkfreq); + wire [38:0] dN = restart ? 0 : (d + dInc); + wire fastclk = ~d[38]; + assign ser_clk = fastclk; + + always @(negedge resetq or posedge clk) + begin + if (!resetq) begin + d <= 0; + end else begin + d <= dN; + end + end +endmodule + +/* + +-----+ +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+---- + | | | | | | | | | | | | + |start| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |stop1|stop2| + | | | | | | | | | | | ? | + +-----+-----+-----+-----+-----+-----+-----+-----+-----+ + + +*/ + +module uart( + input wire clk, // System clock + input wire resetq, + + // Outputs + output wire uart_busy, // High means UART is transmitting + output reg uart_tx, // UART transmit wire + // Inputs + input wire [31:0] baud, + input wire uart_wr_i, // Raise to transmit byte + input wire [7:0] uart_dat_i // 8-bit data +); + parameter CLKFREQ = 1000000; + + reg [3:0] bitcount; + reg [8:0] shifter; + + assign uart_busy = |bitcount; + wire sending = |bitcount; + + wire ser_clk; + + wire starting = uart_wr_i & ~uart_busy; + baudgen #(.CLKFREQ(CLKFREQ)) _baudgen( + .clk(clk), + .resetq(resetq), + .baud(baud), + .restart(1'b0), + .ser_clk(ser_clk)); + + always @(negedge resetq or posedge clk) + begin + if (!resetq) begin + uart_tx <= 1; + bitcount <= 0; + shifter <= 0; + end else begin + if (starting) begin + shifter <= { uart_dat_i[7:0], 1'b0 }; + bitcount <= 1 + 8 + 1; + end + + if (sending & ser_clk) begin + { shifter, uart_tx } <= { 1'b1, shifter }; + bitcount <= bitcount - 4'd1; + end + end + end + +endmodule + +module rxuart( + input wire clk, + input wire resetq, + input wire [31:0] baud, + input wire uart_rx, // UART recv wire + input wire rd, // read strobe + output wire valid, // has data + output wire [7:0] data); // data + parameter CLKFREQ = 1000000; + + reg [4:0] bitcount; + reg [7:0] shifter; + + // On starting edge, wait 3 half-bits then sample, and sample every 2 bits thereafter + + wire idle = &bitcount; + wire sample; + reg [2:0] hh = 3'b111; + wire [2:0] hhN = {hh[1:0], uart_rx}; + wire startbit = idle & (hhN[2:1] == 2'b10); + wire [7:0] shifterN = sample ? {hh[1], shifter[7:1]} : shifter; + + wire ser_clk; + baudgen #(.CLKFREQ(CLKFREQ)) _baudgen( + .clk(clk), + .baud({baud[30:0], 1'b0}), + .resetq(resetq), + .restart(startbit), + .ser_clk(ser_clk)); + + assign valid = (bitcount == 18); + reg [4:0] bitcountN; + always @* + if (startbit) + bitcountN = 0; + else if (!idle & !valid & ser_clk) + bitcountN = bitcount + 5'd1; + else if (valid & rd) + bitcountN = 5'b11111; + else + bitcountN = bitcount; + + // 3,5,7,9,11,13,15,17 + assign sample = (bitcount > 2) & bitcount[0] & !valid & ser_clk; + assign data = shifter; + + always @(negedge resetq or posedge clk) + begin + if (!resetq) begin + hh <= 3'b111; + bitcount <= 5'b11111; + shifter <= 0; + end else begin + hh <= hhN; + bitcount <= bitcountN; + shifter <= shifterN; + end + end +endmodule + +module buart( + input wire clk, + input wire resetq, + input wire [31:0] baud, + input wire rx, // recv wire + output wire tx, // xmit wire + input wire rd, // read strobe + input wire wr, // write strobe + output wire valid, // has recv data + output wire busy, // is transmitting + input wire [7:0] tx_data, + output wire [7:0] rx_data // data +); + parameter CLKFREQ = 1000000; + + rxuart #(.CLKFREQ(CLKFREQ)) _rx ( + .clk(clk), + .resetq(resetq), + .baud(baud), + .uart_rx(rx), + .rd(rd), + .valid(valid), + .data(rx_data)); + uart #(.CLKFREQ(CLKFREQ)) _tx ( + .clk(clk), + .resetq(resetq), + .baud(baud), + .uart_busy(busy), + .uart_tx(tx), + .uart_wr_i(wr), + .uart_dat_i(tx_data)); +endmodule diff --git a/docs/j1/verilog/xilinx-top.v b/docs/j1/verilog/xilinx-top.v new file mode 100644 index 0000000..6695d77 --- /dev/null +++ b/docs/j1/verilog/xilinx-top.v @@ -0,0 +1,215 @@ +`default_nettype none + + +module bram_tdp #( + parameter DATA = 72, + parameter ADDR = 10 +) ( + // Port A + input wire a_clk, + input wire a_wr, + input wire [ADDR-1:0] a_addr, + input wire [DATA-1:0] a_din, + output reg [DATA-1:0] a_dout, + + // Port B + input wire b_clk, + input wire b_wr, + input wire [ADDR-1:0] b_addr, + input wire [DATA-1:0] b_din, + output reg [DATA-1:0] b_dout +); + +// Shared memory +reg [DATA-1:0] mem [(2**ADDR)-1:0]; + initial begin + $readmemh("../build/firmware/demo0.hex", mem); + end + +// Port A +always @(posedge a_clk) begin + a_dout <= mem[a_addr]; + if(a_wr) begin + a_dout <= a_din; + mem[a_addr] <= a_din; + end +end + +// Port B +always @(posedge b_clk) begin + b_dout <= mem[b_addr]; + if(b_wr) begin + b_dout <= b_din; + mem[b_addr] <= b_din; + end +end + +endmodule + +// A 16Kbyte RAM (4096x32) with one write port and one read port +module ram16k0( + input wire clk, + + input wire[15:0] a_addr, + output wire[31:0] a_q, + input wire[31:0] a_d, + input wire a_wr, + + input wire[12:0] b_addr, + output wire[15:0] b_q); + + //synthesis attribute ram_style of mem is block + reg [31:0] mem[0:4095]; //pragma attribute mem ram_block TRUE + initial begin + $readmemh("../build/firmware/demo0.hex", mem); + end + + always @ (posedge clk) + if (a_wr) + mem[a_addr[13:2]] <= a_d; + + reg [15:0] a_addr_; + always @ (posedge clk) + a_addr_ <= a_addr; + assign a_q = mem[a_addr_[13:2]]; + + reg [12:0] raddr_reg; + always @ (posedge clk) + raddr_reg <= b_addr; + wire [31:0] insn32 = mem[raddr_reg[12:1]]; + assign b_q = raddr_reg[0] ? insn32[31:16] : insn32[15:0]; +endmodule + +module ram16k( + input wire clk, + + input wire[15:0] a_addr, + output wire[31:0] a_q, + input wire[31:0] a_d, + input wire a_wr, + + input wire[12:0] b_addr, + output wire[15:0] b_q); + + wire [31:0] insn32; + + bram_tdp #(.DATA(32), .ADDR(12)) nram ( + .a_clk(clk), + .a_wr(a_wr), + .a_addr(a_addr[13:2]), + .a_din(a_d), + .a_dout(a_q), + + .b_clk(clk), + .b_wr(1'b0), + .b_addr(b_addr[12:1]), + .b_din(32'd0), + .b_dout(insn32)); + + reg ba_; + always @(posedge clk) + ba_ <= b_addr[0]; + assign b_q = ba_ ? insn32[31:16] : insn32[15:0]; + +endmodule + + +module top( + input wire CLK, + output wire DUO_LED, + input wire DUO_SW1, + input wire RXD, + output wire TXD, + input wire DTR + ); + localparam MHZ = 40; + + wire fclk; + + DCM_CLKGEN #( + .CLKFX_MD_MAX(0.0), // Specify maximum M/D ratio for timing anlysis + .CLKFX_DIVIDE(32), // Divide value - D - (1-256) + .CLKFX_MULTIPLY(MHZ), // Multiply value - M - (2-256) + .CLKIN_PERIOD(31.25), // Input clock period specified in nS + .STARTUP_WAIT("FALSE") // Delay config DONE until DCM_CLKGEN LOCKED (TRUE/FALSE) + ) + DCM_CLKGEN_inst ( + .CLKFX(fclk), // 1-bit output: Generated clock output + .CLKIN(CLK), // 1-bit input: Input clock + .FREEZEDCM(0), // 1-bit input: Prevents frequency adjustments to input clock + .PROGCLK(0), // 1-bit input: Clock input for M/D reconfiguration + .PROGDATA(0), // 1-bit input: Serial data input for M/D reconfiguration + .PROGEN(0), // 1-bit input: Active high program enable + .RST(0) // 1-bit input: Reset input pin + ); + + reg [25:0] counter; + always @(posedge fclk) + counter <= counter + 26'd1; + assign DUO_LED = counter[25]; + + // ------------------------------------------------------------------------ + + wire uart0_valid, uart0_busy; + wire [7:0] uart0_data; + wire uart0_rd, uart0_wr; + reg [31:0] baud = 32'd115200; + wire UART0_RX; + buart #(.CLKFREQ(MHZ * 1000000)) _uart0 ( + .clk(fclk), + .resetq(1'b1), + .baud(baud), + .rx(RXD), + .tx(TXD), + .rd(uart0_rd), + .wr(uart0_wr), + .valid(uart0_valid), + .busy(uart0_busy), + .tx_data(dout_[7:0]), + .rx_data(uart0_data)); + + wire [15:0] mem_addr; + wire [31:0] mem_din; + wire mem_wr; + wire [31:0] dout; + + wire [12:0] code_addr; + wire [15:0] insn; + + wire io_wr; + + wire resetq = DTR; + + j1 _j1 ( + .clk(fclk), + .resetq(resetq), + + .io_wr(io_wr), + .mem_addr(mem_addr), + .mem_wr(mem_wr), + .mem_din(mem_din), + .dout(dout), + .io_din({16'd0, uart0_data, 4'd0, DTR, uart0_valid, uart0_busy, DUO_SW1}), + + .code_addr(code_addr), + .insn(insn) + ); + + ram16k ram(.clk(fclk), + .a_addr(mem_addr), + .a_q(mem_din), + .a_wr(mem_wr), + .a_d(dout), + .b_addr(code_addr), + .b_q(insn)); + + reg io_wr_; + reg [15:0] mem_addr_; + reg [31:0] dout_; + always @(posedge fclk) + {io_wr_, mem_addr_, dout_} <= {io_wr, mem_addr, dout}; + + assign uart0_wr = io_wr_ & (mem_addr_ == 16'h0000); + assign uart0_rd = io_wr_ & (mem_addr_ == 16'h0002); + +endmodule diff --git a/docs/j1/xilinx/.gitignore b/docs/j1/xilinx/.gitignore new file mode 100644 index 0000000..e138931 --- /dev/null +++ b/docs/j1/xilinx/.gitignore @@ -0,0 +1,44 @@ +*.bgn +*.bit +*_bitgen.xwbt +*.bld +*.cfi +*.drc +*.map +*.mcs +*.mrp +*.ncd +*.ngc +*.ngc_xst.xrpt +*.ngd +*_ngdbuild.xrpt +*.ngm +*_par.grf +*_par.ncd +*_par.pad +*_par_pad.csv +*_par_pad.txt +*_par.par +*_par.ptwx +*_par.unroutes +*_par.xpi +*.pcf +*.prj +*.prm +*.psr +*.scr +*.srp +*.xml +*.html +_impactbatch.log +netlist.lst +smartguide.ncd +top.lso +top_map.xrpt +top_par.xrpt +usage_statistics_webtalk.html +webtalk.log +xlnx_auto_0_xdb +_xmsgs +xst +unused/ diff --git a/docs/j1/xilinx/Makefile b/docs/j1/xilinx/Makefile new file mode 100644 index 0000000..481513b --- /dev/null +++ b/docs/j1/xilinx/Makefile @@ -0,0 +1,11 @@ +project = j1-papilioduo +vendor = xilinx +family = spartan3s +part = xc6slx9-2-tqg144 +# part = xc3s200an-4ftg256 +top_module = top +flashsize = 2048 + +vfiles = ../verilog/xilinx-top.v ../verilog/uart.v ../verilog/j1.v ../verilog/stack.v + +include xilinx.mk diff --git a/docs/j1/xilinx/go b/docs/j1/xilinx/go new file mode 100644 index 0000000..c527f4c --- /dev/null +++ b/docs/j1/xilinx/go @@ -0,0 +1,22 @@ +set -e +cd ../toolchain +sh go +cd ../xilinx + +$HOME/Downloads/DesignLab-1.0.5/tools/Papilio_Loader/programmer/linux32/papilio-prog -v -f j1-papilioduo.bit +python shell.py -h /dev/ttyUSB2 -i ../build/firmware/nuc.hex ; exit + +make clean +make +if false +then + cp ../build/firmware/nuc.hex ../build/firmware/nuc.mem + data2mem -bm j1-papilioduo_bd.bmm -bd ../build/firmware/nuc.mem -bt j1-papilioduo.bit + trce -v 10 j1-papilioduo.ncd j1-papilioduo.pcf -o j1-papilioduo.twr + DL=j1-papilioduo_rp.bit +else + DL=j1-papilioduo.bit +fi +$HOME/Downloads/DesignLab-1.0.5/tools/Papilio_Loader/programmer/linux32/papilio-prog -v -f $DL +python shell.py -h /dev/ttyUSB2 -i ../build/firmware/nuc.hex ; exit +# miniterm.py /dev/ttyUSB0 115200 diff --git a/docs/j1/xilinx/j1-papilioduo.bmm b/docs/j1/xilinx/j1-papilioduo.bmm new file mode 100644 index 0000000..3dea0be --- /dev/null +++ b/docs/j1/xilinx/j1-papilioduo.bmm @@ -0,0 +1,24 @@ +// BMM LOC annotation file. +// +// Release 14.6 - P.20131013, build 3.0.10 Apr 3, 2013 +// Copyright (c) 1995-2015 Xilinx, Inc. All rights reserved. + + +/////////////////////////////////////////////////////////////////////////////// +// +// Address space 'j1' 0x00000000:0x000007FF (2 KBytes). +// +/////////////////////////////////////////////////////////////////////////////// + +// ADDRESS_SPACE j1 RAMB16 [0xffff0000:0xffff3FFF] +// BUS_BLOCK +// ram/nram/Mram_mem7 RAMB16 [3:0] [0:4095]; +// ram/nram/Mram_mem6 RAMB16 [7:4] [0:4095]; +// ram/nram/Mram_mem5 RAMB16 [11:8] [0:4095]; +// ram/nram/Mram_mem4 RAMB16 [15:12] [0:4095]; +// ram/nram/Mram_mem3 RAMB16 [19:16] [0:4095]; +// ram/nram/Mram_mem2 RAMB16 [23:20] [0:4095]; +// ram/nram/Mram_mem1 RAMB16 [27:24] [0:4095]; +// ram/nram/Mram_mem0 RAMB16 [31:28] [0:4095]; +// END_BUS_BLOCK; +// END_ADDRESS_SPACE; diff --git a/docs/j1/xilinx/j1-papilioduo.ucf b/docs/j1/xilinx/j1-papilioduo.ucf new file mode 100644 index 0000000..e06e002 --- /dev/null +++ b/docs/j1/xilinx/j1-papilioduo.ucf @@ -0,0 +1,183 @@ +# UCF file for the Papilio DUO board +# Generated by pin_converter, written by Kevin Lindsey +# https://github.com/thelonious/papilio_pins/tree/development/pin_converter + +# Main board wing pin [] to FPGA pin Pxx map +# -------C------- -------B------- -------A------- +# [GND] [C00] P114 [GND] [B00] P99 P100 [A15] +# [2V5] [C01] P115 [2V5] [B01] P97 P98 [A14] +# [3V3] [C02] P116 [3V3] [B02] P92 P93 [A13] +# [5V0] [C03] P117 [5V0] [B03] P87 P88 [A12] +# [C04] P118 [B04] P84 P85 [A11] [5V0] +# [C05] P119 [B05] P82 P83 [A10] [3V3] +# [C06] P120 [B06] P80 P81 [A09] [2V5] +# [C07] P121 [B07] P78 P79 [A08] [GND] +# [GND] [C08] P123 [GND] [B08] P74 P75 [A07] +# [2V5] [C09] P124 [2V5] [B09] P95 P67 [A06] +# [3V3] [C10] P126 [3V3] [B10] P62 P66 [A05] +# [5V0] [C11] P127 [5V0] [B11] P59 P61 [A04] +# [C12] P131 [B12] P57 P58 [A03] [5V0] +# [C13] P132 [B13] P55 P56 [A02] [3V3] +# [C14] P133 [B14] P50 P51 [A01] [2V5] +# [C15] P134 [B15] P47 P48 [A00] [GND] + +## Prohibit the automatic placement of pins that are connected to VCC or GND for configuration. +CONFIG PROHIBIT=P144; +CONFIG PROHIBIT=P69; +CONFIG PROHIBIT=P60; + +#NET "*" IOSTANDARD = LVTTL; + +NET CLK LOC="P94" | IOSTANDARD=LVTTL; # CLK +TIMESPEC TS_Period_1 = PERIOD "CLK" 31.25 ns HIGH 50%; +NET TXD LOC="P141" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; +NET RXD LOC="P46" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; +NET DTR LOC="P137" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; + +// NET "fclk" PERIOD = 6 ns HIGH 50%; + +# +# NET Arduino_0 LOC="P116" | IOSTANDARD=LVTTL; # A0 +# NET Arduino_1 LOC="P117" | IOSTANDARD=LVTTL; # A1 +# NET Arduino_2 LOC="P118" | IOSTANDARD=LVTTL; # A2 +# NET Arduino_3 LOC="P119" | IOSTANDARD=LVTTL; # A3 +# NET Arduino_4 LOC="P120" | IOSTANDARD=LVTTL; # A4 +# NET Arduino_5 LOC="P121" | IOSTANDARD=LVTTL; # A5 +# NET Arduino_6 LOC="P123" | IOSTANDARD=LVTTL; # A6 +# NET Arduino_7 LOC="P124" | IOSTANDARD=LVTTL; # A7 +# NET Arduino_8 LOC="P126" | IOSTANDARD=LVTTL; # A8 +# NET Arduino_9 LOC="P127" | IOSTANDARD=LVTTL; # A9 +# NET Arduino_10 LOC="P131" | IOSTANDARD=LVTTL; # A10 +# NET Arduino_11 LOC="P132" | IOSTANDARD=LVTTL; # A11 +# NET Arduino_12 LOC="P133" | IOSTANDARD=LVTTL; # A12 +# NET Arduino_13 LOC="P134" | IOSTANDARD=LVTTL; # A13 +# +# NET Arduino_14 LOC="P115" | IOSTANDARD=LVTTL; # B0 +# NET Arduino_15 LOC="P114" | IOSTANDARD=LVTTL; # B1 +# NET Arduino_16 LOC="P112" | IOSTANDARD=LVTTL; # B2 +# NET Arduino_17 LOC="P111" | IOSTANDARD=LVTTL; # B3 +# NET Arduino_18 LOC="P105" | IOSTANDARD=LVTTL; # B4 +# NET Arduino_19 LOC="P102" | IOSTANDARD=LVTTL; # B5 +# NET Arduino_20 LOC="P101" | IOSTANDARD=LVTTL; # B6 +# NET Arduino_21 LOC="P100" | IOSTANDARD=LVTTL; # B7 +# +# NET Arduino_22 LOC="P99" | IOSTANDARD=LVTTL; # C0 +# NET Arduino_24 LOC="P97" | IOSTANDARD=LVTTL; # C1 +# NET Arduino_26 LOC="P93" | IOSTANDARD=LVTTL; # C2 +# NET Arduino_28 LOC="P88" | IOSTANDARD=LVTTL; # C3 +# NET Arduino_30 LOC="P85" | IOSTANDARD=LVTTL; # C4 +# NET Arduino_32 LOC="P83" | IOSTANDARD=LVTTL; # C5 +# NET Arduino_34 LOC="P81" | IOSTANDARD=LVTTL; # C6 +# NET Arduino_36 LOC="P79" | IOSTANDARD=LVTTL; # C7 +# NET Arduino_38 LOC="P75" | IOSTANDARD=LVTTL; # C8 +# NET Arduino_40 LOC="P67" | IOSTANDARD=LVTTL; # C9 +# NET Arduino_42 LOC="P62" | IOSTANDARD=LVTTL; # C10 +# NET Arduino_44 LOC="P59" | IOSTANDARD=LVTTL; # C11 +# NET Arduino_46 LOC="P57" | IOSTANDARD=LVTTL; # C12 +# NET Arduino_48 LOC="P55" | IOSTANDARD=LVTTL; # C13 +# NET Arduino_50 LOC="P50" | IOSTANDARD=LVTTL; # C14 +# NET Arduino_52 LOC="P47" | IOSTANDARD=LVTTL; # C15 +# +# NET Arduino_23 LOC="P98" | IOSTANDARD=LVTTL ; +# NET Arduino_25 LOC="P95" | IOSTANDARD=LVTTL ; +# NET Arduino_27 LOC="P92" | IOSTANDARD=LVTTL ; +# NET Arduino_29 LOC="P87" | IOSTANDARD=LVTTL ; +# NET Arduino_31 LOC="P84" | IOSTANDARD=LVTTL ; +# NET Arduino_33 LOC="P82" | IOSTANDARD=LVTTL ; +# NET Arduino_35 LOC="P80" | IOSTANDARD=LVTTL ; +# NET Arduino_37 LOC="P78" | IOSTANDARD=LVTTL ; +# NET Arduino_39 LOC="P74" | IOSTANDARD=LVTTL ; +# NET Arduino_41 LOC="P66" | IOSTANDARD=LVTTL ; +# NET Arduino_43 LOC="P61" | IOSTANDARD=LVTTL ; +# NET Arduino_45 LOC="P58" | IOSTANDARD=LVTTL ; +# NET Arduino_47 LOC="P56" | IOSTANDARD=LVTTL ; +# NET Arduino_49 LOC="P51" | IOSTANDARD=LVTTL ; +# NET Arduino_51 LOC="P48" | IOSTANDARD=LVTTL ; +# NET Arduino_53 LOC="P39" | IOSTANDARD=LVTTL ; +# +# # SRAM +# +# NET "sram_addr<0>" LOC = "P7" | IOSTANDARD=LVTTL | SLEW=FAST; +# NET "sram_addr<1>" LOC = "P8" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<2>" LOC = "P9" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<3>" LOC = "P10" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<4>" LOC = "P11" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<5>" LOC = "P5" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<6>" LOC = "P2" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<7>" LOC = "P1" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<8>" LOC = "P143" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<9>" LOC = "P142" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<10>" LOC = "P43" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<11>" LOC = "P41" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<12>" LOC = "P40" | IOSTANDARD=LVTTL | SLEW=FAST; +# NET "sram_addr<13>" LOC = "P35" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<14>" LOC = "P34" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<15>" LOC = "P27" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<16>" LOC = "P29" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<17>" LOC = "P33" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_addr<18>" LOC = "P32" | IOSTANDARD=LVTTL | SLEW=FAST ; +# #NET "sram_addr<19>" LOC = "P44" | IOSTANDARD=LVTTL | SLEW=FAST ; +# #NET "sram_addr<20>" LOC = "P30" | IOSTANDARD=LVTTL | SLEW=FAST ; +# +# # Data lines +# NET "sram_data<0>" LOC = "P14" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_data<1>" LOC = "P15" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_data<2>" LOC = "P16" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_data<3>" LOC = "P17" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_data<4>" LOC = "P21" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_data<5>" LOC = "P22" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_data<6>" LOC = "P23" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_data<7>" LOC = "P24" | IOSTANDARD=LVTTL | SLEW=FAST ; +# +# # Control lines +# NET "sram_ce" LOC = "P12" | IOSTANDARD=LVTTL | SLEW=FAST; +# NET "sram_we" LOC = "P6" | IOSTANDARD=LVTTL | SLEW=FAST ; +# NET "sram_oe" LOC = "P26" | IOSTANDARD=LVTTL | SLEW=FAST; +# +# NET SPI_CS LOC="P38" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # FLASH_CS OK +# NET SPI_SCK LOC="P70" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # FLASH_CK OK +# NET SPI_MOSI LOC="P64" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # FLASH_SI OK +# NET SPI_MISO LOC="P65" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # FLASH_SO OK +# +# #Dragon MPSSE +# NET BD0_MPSSE_TCK LOC="P46" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET BD1_MPSSE_TDI LOC="P141" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET BD2_MPSSE_TDO LOC="P140" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET BD3_MPSSE_TMS LOC="P138" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET BD4_MPSSE_DTR LOC="P137" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# +# #Arduino JTAG +# NET ARD_JTAG_TDI LOC="P88" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET ARD_JTAG_TDO LOC="P85" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET ARD_JTAG_TMS LOC="P83" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET ARD_JTAG_TCK LOC="P81" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# +# #Arduino SPI +# NET ARD_SPI_MISO LOC="P133" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET ARD_SPI_MOSI LOC="P132" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET ARD_SPI_SCLK LOC="P134" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# +# #Dragon SPI +# NET DRAGON_SPI_GND LOC="P78" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET DRAGON_SPI_RESET LOC="P79" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# #NET DRAGON_SPI_RESET LOC="P79" | IOSTANDARD=LVTTL | DRIVE=8 | PULLUP | SLEW=SLOW; +# NET DRAGON_SPI_MOSI LOC="P74" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET DRAGON_SPI_SCK LOC="P75" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET DRAGON_SPI_VTG LOC="P66" | IOSTANDARD=LVTTL | DRIVE=24 | SLEW=SLOW; +# NET DRAGON_SPI_MISO LOC="P67" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# +# #Dragon JTAG +# NET DRAGON_JTAG_TCK LOC="P47" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET DRAGON_JTAG_GND LOC="P39" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET DRAGON_JTAG_TDO LOC="P50" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET DRAGON_JTAG_VTG LOC="P48" | IOSTANDARD=LVTTL | DRIVE=24 | SLEW=SLOW; +# NET DRAGON_JTAG_TMS LOC="P55" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET DRAGON_JTAG_RESET LOC="P51" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# #NET DRAGON_JTAG_RESET LOC="P51" | IOSTANDARD=LVTTL | DRIVE=8 | PULLUP | SLEW=SLOW; +# NET DRAGON_JTAG_TDI LOC="P59" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET DRAGON_JTAG_GND2 LOC="P58" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# +# #Dragon Misc +NET DUO_SW1 LOC="P104" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; +# NET ARD_RESET LOC="P139" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; # ARD_RESET +NET DUO_LED LOC="P134" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=SLOW; diff --git a/docs/j1/xilinx/shell.py b/docs/j1/xilinx/shell.py new file mode 100644 index 0000000..814e6a2 --- /dev/null +++ b/docs/j1/xilinx/shell.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python + +import sys +from datetime import datetime +import time +import array +import struct +import os + +try: + import serial +except: + print "This tool needs PySerial, but it was not found" + sys.exit(1) + +import swapforth as sf + +class TetheredJ1b(sf.TetheredFT900): + def __init__(self, port): + ser = serial.Serial(port, 115200, timeout=None, rtscts=0) + self.ser = ser + self.searchpath = ['.'] + self.log = open("log", "w") + + def boot(self, bootfile = None): + ser = self.ser + ser.setDTR(1) + ser.setDTR(0) + boot = array.array('I', [int(l, 16) for l in open(bootfile)]) + boot = boot[:0x3f80 / 4] # remove bootloader itself (top 128 bytes) + while boot[-1] == 0: # remove any unused words + boot = boot[:-1] + boot = boot.tostring() + ser.write(chr(27)) + print 'wrote 27' + # print repr(ser.read(1)) + + ser.write(struct.pack('I', len(boot))) + ser.write(boot) + print 'completed load of %d bytes' % len(boot) + # print repr(ser.read(1)) + +if __name__ == '__main__': + port = '/dev/ttyUSB0' + image = None + + r = None + + args = sys.argv[1:] + while args: + a = args[0] + if a.startswith('-i'): + image = args[1] + args = args[2:] + elif a.startswith('-h'): + port = args[1] + args = args[2:] + else: + if not r: + r = TetheredJ1b(port) + r.boot(image) + if a.startswith('-e'): + print r.shellcmd(args[1]) + args = args[2:] + else: + try: + r.include(a) + except sf.Bye: + pass + args = args[1:] + if not r: + r = TetheredJ1b(port) + r.boot(image) + + print repr(r.ser.read(1)) + # r.interactive_command(None) + r.shell(False) + # r.listen() diff --git a/docs/j1/xilinx/xilinx.mk b/docs/j1/xilinx/xilinx.mk new file mode 100644 index 0000000..f71dede --- /dev/null +++ b/docs/j1/xilinx/xilinx.mk @@ -0,0 +1,176 @@ +# The top level module should define the variables below then include +# this file. The files listed should be in the same directory as the +# Makefile. +# +# variable description +# ---------- ------------- +# project project name (top level module should match this name) +# top_module top level module of the project +# libdir path to library directory +# libs library modules used +# vfiles all local .v files +# xilinx_cores all local .xco files +# vendor vendor of FPGA (xilinx, altera, etc.) +# family FPGA device family (spartan3e) +# part FPGA part name (xc4vfx12-10-sf363) +# flashsize size of flash for mcs file (16384) +# optfile (optional) xst extra opttions file to put in .scr +# map_opts (optional) options to give to map +# par_opts (optional) options to give to par +# intstyle (optional) intstyle option to all tools +# +# files description +# ---------- ------------ +# $(project).ucf ucf file +# +# Library modules should have a modules.mk in their root directory, +# namely $(libdir)//module.mk, that simply adds to the vfiles +# and xilinx_cores variable. +# +# all the .xco files listed in xilinx_cores will be generated with core, with +# the resulting .v and .ngc files placed back in the same directory as +# the .xco file. +# +# TODO: .xco files are device dependant, should use a template based system + +coregen_work_dir ?= ./coregen-tmp +map_opts ?= -timing -ol high -detail -pr b -register_duplication -w +par_opts ?= -ol high +isedir ?= /data/Xilinx/14.7/ISE_DS +xil_env ?= . $(isedir)/settings64.sh +flashsize ?= 8192 + +libmks = $(patsubst %,$(libdir)/%/module.mk,$(libs)) +mkfiles = Makefile $(libmks) xilinx.mk +include $(libmks) + +corengcs = $(foreach core,$(xilinx_cores),$(core:.xco=.ngc)) +local_corengcs = $(foreach ngc,$(corengcs),$(notdir $(ngc))) +vfiles += $(foreach core,$(xilinx_cores),$(core:.xco=.v)) +junk += $(local_corengcs) + +.PHONY: default xilinx_cores clean twr etwr +default: $(project).bit $(project).mcs +xilinx_cores: $(corengcs) +twr: $(project).twr +etwr: $(project)_err.twr + +define cp_template +$(2): $(1) + cp $(1) $(2) +endef +$(foreach ngc,$(corengcs),$(eval $(call cp_template,$(ngc),$(notdir $(ngc))))) + +%.ngc %.v: %.xco + @echo "=== rebuilding $@" + if [ -d $(coregen_work_dir) ]; then \ + rm -rf $(coregen_work_dir)/*; \ + else \ + mkdir -p $(coregen_work_dir); \ + fi + cd $(coregen_work_dir); \ + $(xil_env); \ + coregen -b $$OLDPWD/$<; \ + cd - + xcodir=`dirname $<`; \ + basename=`basename $< .xco`; \ + if [ ! -r $(coregen_work_dir/$$basename.ngc) ]; then \ + echo "'$@' wasn't created."; \ + exit 1; \ + else \ + cp $(coregen_work_dir)/$$basename.v $(coregen_work_dir)/$$basename.ngc $$xcodir; \ + fi +junk += $(coregen_work_dir) + +date = $(shell date +%F-%H-%M) + +# some common junk +junk += *.xrpt + +programming_files: $(project).bit $(project).mcs + mkdir -p $@/$(date) + mkdir -p $@/latest + for x in .bit .mcs .cfi _bd.bmm; do cp $(project)$$x $@/$(date)/$(project)$$x; cp $(project)$$x $@/latest/$(project)$$x; done + $(xil_env); xst -help | head -1 | sed 's/^/#/' | cat - $(project).scr > $@/$(date)/$(project).scr + +$(project).mcs: $(project).bit + $(xil_env); \ + promgen -w -s $(flashsize) -p mcs -o $@ -u 0 $^ +junk += $(project).mcs $(project).cfi $(project).prm + +$(project).bit: $(project)_par.ncd + $(xil_env); \ + bitgen $(intstyle) -g UserID:0x09470947 -g DriveDone:yes -g StartupClk:Cclk -w $(project)_par.ncd $(project).bit + # bitgen $(intstyle) -g compress -g UserID:0x09470947 -g DriveDone:yes -g StartupClk:Cclk -w $(project)_par.ncd $(project).bit + # bitgen $(intstyle) -g UserID:0x09470947 -g DriveDone:yes -g StartupClk:Cclk -w $(project)_par.ncd $(project).bit +junk += $(project).bgn $(project).bit $(project).drc $(project)_bd.bmm + + +$(project)_par.ncd: $(project).ncd + $(xil_env); \ + if par $(intstyle) $(par_opts) -w $(project).ncd $(project)_par.ncd; then \ + :; \ + else \ + $(MAKE) etwr; \ + fi +junk += $(project)_par.ncd $(project)_par.par $(project)_par.pad +junk += $(project)_par_pad.csv $(project)_par_pad.txt +junk += $(project)_par.grf $(project)_par.ptwx +junk += $(project)_par.unroutes $(project)_par.xpi + +$(project).ncd: $(project).ngd + if [ -r $(project)_par.ncd ]; then \ + cp $(project)_par.ncd smartguide.ncd; \ + smartguide="-smartguide smartguide.ncd"; \ + else \ + smartguide=""; \ + fi; \ + $(xil_env); \ + map $(intstyle) $(map_opts) $$smartguide $< +junk += $(project).ncd $(project).pcf $(project).ngm $(project).mrp $(project).map +junk += smartguide.ncd $(project).psr +junk += $(project)_summary.xml $(project)_usage.xml + +$(project).ngd: $(project).ngc $(project).ucf $(project).bmm + $(xil_env); ngdbuild $(intstyle) $(project).ngc -bm $(project).bmm +junk += $(project).ngd $(project).bld + +$(project).ngc: $(vfiles) $(local_corengcs) $(project).scr $(project).prj + $(xil_env); xst $(intstyle) -ifn $(project).scr +junk += xlnx_auto* $(top_module).lso $(project).srp +junk += netlist.lst xst $(project).ngc + +$(project).prj: $(vfiles) $(mkfiles) + for src in $(vfiles); do echo "verilog work $$src" >> $(project).tmpprj; done + sort -u $(project).tmpprj > $(project).prj + rm -f $(project).tmpprj +junk += $(project).prj + +optfile += $(wildcard $(project).opt) +top_module ?= $(project) +$(project).scr: $(optfile) $(mkfiles) ./xilinx.opt + echo "run" > $@ + echo "-p $(part)" >> $@ + echo "-top $(top_module)" >> $@ + echo "-ifn $(project).prj" >> $@ + echo "-ofn $(project).ngc" >> $@ + cat ./xilinx.opt $(optfile) >> $@ +junk += $(project).scr + +$(project).post_map.twr: $(project).ncd + $(xil_env); trce -e 10 $< $(project).pcf -o $@ +junk += $(project).post_map.twr $(project).post_map.twx smartpreview.twr + +$(project).twr: $(project)_par.ncd + $(xil_env); trce $< $(project).pcf -o $(project).twr +junk += $(project).twr $(project).twx smartpreview.twr + +$(project)_err.twr: $(project)_par.ncd + $(xil_env); trce -e 10 $< $(project).pcf -o $(project)_err.twr +junk += $(project)_err.twr $(project)_err.twx + +.gitignore: $(mkfiles) + echo programming_files $(junk) | sed 's, ,\n,g' > .gitignore + +clean:: + rm -rf $(junk) diff --git a/docs/j1/xilinx/xilinx.opt b/docs/j1/xilinx/xilinx.opt new file mode 100644 index 0000000..c9e5ab7 --- /dev/null +++ b/docs/j1/xilinx/xilinx.opt @@ -0,0 +1,42 @@ +-ifmt mixed +-ofmt NGC +-opt_mode speed +-opt_level 1 +-iuc NO +-keep_hierarchy no +-netlist_hierarchy as_optimized +-rtlview no +-glob_opt AllClockNets +-read_cores yes +-write_timing_constraints NO +-cross_clock_analysis NO +-hierarchy_separator / +-bus_delimiter <> +-case maintain +-slice_utilization_ratio 100 +-bram_utilization_ratio 100 +#-dsp_utilization_ratio 100 +-safe_implementation No +-fsm_extract YES +-fsm_encoding Auto +-fsm_style lut +-ram_extract Yes +-ram_style Auto +-rom_extract Yes +-rom_style Auto +-shreg_extract YES +-auto_bram_packing NO +-resource_sharing NO +-async_to_sync NO +#-use_dsp48 auto +-iobuf YES +-max_fanout 500 +-register_duplication YES +-register_balancing No +-optimize_primitives NO +-use_clock_enable Auto +-use_sync_set Auto +-use_sync_reset Auto +-iob auto +-equivalent_register_removal YES +-slice_utilization_ratio_maxmargin 5 -- cgit v1.2.3