├── src ├── drv │ ├── freega.h │ ├── Makefile │ ├── dump.c │ ├── peek.c │ ├── poke.c │ ├── pokeb.c │ ├── newtest.c │ └── set.c ├── Makefile ├── assembler │ ├── Mmakefile │ ├── xml.m │ ├── asm_out.m │ ├── assemble.m │ └── prettyprint.m ├── fw_risc16 │ └── Makefile ├── fw_tta16 │ ├── Makefile │ └── prepro.m4 └── r16asm │ ├── test.S │ └── CodeCleaner.py ├── data ├── font.bmp └── vgabios-0.4c │ ├── VGABIOS-lgpl-latest.bin │ ├── VGABIOS-lgpl-latest.debug.bin │ ├── tests │ └── lfbprof │ │ └── Makefile │ ├── BUGS │ ├── Notes │ ├── dataseghack │ ├── vgabios.h │ ├── TODO │ └── Makefile ├── doc └── openvga.pdf ├── Makefile ├── sim ├── cpu │ ├── risc16 │ │ ├── hwtb_risc_tb.v │ │ ├── risc16_tb.v │ │ ├── risc16_tile_tb.v │ │ └── risc_mem_wb.v │ ├── tta16 │ │ ├── hwtb_tta_tb.v │ │ ├── tta16_tb.v │ │ └── tta16_tile_tb.v │ └── fastbits_tb.v ├── lib │ ├── clock │ │ └── clkdiv_tb.v │ ├── mfsr │ │ ├── mfsr10_tb.v │ │ └── mfsr9_tb.v │ ├── mux │ │ ├── mux8to1_tb.v │ │ └── mux4to1_tb.v │ ├── counter │ │ ├── bin2gray_tb.v │ │ └── fib │ │ │ └── fib20_tb.v │ ├── fifo │ │ ├── sync │ │ │ └── sfifo2k_tb.v │ │ └── async │ │ │ ├── afifo2k_tb.v │ │ │ └── afifo16_tb.v │ ├── pre_read_tb.v │ ├── wb_bram_tb.v │ ├── wb_leds_tb.v │ ├── wb_serial_port_tb.v │ └── wb_sync_tb.v ├── xilinx │ ├── DCM_tb.v │ ├── OBUFT_tb.v │ ├── RAM16X1D_tb.v │ ├── RAM32M_tb.v │ ├── IFDDRRSE_tb.v │ ├── OFDDRRSE_tb.v │ ├── RAMB16_S9_S9_testbench.v │ ├── RAMB36SDP_tb.v │ ├── RAMB16_S1_S36_testbench.v │ ├── XORCY.v │ ├── BUFG.v │ ├── MUXF5.v │ ├── IBUF.v │ ├── MUXCY.v │ ├── LUT3.v │ ├── LUT4.v │ ├── BUFGMUX.v │ ├── FD.v │ ├── OBUF.v │ ├── FDE.v │ ├── FDR.v │ ├── RAMB16_S9_S36_testbench.v │ ├── OBUFT.v │ ├── FDRSE.v │ ├── MULT18X18S.v │ ├── FDCE.v │ ├── LUT6.v │ ├── RAM16X1S.v │ ├── MUXF7.v │ ├── OFDDRTRSE.v │ ├── IFDDRRSE.v │ ├── OFDDRRSE.v │ ├── FDDRRSE.v │ └── RAM16X1D.v ├── mem │ ├── rfc_tb.v │ └── wb_sdram_ctrl_tb.v ├── video │ └── crtc_tb.v ├── pci │ ├── cfgspace_tb.v │ └── wb_pci_top_tb.v └── Makefile ├── docker-compose.yml ├── Dockerfile ├── rtl ├── video │ ├── crtc_tb.v │ ├── video_tb.v │ └── vga16.v ├── cpu │ ├── risc16 │ │ ├── defines.v │ │ ├── risc_rf.v │ │ ├── risc_mem_wb.v │ │ └── branch.v │ └── fastbits.v ├── lib │ ├── mfsr │ │ ├── mfsr11.v │ │ ├── mfsr7.v │ │ ├── mfsr9.v │ │ ├── mfsr10.v │ │ └── mfsr8.v │ ├── clock │ │ └── clkdiv.v │ ├── mux │ │ ├── mux4to1.v │ │ └── mux8to1.v │ ├── counter │ │ ├── fib │ │ │ └── fib20.v │ │ └── bin2gray.v │ └── wb_leds.v ├── cache │ ├── cache_bram.v │ └── wb_cache_flush.v └── mem │ └── rfc.v ├── README.md └── tools ├── out2v.py └── bmp2font.py /src/drv/freega.h: -------------------------------------------------------------------------------- 1 | #ifndef FREEGA_H_ 2 | #define FREEGA_H_ 3 | 4 | #endif 5 | -------------------------------------------------------------------------------- /data/font.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elec-otago/openvga/HEAD/data/font.bmp -------------------------------------------------------------------------------- /doc/openvga.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elec-otago/openvga/HEAD/doc/openvga.pdf -------------------------------------------------------------------------------- /data/vgabios-0.4c/VGABIOS-lgpl-latest.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elec-otago/openvga/HEAD/data/vgabios-0.4c/VGABIOS-lgpl-latest.bin -------------------------------------------------------------------------------- /data/vgabios-0.4c/VGABIOS-lgpl-latest.debug.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elec-otago/openvga/HEAD/data/vgabios-0.4c/VGABIOS-lgpl-latest.debug.bin -------------------------------------------------------------------------------- /data/vgabios-0.4c/tests/lfbprof/Makefile: -------------------------------------------------------------------------------- 1 | # Very simple makefile for LFBPROF.C using Watcom C++ 10.0a with DOS4GW 2 | 3 | lfbprof.exe: lfbprof.c lfbprof.h 4 | wcl386 -zq -s -d2 lfbprof.c 5 | 6 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS = fw_tta16 fw_risc16 drv 2 | 3 | all: 4 | for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) all); done 5 | 6 | clean: 7 | for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) clean); done 8 | -------------------------------------------------------------------------------- /src/assembler/Mmakefile: -------------------------------------------------------------------------------- 1 | MAIN_TARGET=assemble 2 | GRADE=hlc.gc 3 | 4 | # Static linking 5 | # EXTRA_MLFLAGS = --dynamic 6 | # --mercury-libs static 7 | 8 | depend: assemble.depend 9 | 10 | default_target: assemble 11 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS = src rtl sim 2 | 3 | all: 4 | for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) all); done 5 | 6 | icarus: 7 | cd sim && make icarus 8 | 9 | clean: 10 | for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) clean); done 11 | -------------------------------------------------------------------------------- /data/vgabios-0.4c/BUGS: -------------------------------------------------------------------------------- 1 | The code is quite new, and testing has been very minimal. 2 | Not all the functions have been implemented yet. 3 | 4 | From an implemented point of view, these should be working but do not : 5 | - 43/50 lines switching 6 | - cursor shape seems broken (volker) 7 | 8 | 9 | Please report any bugs to 10 | -------------------------------------------------------------------------------- /src/assembler/xml.m: -------------------------------------------------------------------------------- 1 | :- module xml. 2 | :- interface. 3 | :- import_module string, list, pair. 4 | 5 | :- type xml_t ---> xml(prolog,element). 6 | 7 | :- type prolog ---> empty. 8 | 9 | :- type element ---> e(tag,list(content)). 10 | 11 | :- type content ---> c(string) ; e(element). 12 | 13 | :- type tag ---> t(string,list(pair(string,string))). 14 | -------------------------------------------------------------------------------- /data/vgabios-0.4c/Notes: -------------------------------------------------------------------------------- 1 | Development notes 2 | ----------------- 3 | 4 | - need to split video init function 5 | 1. set bios variables 6 | 2. do the real init with io based on bios variables 7 | 8 | - characters format switching will set the bios 9 | variables and call function #2 above 10 | 11 | - need to rework the tables as explained in Interrupt list 12 | -------------------------------------------------------------------------------- /src/fw_risc16/Makefile: -------------------------------------------------------------------------------- 1 | ASM_FILE=main 2 | OUT2V=../../tools/out2v.py 3 | ASSEM=../r16asm/r16asm.py 4 | 5 | all: assemble 6 | cp *.v ../../rtl/cpu/risc16/ 7 | 8 | %.s: %.S 9 | m4 $< > $*.s 10 | 11 | assemble: $(ASM_FILE).s 12 | ${ASSEM} $(ASM_FILE).s 13 | ${OUT2V} -n 1 -s 0 $(ASM_FILE).out risc_asm.v 14 | 15 | clean: 16 | rm -f $(ASM_FILE).out $(ASM_FILE).s risc_asm.v 17 | -------------------------------------------------------------------------------- /src/fw_tta16/Makefile: -------------------------------------------------------------------------------- 1 | ASM_FILE=main 2 | OUT2V=../../tools/out2v.py 3 | ASSEM=../../bin/assemble 4 | 5 | all: assemble 6 | cp *.v ../../rtl/cpu/tta16/ 7 | 8 | %.s: %.S 9 | m4 $< > $*.s 10 | 11 | assemble: $(ASM_FILE).s 12 | $(ASSEM) $(ASM_FILE).s 13 | $(OUT2V) -n 2 -s 0 $(ASM_FILE).out tta_asm0.v 14 | $(OUT2V) -n 2 -s 1 $(ASM_FILE).out tta_asm1.v 15 | 16 | clean: 17 | rm -f $(ASM_FILE).out $(ASM_FILE).s tta_asm0.v tta_asm1.v 18 | -------------------------------------------------------------------------------- /sim/cpu/risc16/hwtb_risc_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module hwtb_risc_tb; 3 | 4 | reg clk50 = 1; 5 | reg rst_n = 1; 6 | wire [1:0] leds; 7 | 8 | always #10 clk50 <= ~clk50; 9 | 10 | initial begin : Sim 11 | $dumpfile ("tb.vcd"); 12 | $dumpvars; 13 | 14 | #2 rst_n = 0; 15 | #40 rst_n = 1; 16 | 17 | #5000 $finish; 18 | end // Sim 19 | 20 | hwtb_risc TB0 ( 21 | .clk50 (clk50), 22 | .pci_rst_n (rst_n), 23 | .leds (leds) 24 | ); 25 | 26 | 27 | endmodule // hwtb_tta_tb 28 | -------------------------------------------------------------------------------- /sim/cpu/tta16/hwtb_tta_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module hwtb_tta_tb; 3 | 4 | reg clk50 = 1; 5 | reg rst_n = 1; 6 | wire [1:0] leds; 7 | 8 | always #10 clk50 <= ~clk50; 9 | 10 | initial begin : Sim 11 | $dumpfile ("tb.vcd"); 12 | $dumpvars; 13 | 14 | #2 rst_n = 0; 15 | #40 rst_n = 1; 16 | 17 | #5000 $finish; 18 | end // Sim 19 | 20 | hwtb_tta TB0 ( 21 | .clk50 (clk50), 22 | .pci_rst_n (rst_n), 23 | .leds (leds) 24 | ); 25 | 26 | 27 | endmodule // hwtb_tta_tb 28 | -------------------------------------------------------------------------------- /sim/lib/clock/clkdiv_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module clkdiv_tb; 3 | 4 | reg clock = 1; 5 | always #5 clock <= ~clock; 6 | 7 | reg reset = 0; 8 | 9 | wire sclk; 10 | 11 | initial begin : Sim 12 | $write ("%% "); 13 | $dumpfile ("tb.vcd"); 14 | $dumpvars; 15 | 16 | #2 reset = 1; 17 | #20 reset = 0; 18 | 19 | #800 $finish; 20 | end // Sim 21 | 22 | clkdiv CLKDIV0 ( 23 | .clk_i (clock), 24 | .rst_i (reset), 25 | .clk_o (sclk) 26 | ); 27 | 28 | endmodule // clkdiv_tb 29 | -------------------------------------------------------------------------------- /sim/lib/mfsr/mfsr10_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module mfsr10_tb; 3 | 4 | reg clk = 1; 5 | always #5 clk <= ~clk; 6 | 7 | reg [9:0] count = 1; 8 | wire [9:0] count_w; 9 | 10 | initial begin : Sim 11 | #1 $display("%d", count); 12 | #200 13 | $finish; 14 | end 15 | 16 | always @(posedge clk) 17 | count <= #2 count_w; 18 | 19 | always @(count_w) 20 | $display("%d", count_w); 21 | 22 | mfsr10 MFSR0 ( 23 | .count_i (count[9:0]), 24 | .count_o (count_w) 25 | ); 26 | 27 | endmodule // mfsr10_tb 28 | -------------------------------------------------------------------------------- /src/drv/Makefile: -------------------------------------------------------------------------------- 1 | obj-m = freega.o 2 | KVERSION = $(shell uname -r) 3 | all: 4 | make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules 5 | clean: 6 | rm -rf Module.markers modules.order 7 | make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean 8 | 9 | test: testfreega.c dump.c set.c peek.c poke.c newtest.c 10 | gcc -o test testfreega.c 11 | gcc -o new newtest.c 12 | gcc -o dump dump.c 13 | gcc -o set set.c 14 | gcc -o peek peek.c 15 | gcc -o poke poke.c 16 | 17 | testclean: 18 | rm -f test dump set peek poke new 19 | -------------------------------------------------------------------------------- /sim/cpu/fastbits_tb.v: -------------------------------------------------------------------------------- 1 | module fastbits_tb; 2 | 3 | parameter WIDTH = 16; 4 | parameter MSB = WIDTH - 1; 5 | 6 | reg [MSB:0] a = 0; 7 | reg [MSB:0] b = 0; 8 | reg [1:0] m = 0; 9 | wire [MSB:0] b_n; 10 | wire z; 11 | 12 | initial begin : Sim 13 | $dumpfile ("tb.vcd"); 14 | $dumpvars; 15 | 16 | #10 a = 1; 17 | #10 b = 1; 18 | #10 $finish; 19 | end // Sim 20 | 21 | fastbits #( 22 | .WIDTH (WIDTH) 23 | ) FB ( 24 | .a_i (a), 25 | .b_i (b), 26 | .m_i (m), 27 | .b_no (b_n), 28 | .z_o (z) 29 | ); 30 | 31 | endmodule // fastbits_tb 32 | -------------------------------------------------------------------------------- /sim/xilinx/DCM_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module DCM_tb; 3 | 4 | 5 | reg clk100 = 1; 6 | always #5 clk100 <= ~clk100; 7 | 8 | wire clock, locked, clock90, clock180, clock270, clock2x, clockdv; 9 | 10 | 11 | initial begin : Sim 12 | $write ("%% "); 13 | $dumpfile ("tb.vcd"); 14 | $dumpvars; 15 | 16 | #1000 17 | $finish; 18 | end // Sim 19 | 20 | 21 | DCM dcm0 ( 22 | .CLKIN (clk100), 23 | .CLKFB (clock), 24 | .CLK0 (clock), 25 | .CLK90 (clock90), 26 | .CLK180 (clock180), 27 | .CLK270 (clock270), 28 | .CLK2X (clock2x), 29 | .CLKDV (clockdv), 30 | .LOCKED (locked) 31 | ); 32 | 33 | 34 | endmodule // DCM_tb 35 | -------------------------------------------------------------------------------- /sim/xilinx/OBUFT_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module OBUFT_tb; 3 | 4 | reg clock = 1; 5 | always #5 clock <= ~clock; 6 | 7 | reg in = 0; 8 | wire out; 9 | reg en = 0; 10 | 11 | initial begin : Sim 12 | $display ("Time CLK EN IN OUT"); 13 | $monitor ("%5t %b %b %b %b ", $time, clock, en, in, out); 14 | 15 | #10 16 | en <= 1; 17 | 18 | #10 19 | in <= 1; 20 | 21 | #10 22 | in <= 0; 23 | 24 | #10 25 | in <= 1; 26 | 27 | #10 28 | en <= 0; 29 | 30 | #10 31 | $finish; 32 | end // Sim 33 | 34 | OBUFT obuf0 ( 35 | .I (in), 36 | .O (out), 37 | .T (en) 38 | ); 39 | 40 | endmodule // OBUFT_tb 41 | -------------------------------------------------------------------------------- /data/vgabios-0.4c/dataseghack: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | awk \ 4 | 'BEGIN { }\ 5 | /^\.text/,/DATA_SEG_DEFS_HERE/ { print }\ 6 | END { }'\ 7 | $1 > temp.awk.1 8 | 9 | awk \ 10 | 'BEGIN { i = 0; last = "hello" }\ 11 | /BLOCK_STRINGS_BEGIN/,/^\.bss/ { if ( i > 1 ) { print last } last = $0; i = i + 1 }\ 12 | END { }'\ 13 | $1 > temp.awk.2 14 | 15 | awk \ 16 | 'BEGIN { }\ 17 | /DATA_SEG_DEFS_HERE/,/BLOCK_STRINGS_BEGIN/ { print }\ 18 | END { }'\ 19 | $1 > temp.awk.3 20 | 21 | cp $1 $1.orig 22 | cat temp.awk.1 temp.awk.2 temp.awk.3 | sed -e 's/^\.data//' -e 's/^\.bss//' -e 's/^\.text//' > $1 23 | /bin/rm -f temp.awk.1 temp.awk.2 temp.awk.3 $1.orig 24 | -------------------------------------------------------------------------------- /sim/mem/rfc_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module rfc_tb; 3 | 4 | reg clk = 1; 5 | always #5 clk <= ~clk; 6 | 7 | reg rst = 0; 8 | 9 | reg en = 0; 10 | reg gnt = 0; 11 | 12 | wire req, rfc; 13 | 14 | initial begin : Sim 15 | $write ("%% "); 16 | $dumpfile ("tb.vcd"); 17 | $dumpvars; 18 | 19 | #2 rst = 1; 20 | #20 rst = 0; 21 | 22 | #10 en = 1; 23 | 24 | while (rfc) #10 ; 25 | gnt = 1; 26 | #10 gnt = 0; 27 | 28 | #800 $finish; 29 | end // Sim 30 | 31 | rfc #( 32 | .INIT (1), 33 | .RFC_TIMER (10), 34 | .TIMER_BITS (4), 35 | .tRFC (3) 36 | ) RFC0 ( 37 | .clk_i (clk), 38 | .rst_i (rst), 39 | .en_i (en), 40 | .req_o (req), 41 | .gnt_i (gnt), 42 | .rfc_o (rfc) 43 | ); 44 | 45 | endmodule // rfc_tb 46 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | # On the docker host 2 | # type 'xhost +', and then you can run this with 3 | # docker-compose run --rm openvga 4 | # Type casabrowser at the prompt, and you will find the measurement set in the /remote directory. 5 | version: '3.5' 6 | 7 | services: 8 | 9 | openvga: 10 | container_name: openvga 11 | build: 12 | context: . 13 | dockerfile: Dockerfile 14 | volumes: 15 | - '/home/tim/astro/:/remote' 16 | - ${XAUTHORITY}:/tmp/.Xauthority 17 | - /tmp/.X11-unix:/tmp/.X11-unix 18 | environment: 19 | - DISPLAY 20 | - XAUTHORITY=/tmp/.Xauthority 21 | - QT_X11_NO_MITSHM=1 22 | - LIBOVERLAY_SCROLLBAR=0 23 | - LANG=en_US.UTF-8 24 | - LANGUAGE=en_US:en 25 | - LC_ALL=en_US.UTF-8 26 | -------------------------------------------------------------------------------- /sim/lib/mux/mux8to1_tb.v: -------------------------------------------------------------------------------- 1 | module mux8to1_tb; 2 | 3 | reg clock = 1; 4 | always #5 clock <= ~clock; 5 | 6 | reg [2:0] sel = 0; 7 | wire [7:0] out; 8 | 9 | initial begin : Sim 10 | $display ("Time CLK sel out"); 11 | $monitor ("%5t %b %h %h ", $time, clock, sel, out); 12 | 13 | #5 14 | sel <= 1; 15 | 16 | #10 17 | sel <= 2; 18 | 19 | #10 20 | sel <= 7; 21 | 22 | #10 23 | sel <= 5; 24 | 25 | #20 26 | $finish; 27 | end // Sim 28 | 29 | defparam MUX0.WIDTH = 8; 30 | mux8to1 MUX0 ( 31 | .sel_i (sel), 32 | 33 | .data0_i(7), 34 | .data1_i(6), 35 | .data2_i(5), 36 | .data3_i(4), 37 | .data4_i(3), 38 | .data5_i(2), 39 | .data6_i(1), 40 | .data7_i(0), 41 | 42 | .data_o (out) 43 | ); 44 | 45 | endmodule // mux8to1_tb 46 | -------------------------------------------------------------------------------- /sim/lib/mfsr/mfsr9_tb.v: -------------------------------------------------------------------------------- 1 | module mfsr9_tb; 2 | 3 | reg clock = 1; 4 | always #5 clock <= ~clock; 5 | 6 | reg reset = 0; 7 | 8 | //reg [8:0] count; 9 | wire [8:0] count_w, count_i; 10 | 11 | integer count; 12 | initial begin : Sim 13 | $display ("Time CLK RST count countW countI"); 14 | $monitor ("%5t %b %b %d %d %d ", 15 | $time, clock, reset, 16 | count, count_w, count_i 17 | ); 18 | 19 | #5 20 | reset <= 1; 21 | 22 | #10 23 | reset <= 0; 24 | 25 | for (count=1; count<512; count=count+1) #10; 26 | 27 | #20 28 | $finish; 29 | end 30 | 31 | mfsr9 MFSR0 ( 32 | .count_i (count [8:0]), 33 | .count_o (count_w) 34 | ); 35 | 36 | imfsr9 MFSR1 ( 37 | .count_i (count_w), 38 | .count_o (count_i) 39 | ); 40 | 41 | endmodule // mfsr4_tb 42 | -------------------------------------------------------------------------------- /sim/lib/mux/mux4to1_tb.v: -------------------------------------------------------------------------------- 1 | module mux4to1_tb; 2 | 3 | reg clock = 1; 4 | always #5 clock <= ~clock; 5 | 6 | wire [7:0] a = 8'h45; 7 | wire [7:0] b = 8'h1a; 8 | wire [7:0] c = 8'h6d; 9 | wire [7:0] d = 8'h30; 10 | wire [7:0] out; 11 | 12 | reg [1:0] sel = 0; 13 | 14 | initial begin : Sim 15 | $display ("Time CLK a b c d sel out"); 16 | $monitor ("%5t %b %h %h %h %h %b %h", $time, clock, a, b, c, d, sel, out); 17 | 18 | #5 19 | sel <= 1; 20 | 21 | #10 22 | sel <= 2; 23 | 24 | #10 25 | sel <= 3; 26 | 27 | #10 28 | $finish; 29 | end // Sim 30 | 31 | mux4to1 #(8) MUX0 ( 32 | .select_i (sel), 33 | 34 | .input0_i (a), 35 | .input1_i (b), 36 | .input2_i (c), 37 | .input3_i (d), 38 | 39 | .output_o (out) 40 | ); 41 | 42 | endmodule // mux4to1_tb 43 | -------------------------------------------------------------------------------- /sim/lib/counter/bin2gray_tb.v: -------------------------------------------------------------------------------- 1 | `define WIDTH 5 2 | `define MSB (`WIDTH-1) 3 | module bin2gray_tb; 4 | 5 | reg clock = 1; 6 | always #5 clock <= ~clock; 7 | 8 | reg reset = 0; 9 | reg [`MSB:0] count_b = 0; 10 | wire [`MSB:0] count_g; 11 | 12 | 13 | always @(posedge clock) 14 | if (reset) count_b <= 0; 15 | else count_b <= count_b + 1; 16 | 17 | 18 | initial begin : Sim 19 | $display ("%t: Count = %d, Gray = %b", $time, count_b, count_g); 20 | $monitor ("%t: Count = %d, Gray = %b", $time, count_b, count_g); 21 | 22 | #2 23 | reset <= 1; 24 | 25 | #10 26 | reset <= 0; 27 | 28 | #600 29 | $finish; 30 | end // Sim 31 | 32 | 33 | bin2gray #( 34 | .WIDTH (`WIDTH) 35 | ) B2G0 ( 36 | .bin_i (count_b), 37 | .gray_o (count_g) 38 | ); 39 | 40 | endmodule // bin2gray_tb 41 | -------------------------------------------------------------------------------- /sim/lib/counter/fib/fib20_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module fib20_tb; 3 | 4 | integer fibs [0:21]; 5 | 6 | reg clock = 1; 7 | always #5 clock <= ~clock; 8 | 9 | wire [19:0] next_n; 10 | reg [19:0] n = 0; 11 | 12 | always @(posedge clock) 13 | n <= next_n; 14 | 15 | initial #1000 $finish; 16 | 17 | always @* begin 18 | disp_fib (n); 19 | end 20 | 21 | fib20 FIB0 ( 22 | .count_i (n), 23 | .count_o (next_n) 24 | ); 25 | 26 | integer ii; 27 | initial begin 28 | fibs[0] = 0; 29 | fibs[1] = 1; 30 | for (ii=2; ii<22; ii=ii+1) begin 31 | fibs[ii] = fibs[ii-2] + fibs[ii-1]; 32 | end 33 | end 34 | 35 | task disp_fib; 36 | input [31:0] fib; 37 | integer jj, num; 38 | begin 39 | num = 0; 40 | for (jj=0; jj<20; jj=jj+1) 41 | begin 42 | num = num + ((((1<> jj) * fibs[jj+2]); 43 | end 44 | $display ("%d", num); 45 | end 46 | endtask 47 | 48 | endmodule // fib20_tb 49 | -------------------------------------------------------------------------------- /src/r16asm/test.S: -------------------------------------------------------------------------------- 1 | ; Just a demo RISC16 assembly file. 2 | CRTC_SEG: equ 0x40 3 | SPROM_SEG: equ 0x44 4 | LEDS_SEG: equ 0x48 5 | DMA_SEG: equ 0x50 6 | FLUSH_SEG: equ 0x58 7 | 8 | nop 9 | __reset_addr: xor r13, r13 ; Set ZR 10 | xor r12, r12 ; SS 11 | msr.s r13 ; Set SS 12 | subi r14, r13, 1 ; SP := 65535 13 | subi r15, r13, -1 ; LR := 1 (__reset_addr) 14 | 15 | i12 set_leds>>4 16 | brl r15, set_leds ; r15<-pc, pc<-immed 17 | 18 | i12 -end>>4 ; These two lines are the same as: 19 | subi r0, r13, -end ; lea r0, end 20 | sw [r2-0x4], r11 21 | i12 (CRTC_SEG>>4) 22 | orc r1, CRTC_SEG 23 | jz __reset_addr 24 | end: ret 25 | 26 | 27 | ;---------------------------------------------------------------------------- 28 | ; set_leds - The two LSBs of `r0' determines the LED outputs. 29 | set_leds: i12 -LEDS_SEG>>4 30 | subi r1, r13, -LEDS_SEG 31 | msr.d r1 32 | sw.d [r13], r0 33 | ret 34 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:buster-slim 2 | ARG DEBIAN_FRONTEND=noninteractive 3 | 4 | RUN apt-get update && apt-get install -y --no-install-recommends \ 5 | netbase wget ca-certificates gnupg \ 6 | build-essential iverilog 7 | 8 | WORKDIR /tmp 9 | 10 | RUN wget https://paul.bone.id.au/paul.asc && \ 11 | apt-key add paul.asc && \ 12 | echo "deb http://dl.mercurylang.org/deb/ buster main" > /etc/apt/sources.list.d/mercury.list && \ 13 | echo "deb-src http://dl.mercurylang.org/deb/ buster main" >> /etc/apt/sources.list.d/mercury.list && \ 14 | apt-get update && apt-get install -y mercury-recommended 15 | 16 | WORKDIR /openvga 17 | 18 | COPY tools /openvga/tools 19 | COPY src /openvga/src 20 | 21 | # Now try and build the mercury assembler (mercurylang.org) 22 | WORKDIR /openvga/src/assembler 23 | 24 | RUN mmc --make assemble 25 | 26 | ENV LANG en_US.UTF-8 27 | -------------------------------------------------------------------------------- /sim/xilinx/RAM16X1D_tb.v: -------------------------------------------------------------------------------- 1 | module RAM16X1D_tb; 2 | 3 | reg data = 0; 4 | wire data_0; 5 | wire data_1; 6 | reg we = 0; 7 | reg wclk = 1; 8 | reg [3:0] r_addr = 0; 9 | reg [3:0] w_addr = 0; 10 | 11 | 12 | always #5 wclk <= ~wclk; 13 | 14 | initial begin : Sim 15 | $display("Time WCLK D WE A DPRA SPO DPO"); 16 | $monitor("%5t %b %b %b %h %h %b %b", $time, wclk, data, 17 | we, w_addr, r_addr, data_0, data_1); 18 | 19 | #2 20 | we <= 1; 21 | data <= 1; 22 | 23 | #10 24 | w_addr <= w_addr + 1; 25 | data <= 1; 26 | 27 | #20 28 | $finish; 29 | end // Sim 30 | 31 | // 16-bits of RAM, WOW!! 32 | RAM16X1D ram0( 33 | .D(data), 34 | .WE(we), 35 | .WCLK(wclk), 36 | .A0(w_addr[0]), 37 | .A1(w_addr[1]), 38 | .A2(w_addr[2]), 39 | .A3(w_addr[3]), 40 | .DPRA0(r_addr[0]), 41 | .DPRA1(r_addr[1]), 42 | .DPRA2(r_addr[2]), 43 | .DPRA3(r_addr[3]), 44 | .SPO(data_0), 45 | .DPO(data_1) 46 | ); 47 | 48 | endmodule // RAM16X1D_tb 49 | -------------------------------------------------------------------------------- /sim/xilinx/RAM32M_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module RAM32M_tb; 3 | 4 | reg wclk = 1; 5 | always #5 wclk <= ~wclk; 6 | 7 | reg write = 0; 8 | reg [4:0] aa, ab, ac, ad; 9 | reg [1:0] da, db, dc, dd; 10 | 11 | wire [1:0] oa, ob, oc, od; 12 | 13 | initial begin : Sim 14 | $write ("%% "); 15 | $dumpfile ("tb.vcd"); 16 | $dumpvars; 17 | 18 | #5 19 | write <= 1; 20 | aa <= 2; 21 | ab <= 3; 22 | ac <= 4; 23 | ad <= 5; 24 | 25 | da <= $random; 26 | db <= $random; 27 | dc <= $random; 28 | dd <= $random; 29 | 30 | #10 31 | aa <= 6; 32 | ab <= 7; 33 | ac <= 8; 34 | ad <= 9; 35 | 36 | da <= $random; 37 | db <= $random; 38 | dc <= $random; 39 | dd <= $random; 40 | 41 | #10 42 | write <= 0; 43 | 44 | 45 | #30 46 | $finish; 47 | end // Sim 48 | 49 | 50 | RAM32M ram0 ( 51 | .WCLK (wclk), 52 | .WE (write), 53 | .ADDRA (aa), 54 | .ADDRB (ab), 55 | .ADDRC (ac), 56 | .ADDRD (ad), 57 | .DIA (da), 58 | .DIB (db), 59 | .DIC (dc), 60 | .DID (dd), 61 | .DOA (oa), 62 | .DOB (ob), 63 | .DOC (oc), 64 | .DOD (od) 65 | ); 66 | 67 | endmodule // RAM32M_tb 68 | -------------------------------------------------------------------------------- /sim/lib/fifo/sync/sfifo2k_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module sfifo2k_tb; 3 | 4 | reg clock = 1; 5 | reg reset_n = 1; 6 | reg read = 0; 7 | reg write = 0; 8 | 9 | reg [17:0] wr_data = 0; 10 | wire [17:0] rd_data; 11 | 12 | wire full; 13 | wire empty; 14 | 15 | always #5 clock <= ~clock; 16 | 17 | 18 | integer ii; 19 | initial begin : Sim 20 | $write ("%% "); 21 | $dumpfile ("tb.vcd"); 22 | $dumpvars; 23 | 24 | 25 | #2 26 | reset_n = 0; 27 | 28 | #10 29 | reset_n = 1; 30 | 31 | for (ii=0; ii<20; ii=ii+1) begin 32 | #10 write = 1; 33 | wr_data = ii; 34 | end 35 | 36 | #10 37 | read = 1; 38 | write = 0; 39 | wr_data = ii; 40 | 41 | #220 42 | read = 0; 43 | write = 0; 44 | 45 | #30 46 | $finish; 47 | end // Sim 48 | 49 | 50 | // 18-bit wide, 1024 entry FIFO. 51 | sfifo2k #( 52 | .WIDTH (18), 53 | .SIZE (16), 54 | .PWIDTH (4) 55 | ) FIFO0 ( 56 | .clock_i (clock), 57 | .reset_ni (reset_n), 58 | .read_i (read), 59 | .write_i (write), 60 | .data_i (wr_data), 61 | .data_o (rd_data), 62 | 63 | .empty_o (empty), 64 | .full_o (full) 65 | ); 66 | 67 | 68 | endmodule // sfifo2k_tb 69 | -------------------------------------------------------------------------------- /sim/lib/pre_read_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module pre_read_tb; 3 | 4 | reg a_clk = 1; 5 | reg b_clk = 1; 6 | reg reset = 0; 7 | 8 | always #5 a_clk <= ~a_clk; 9 | always #10 b_clk <= ~b_clk; 10 | 11 | reg a_wr = 0; 12 | reg [8:0] a_adr = 0; 13 | 14 | reg b_rd = 0; 15 | wire b_en; 16 | wire [8:0] b_adr; 17 | 18 | initial begin : Sim 19 | $dumpfile("tb.vcd"); 20 | $dumpvars(); 21 | 22 | #2 reset = 1; 23 | #30 reset = 0; 24 | 25 | #10 a_wr = 1; 26 | #10 a_wr = 0; 27 | 28 | #40 a_wr = 1; 29 | #10 a_wr = 0; 30 | 31 | #40 a_wr = 1; 32 | #10 a_wr = 0; 33 | 34 | #20 b_rd = 1; 35 | #60 b_rd = 0; 36 | 37 | #40 a_wr = 1; 38 | #10 a_wr = 0; 39 | 40 | #300 $finish; 41 | end // Sim 42 | 43 | initial begin 44 | #4000 $display ("Emergency exit!"); 45 | $finish; 46 | end 47 | 48 | always @(posedge a_clk) 49 | if (a_wr) a_adr <= #2 a_adr + 1; 50 | 51 | pre_read #( 52 | .ADDRESS (9), 53 | .INIT (0) 54 | ) PR0 ( 55 | .reset_i (reset), 56 | 57 | .a_clk_i (a_clk), 58 | .a_wr_i (a_wr), 59 | 60 | .b_clk_i (b_clk), 61 | .b_rd_i (b_rd), 62 | .b_en_ao (b_en), 63 | .b_adr_ao (b_adr) 64 | ); 65 | 66 | endmodule // pre_read_tb 67 | -------------------------------------------------------------------------------- /sim/xilinx/IFDDRRSE_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module IFDDRRSE_tb; 3 | 4 | reg clock = 1; 5 | always #5 clock <= ~clock; 6 | 7 | reg clk_en = 0; 8 | reg reset = 0; 9 | reg set = 0; 10 | 11 | wire [1:0] data; 12 | reg ddr_data = 0; 13 | 14 | initial begin : Sim 15 | 16 | $write ("%% "); 17 | $dumpfile ("test.vcd"); 18 | $dumpvars;// (1, CNTRL0, ddr_cke); 19 | 20 | /* $display ("Time CLK RST start read last RAS# CAS# WE# AP"); 21 | $monitor ("%5t %b %b %b %b %b %b %b %b %b", 22 | $time, clock, reset, 23 | cmd_start, cmd_read, cmd_last, 24 | ddr_ras_n, ddr_cas_n, ddr_we_n, ap 25 | ); 26 | */ 27 | 28 | reset <= 1; 29 | clk_en <= 1; 30 | 31 | #10 32 | reset <= 0; 33 | 34 | #5 35 | ddr_data <= 1; 36 | 37 | #10 38 | ddr_data <= 0; 39 | 40 | #11 41 | ddr_data <= 1; 42 | 43 | #10 44 | set <= 1; 45 | 46 | #10 47 | set <= 0; 48 | 49 | #20 50 | $finish; 51 | end // Sim 52 | 53 | 54 | IFDDRRSE odata_fddr ( 55 | .C0 (clock), 56 | .C1 (~clock), 57 | .CE (clk_en), 58 | .D (ddr_data), 59 | .R (reset), 60 | .S (set), 61 | .Q0 (data [0]), 62 | .Q1 (data [1]) 63 | ); 64 | 65 | endmodule // IFDDRRSE_tb 66 | -------------------------------------------------------------------------------- /sim/xilinx/OFDDRRSE_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module OFDDRRSE_tb; 3 | 4 | reg clock = 1; 5 | always #5 clock <= ~clock; 6 | 7 | reg clk_en = 0; 8 | reg reset = 0; 9 | reg set = 0; 10 | 11 | reg [1:0] data = 0; 12 | wire ddr_data; 13 | 14 | wire d0 = data [0]; 15 | wire d1 = data [1]; 16 | 17 | initial begin : Sim 18 | 19 | $write ("%% "); 20 | $dumpfile ("test.vcd"); 21 | $dumpvars;// (1, CNTRL0, ddr_cke); 22 | 23 | $display ("Time CLK RST SET CE D0 D1 Q "); 24 | $monitor ("%5t %b %b %b %b %b %b %b", 25 | $time, clock, reset, set, clk_en, 26 | d0, d1, ddr_data 27 | ); 28 | 29 | 30 | reset <= 1; 31 | clk_en <= 1; 32 | 33 | #11 34 | reset <= 0; 35 | 36 | #10 37 | data <= 2'b01; 38 | 39 | #10 40 | data <= 2'b10; 41 | 42 | #10 43 | data <= 2'b11; 44 | 45 | #10 46 | data <= 2'b00; 47 | 48 | #10 49 | set <= 1; 50 | 51 | #10 52 | set <= 0; 53 | 54 | #20 55 | $finish; 56 | end // Sim 57 | 58 | defparam odata_fddr.DELAY = 3.0; 59 | OFDDRRSE odata_fddr ( 60 | .Q (ddr_data), 61 | .C0 (clock), 62 | .C1 (~clock), 63 | .CE (clk_en), 64 | .D0 (data [0]), 65 | .D1 (data [1]), 66 | .R (reset), 67 | .S (set) 68 | ); 69 | 70 | endmodule // OFDDRRSE_tb 71 | -------------------------------------------------------------------------------- /rtl/video/crtc_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module crtc_tb; 3 | 4 | parameter WIDTH = 10; 5 | parameter MSB = WIDTH - 1; 6 | 7 | reg clock = 1; 8 | always #5 clock <= ~clock; 9 | 10 | reg reset_n = 1; 11 | 12 | wire vsync, hsync; 13 | wire vblank, hblank; 14 | wire de; 15 | 16 | wire [MSB:0] row, col; 17 | 18 | 19 | initial begin : Sim 20 | $write ("%% "); 21 | $dumpfile ("tb.vcd"); 22 | $dumpvars;// (1, CNTRL0, ddr_cke); 23 | 24 | #5 reset_n <= 0; 25 | #20 reset_n <= 1; 26 | 27 | #60000 28 | $finish; 29 | end // Sim 30 | 31 | 32 | crtc #( 33 | .WIDTH (WIDTH) 34 | ) CRTC0 ( 35 | .clock_i (clock), // Character clock 36 | .reset_ni (reset_n), 37 | .enable_i (1'b1), 38 | /* 39 | .hsynct_i (1), 40 | .hbporch_i (2), 41 | .hactive_i (11), 42 | .hfporch_i (12), 43 | 44 | .vsynct_i (1), 45 | .vbporch_i (2), 46 | .vactive_i (11), 47 | .vfporch_i (12), 48 | */ 49 | .hsynct_i (11), 50 | .hbporch_i (17), 51 | .hactive_i (97), 52 | .hfporch_i (99), // h-total too 53 | 54 | .vsynct_i (1), 55 | .vbporch_i (34), 56 | .vactive_i (514), 57 | .vfporch_i (524), 58 | 59 | .row_o (row), 60 | .col_o (col), 61 | 62 | .de_o (de), 63 | .hsync_o (hsync), 64 | .vsync_o (vsync), 65 | .hblank_o (hblank), 66 | .vblank_o (vblank) 67 | ); 68 | 69 | 70 | endmodule // crtc_tb 71 | -------------------------------------------------------------------------------- /sim/video/crtc_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module crtc_tb; 3 | 4 | parameter WIDTH = 10; 5 | parameter MSB = WIDTH - 1; 6 | 7 | reg clock = 1; 8 | always #5 clock <= ~clock; 9 | 10 | reg reset_n = 1; 11 | 12 | wire vsync, hsync; 13 | wire vblank, hblank; 14 | wire de; 15 | 16 | wire [MSB:0] row, col; 17 | 18 | 19 | initial begin : Sim 20 | $write ("%% "); 21 | $dumpfile ("tb.vcd"); 22 | $dumpvars;// (1, CNTRL0, ddr_cke); 23 | 24 | #5 reset_n <= 0; 25 | #20 reset_n <= 1; 26 | 27 | #60000 28 | $finish; 29 | end // Sim 30 | 31 | 32 | crtc #( 33 | .WIDTH (WIDTH) 34 | ) CRTC0 ( 35 | .clock_i (clock), // Character clock 36 | .reset_ni (reset_n), 37 | .enable_i (1'b1), 38 | /* 39 | .hsynct_i (1), 40 | .hbporch_i (2), 41 | .hactive_i (11), 42 | .hfporch_i (12), 43 | 44 | .vsynct_i (1), 45 | .vbporch_i (2), 46 | .vactive_i (11), 47 | .vfporch_i (12), 48 | */ 49 | .hsynct_i (11), 50 | .hbporch_i (17), 51 | .hactive_i (97), 52 | .hfporch_i (99), // h-total too 53 | 54 | .vsynct_i (1), 55 | .vbporch_i (34), 56 | .vactive_i (514), 57 | .vfporch_i (524), 58 | 59 | .row_o (row), 60 | .col_o (col), 61 | 62 | .de_o (de), 63 | .hsync_o (hsync), 64 | .vsync_o (vsync), 65 | .hblank_o (hblank), 66 | .vblank_o (vblank) 67 | ); 68 | 69 | 70 | endmodule // crtc_tb 71 | -------------------------------------------------------------------------------- /sim/cpu/risc16/risc16_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module risc16_tb; 3 | 4 | parameter WIDTH = 16; 5 | parameter ADDRESS = 25; 6 | parameter MSB = WIDTH - 1; 7 | 8 | reg cpu_clk = 1; 9 | always #6 cpu_clk = ~cpu_clk; 10 | 11 | reg wb_clk = 1; 12 | always #12 wb_clk = ~wb_clk; 13 | 14 | reg reset = 0; 15 | 16 | 17 | initial begin : Sim 18 | $dumpfile ("tb.vcd"); 19 | $dumpvars; 20 | 21 | #2 reset = 1; 22 | #24 reset = 0; 23 | 24 | #300 $finish; 25 | end // Sim 26 | 27 | // Dummy WB module. 28 | wire cyc, we; 29 | reg ack = 0; 30 | reg [MSB:0] dat; 31 | always @(posedge cpu_clk) 32 | if (cyc && !ack) ack <= #2 1; 33 | else ack <= #2 0; 34 | 35 | always @(posedge cpu_clk) 36 | dat <= #2 $random; 37 | 38 | risc16 #( 39 | .HIGHZ (0), 40 | .WIDTH (WIDTH), 41 | .INSTR (WIDTH), 42 | .ADDRESS (ADDRESS), 43 | .PCBITS (10), 44 | .WBBITS (WIDTH) 45 | ) RISC16 ( 46 | .cpu_clk_i (cpu_clk), 47 | .cpu_rst_i (reset), 48 | 49 | .wb_clk_i (cpu_clk), 50 | .wb_rst_i (reset), 51 | .wb_cyc_o (cyc), 52 | .wb_stb_o (), 53 | .wb_we_o (we), 54 | .wb_ack_i (ack), 55 | .wb_rty_i (0), 56 | .wb_err_i (0), 57 | .wb_cti_o (), 58 | .wb_bte_o (), 59 | .wb_adr_o (), 60 | .wb_sel_o (), 61 | .wb_dat_o (), 62 | .wb_sel_i ({ack, ack}), 63 | .wb_dat_i (dat) 64 | ); 65 | 66 | 67 | endmodule // risc16_tb 68 | -------------------------------------------------------------------------------- /sim/cpu/tta16/tta16_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module tta16_tb; 3 | 4 | parameter WIDTH = 16; 5 | parameter INSTR = 32; 6 | parameter ADDRESS = 25; 7 | parameter MSB = WIDTH - 1; 8 | 9 | reg cpu_clk = 1; 10 | always #6 cpu_clk = ~cpu_clk; 11 | 12 | reg wb_clk = 1; 13 | always #12 wb_clk = ~wb_clk; 14 | 15 | reg reset = 0; 16 | 17 | 18 | initial begin : Sim 19 | $dumpfile ("tb.vcd"); 20 | $dumpvars; 21 | 22 | #2 reset = 1; 23 | #24 reset = 0; 24 | 25 | #480 $finish; 26 | end // Sim 27 | 28 | // Dummy WB module. 29 | wire cyc, we; 30 | reg ack = 0; 31 | reg [MSB:0] dat; 32 | always @(posedge cpu_clk) 33 | if (cyc && !ack) ack <= #2 1; 34 | else ack <= #2 0; 35 | 36 | always @(posedge cpu_clk) 37 | dat <= #2 $random; 38 | 39 | tta16 #( 40 | .HIGHZ (0), 41 | .WIDTH (WIDTH), 42 | .INSTR (INSTR), 43 | .ADDRESS (ADDRESS), 44 | .PCBITS (11), 45 | .WBBITS (WIDTH) 46 | ) TTA16 ( 47 | .cpu_clk_i (cpu_clk), 48 | .cpu_rst_i (reset), 49 | 50 | .wb_clk_i (cpu_clk), 51 | .wb_rst_i (reset), 52 | .wb_cyc_o (cyc), 53 | .wb_stb_o (), 54 | .wb_we_o (we), 55 | .wb_ack_i (ack), 56 | .wb_rty_i (0), 57 | .wb_err_i (0), 58 | .wb_cti_o (), 59 | .wb_bte_o (), 60 | .wb_adr_o (), 61 | .wb_sel_o (), 62 | .wb_dat_o (), 63 | .wb_sel_i ({ack, ack}), 64 | .wb_dat_i (dat) 65 | ); 66 | 67 | 68 | endmodule // tta16_tb 69 | -------------------------------------------------------------------------------- /sim/lib/wb_bram_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module wb_bram_tb; 3 | 4 | reg clock = 1; 5 | always #5 clock <= ~clock; 6 | 7 | reg reset = 0; 8 | 9 | reg cyc = 0; 10 | reg stb = 0; 11 | reg write = 0; 12 | reg [2:0] cti = 0; 13 | reg [8:0] adr; 14 | wire ack, err; 15 | 16 | reg [31:0] data_to; 17 | reg [3:0] bes_to; 18 | 19 | wire [31:0] data_from; 20 | wire [3:0] bes_from; 21 | 22 | 23 | initial begin : Sim 24 | $write ("%% "); 25 | $dumpfile ("tb.vcd"); 26 | $dumpvars; 27 | 28 | #2 reset = 1; 29 | #20 reset = 0; 30 | 31 | #10 cyc = 1; stb = 1; write = 1; cti = 2; adr = 0; data_to = $random; bes_to = 4'hf; 32 | #10 ; 33 | #10 cti = 7; adr = 1; stb = 0; data_to = $random; 34 | #10 stb = 1; 35 | #20 cyc = 0; stb = 0; 36 | 37 | #20 cyc = 1; stb = 1; write = 0; cti = 2; adr = 0; 38 | #20 cti = 7; adr = 1; 39 | #10 cyc = 0; stb = 0; 40 | 41 | #800 $finish; 42 | end // Sim 43 | 44 | 45 | wb_bram #( 46 | .HIGHZ (1) 47 | ) BRAM ( 48 | .wb_clk_i (clock), 49 | .wb_rst_i (reset), 50 | .wb_cyc_i (cyc), 51 | .wb_stb_i (stb), 52 | .wb_we_i (write), 53 | .wb_ack_o (ack), 54 | .wb_err_o (err), 55 | .wb_cti_i (cti), 56 | .wb_bte_i (0), 57 | .wb_adr_i (adr), 58 | .wb_sel_i (bes_to), 59 | .wb_dat_i (data_to), 60 | .wb_sel_o (bes_from), 61 | .wb_dat_o (data_from) 62 | ); 63 | 64 | 65 | endmodule // wb_bram_tb 66 | -------------------------------------------------------------------------------- /sim/lib/wb_leds_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module wb_leds_tb; 3 | 4 | // parameter WIDTH = 32; 5 | parameter WIDTH = 8; 6 | parameter ENABLES = WIDTH/8; 7 | parameter MSB = WIDTH - 1; 8 | parameter ESB = ENABLES - 1; 9 | 10 | reg wb_clk = 1; 11 | always #5 wb_clk = ~wb_clk; 12 | 13 | reg wb_rst = 0; 14 | 15 | reg wb_stb, wb_we; 16 | wire wb_ack; 17 | reg [ESB:0] wb_sel2 = 2'b11; 18 | reg [MSB:0] wb_dat2; 19 | wire [ESB:0] wb_self; 20 | wire [MSB:0] leds, wb_datf; 21 | 22 | initial begin : Sim 23 | $dumpfile ("tb.vcd"); 24 | $dumpvars; 25 | 26 | #2 wb_rst = 1; 27 | wb_stb = 0; wb_we = 0; 28 | #20 wb_rst = 0; 29 | 30 | #20 wb_stb = 1; wb_we = 1; wb_dat2 = $random; 31 | while (!wb_ack) #10; 32 | wb_stb = 0; wb_we = 0; 33 | 34 | #20 wb_stb = 1; wb_we = 1; wb_dat2 = $random; 35 | while (!wb_ack) #10; 36 | wb_stb = 0; wb_we = 0; 37 | 38 | #10 wb_stb = 1; 39 | while (!wb_ack) #10; 40 | wb_stb = 0; 41 | 42 | #300 $finish; 43 | end // Sim 44 | 45 | initial #400 $finish; 46 | 47 | wb_leds #( 48 | .HIGHZ (0), 49 | .WIDTH (WIDTH) 50 | ) LEDS ( 51 | .wb_clk_i (wb_clk), 52 | .wb_rst_i (wb_rst), 53 | 54 | .wb_cyc_i (wb_stb), 55 | .wb_stb_i (wb_stb), 56 | .wb_we_i (wb_we), 57 | .wb_ack_o (wb_ack), 58 | .wb_sel_i (wb_sel2), 59 | .wb_dat_i (wb_dat2), 60 | .wb_sel_o (wb_self), 61 | .wb_dat_o (wb_datf), 62 | 63 | .leds_o (leds) 64 | ); // wb_leds 65 | 66 | endmodule // wb_leds_tb 67 | -------------------------------------------------------------------------------- /sim/xilinx/RAMB16_S9_S9_testbench.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module RAMB16_S9_S36_testbench; 3 | 4 | 5 | reg clock = 1; 6 | reg reset = 1; 7 | 8 | reg [7:0] dia = 8'h0; 9 | reg [10:0] addra = 10'h0; 10 | reg ena = 0; 11 | reg wea = 0; 12 | wire [7:0] doa; 13 | wire dopa; 14 | 15 | reg [7:0] dib = 8'hFF; 16 | reg [10:0] addrb = 1; 17 | reg enb = 1; 18 | reg web = 0; 19 | wire [7:0] dob; 20 | wire dopb; 21 | 22 | always #5 clock <= ~clock; 23 | 24 | initial begin : Init 25 | $display("Time CLK RESET ADDRA WE DiA DiB DoA DoB"); 26 | $monitor("%5t %b %b %d %b %h %h %h %h ", 27 | $time, clock, reset, addra, wea, dia, dib, doa, dob 28 | ); 29 | 30 | #5 31 | ena <= 1; 32 | enb <= 1; 33 | reset <= 0; 34 | 35 | #10 36 | wea <= 1; 37 | web <= 1; 38 | dia <= 8'hf3; 39 | dib <= 8'ha5; 40 | 41 | #10 42 | wea <= 0; 43 | web <= 0; 44 | 45 | #10 46 | $display("%% doa = %h", doa); 47 | 48 | #10 49 | $finish; 50 | end 51 | 52 | RAMB16_S9_S9 lut0 ( 53 | .DIA(dia), 54 | .DIPA(1'b0), 55 | .ADDRA(addra), 56 | .ENA(ena), 57 | .WEA(wea), 58 | .SSRA(0), 59 | .CLKA(clock), 60 | .DOA(doa), 61 | .DOPA(dopa), 62 | 63 | .DIB(dib), 64 | .DIPB(1'b0), 65 | .ADDRB(addrb), 66 | .ENB(enb), 67 | .WEB(web), 68 | .SSRB(0), 69 | .CLKB(clock), 70 | .DOB(dob), 71 | .DOPB(dopb) 72 | ); 73 | 74 | endmodule // RAMB16_S9_S36_testbench 75 | -------------------------------------------------------------------------------- /sim/lib/wb_serial_port_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module wb_serial_port_tb; 3 | 4 | // parameter WIDTH = 32; 5 | parameter WIDTH = 8; 6 | parameter ENABLES = WIDTH/8; 7 | parameter MSB = WIDTH - 1; 8 | parameter ESB = ENABLES - 1; 9 | 10 | reg wb_clk = 1; 11 | always #5 wb_clk = ~wb_clk; 12 | 13 | reg wb_rst = 0; 14 | 15 | reg wb_stb, wb_we; 16 | wire wb_ack; 17 | reg [ESB:0] wb_sel2 = 2'b11; 18 | reg [MSB:0] wb_dat2; 19 | wire [ESB:0] wb_self; 20 | wire [MSB:0] leds, wb_datf; 21 | 22 | initial begin : Sim 23 | $dumpfile ("tb.vcd"); 24 | $dumpvars; 25 | 26 | #2 wb_rst = 1; 27 | wb_stb = 0; wb_we = 0; 28 | #20 wb_rst = 0; 29 | 30 | #20 wb_stb = 1; wb_we = 1; wb_dat2 = $random; 31 | while (!wb_ack) #10; 32 | wb_stb = 0; wb_we = 0; 33 | 34 | #20 wb_stb = 1; wb_we = 1; wb_dat2 = $random; 35 | while (!wb_ack) #10; 36 | wb_stb = 0; wb_we = 0; 37 | 38 | #10 wb_stb = 1; 39 | while (!wb_ack) #10; 40 | wb_stb = 0; 41 | 42 | #300 $finish; 43 | end // Sim 44 | 45 | initial #400 $finish; 46 | 47 | wb_serial_port #( 48 | .HIGHZ (0), 49 | .WIDTH (WIDTH) 50 | ) LEDS ( 51 | .wb_clk_i (wb_clk), 52 | .wb_rst_i (wb_rst), 53 | 54 | .wb_cyc_i (wb_stb), 55 | .wb_stb_i (wb_stb), 56 | .wb_we_i (wb_we), 57 | .wb_ack_o (wb_ack), 58 | .wb_sel_i (wb_sel2), 59 | .wb_dat_i (wb_dat2), 60 | .wb_sel_o (wb_self), 61 | .wb_dat_o (wb_datf), 62 | 63 | .leds_o (leds) 64 | ); // wb_leds 65 | 66 | endmodule // wb_serial_port_tb 67 | -------------------------------------------------------------------------------- /src/assembler/asm_out.m: -------------------------------------------------------------------------------- 1 | :- module asm_out. 2 | :- interface. 3 | :- import_module int, list, pair, integer, asm, config_asm, prettyprint. 4 | 5 | :- type asm_out == list(pair(int,integer)). 6 | 7 | :- pred asm_to_out(config::in, asm::in, asm_out::out) is det. 8 | :- pred print_out(config::in, asm_out::in, pr_state::in, pr_state::out) is det. 9 | :- pred sort_out(asm_out::in, asm_out::out) is det. 10 | :- pred pack(int::in,int::in,asm_out::in, asm_out::out) is det. 11 | 12 | :- implementation. 13 | :- import_module string,exception. 14 | 15 | asm_to_out(_,[],[]). 16 | asm_to_out(Conf,[_-label(_)|T],Res) :- asm_to_out(Conf,T,Res). 17 | asm_to_out(Conf,[A-i(_,_,D,_)|T],[A-D|Res]) :- asm_to_out(Conf,T,Res). 18 | 19 | print_out(Config,Code) --> print_with_pred_sep(newline,pred(X::in,Y::in,Z::out) is det :- print_outval(Config,X,Y,Z),Code),newline. 20 | 21 | :- pred print_outval(config::in, pair(int,integer)::in, pr_state::in, pr_state::out) is det. 22 | print_outval(Config,Addr-Instr) --> pN(pad_left(int_to_base_string(Addr,16),'0',(Config^model^pc_width+3)>>2)++":"),write_integer((Config^model^instruction_width+3)>>2,16,Instr). 23 | 24 | sort_out(X,Y) :- list.sort(X,Y). 25 | 26 | pack(Sofar,Max,[],Asm) :- (Sofar>=Max -> Asm=[] ; pack(Sofar+1,Max,[],A),Asm=[Sofar-zero|A]). 27 | pack(Sofar,Max,X@[Addr-D|T],Asm) :- 28 | ( Addr throw("Pack: instruction stream out of order") 29 | ; Addr=Sofar -> pack(Sofar+1,Max,T,A),Asm=[Addr-D|A] 30 | ; pack(Sofar+1,Max,X,A),Asm=[Sofar-zero|A]). -------------------------------------------------------------------------------- /sim/lib/fifo/async/afifo2k_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module afifo2k_tb; 3 | 4 | reg rclk = 1; 5 | reg wclk = 1; 6 | 7 | reg reset = 0; 8 | reg read = 0; 9 | reg write = 0; 10 | 11 | reg [17:0] wr_data = 0; 12 | wire [17:0] rd_data; 13 | 14 | wire full; 15 | wire empty; 16 | 17 | always #15 rclk <= ~rclk; 18 | always #5 wclk <= ~wclk; 19 | 20 | 21 | initial begin : Sim 22 | $dumpfile ("tb.vcd"); 23 | $dumpvars; 24 | 25 | #2 26 | reset <= 1; 27 | 28 | #30 29 | reset <= 0; 30 | 31 | #30 32 | read <= 0; 33 | write <= 0; 34 | 35 | #10 36 | write <= 1; 37 | // wr_data <= 18'h30F0; 38 | /* 39 | #10 40 | wr_data <= 18'h0A0A; 41 | 42 | #10 // 62 43 | wr_data <= $random; 44 | 45 | #10 46 | wr_data <= $random; 47 | 48 | #10 49 | write <= 0; 50 | 51 | #10 // 92 52 | read <= 1; 53 | 54 | #30 // 122 55 | read <= 0; 56 | 57 | #30 // 152 58 | read <= 1; 59 | 60 | #60 // 212 61 | read <= 0; 62 | */ 63 | #200 64 | read <= 1; 65 | 66 | #30 67 | write <= 0; 68 | 69 | #600 70 | $finish; 71 | end // Sim 72 | 73 | 74 | // Fill the FIFO. 75 | always @(posedge wclk) 76 | wr_data <= #5 $random; 77 | 78 | 79 | // 18-bit wide, 15 entry FIFO, ultra high-speed FIFO 80 | afifo2k #('d18) FIFO0( 81 | .reset_ni (~reset), 82 | 83 | .rd_clk_i (rclk), 84 | .rd_en_i (read), 85 | .rd_data_o (rd_data), 86 | 87 | .wr_clk_i (wclk), 88 | .wr_en_i (write), 89 | .wr_data_i (wr_data), 90 | 91 | .wfull_o (full), 92 | .rempty_o (empty) 93 | ); 94 | 95 | 96 | endmodule // afifo2k_tb 97 | -------------------------------------------------------------------------------- /sim/lib/fifo/async/afifo16_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module afifo16_tb; 3 | 4 | reg rclk = 1; 5 | reg wclk = 1; 6 | 7 | reg reset = 0; 8 | reg read = 0; 9 | reg write = 0; 10 | 11 | reg [17:0] wr_data = 0; 12 | wire [17:0] rd_data; 13 | 14 | wire full; 15 | wire empty; 16 | 17 | always #15 rclk <= ~rclk; 18 | always #5 wclk <= ~wclk; 19 | 20 | 21 | initial begin : Sim 22 | $dumpfile ("tb.vcd"); 23 | $dumpvars; 24 | 25 | #2 26 | reset <= 1; 27 | 28 | #30 29 | reset <= 0; 30 | 31 | #30 32 | read <= 0; 33 | write <= 0; 34 | 35 | #10 36 | write <= 1; 37 | // wr_data <= 18'h30F0; 38 | /* 39 | #10 40 | wr_data <= 18'h0A0A; 41 | 42 | #10 // 62 43 | wr_data <= $random; 44 | 45 | #10 46 | wr_data <= $random; 47 | 48 | #10 49 | write <= 0; 50 | 51 | #10 // 92 52 | read <= 1; 53 | 54 | #30 // 122 55 | read <= 0; 56 | 57 | #30 // 152 58 | read <= 1; 59 | 60 | #60 // 212 61 | read <= 0; 62 | */ 63 | #200 64 | read <= 1; 65 | 66 | #30 67 | write <= 0; 68 | 69 | #600 70 | $finish; 71 | end // Sim 72 | 73 | 74 | // Fill the FIFO. 75 | always @(posedge wclk) 76 | wr_data <= #5 $random; 77 | 78 | 79 | // 18-bit wide, 15 entry FIFO, ultra high-speed FIFO 80 | afifo16 #('d18) FIFO0 ( 81 | .reset_ni (~reset), 82 | 83 | .rd_clk_i (rclk), 84 | .rd_en_i (read), 85 | .rd_data_o (rd_data), 86 | 87 | .wr_clk_i (wclk), 88 | .wr_en_i (write), 89 | .wr_data_i (wr_data), 90 | 91 | .wfull_o (full), 92 | .rempty_o (empty) 93 | ); 94 | 95 | 96 | endmodule // afifo16_tb 97 | -------------------------------------------------------------------------------- /data/vgabios-0.4c/vgabios.h: -------------------------------------------------------------------------------- 1 | #ifndef vgabios_h_included 2 | #define vgabios_h_included 3 | 4 | /* Types */ 5 | typedef unsigned char Bit8u; 6 | typedef unsigned short Bit16u; 7 | typedef unsigned long Bit32u; 8 | typedef unsigned short Boolean; 9 | 10 | /* Defines */ 11 | 12 | #define SET_AL(val8) AX = ((AX & 0xff00) | (val8)) 13 | #define SET_BL(val8) BX = ((BX & 0xff00) | (val8)) 14 | #define SET_CL(val8) CX = ((CX & 0xff00) | (val8)) 15 | #define SET_DL(val8) DX = ((DX & 0xff00) | (val8)) 16 | #define SET_AH(val8) AX = ((AX & 0x00ff) | ((val8) << 8)) 17 | #define SET_BH(val8) BX = ((BX & 0x00ff) | ((val8) << 8)) 18 | #define SET_CH(val8) CX = ((CX & 0x00ff) | ((val8) << 8)) 19 | #define SET_DH(val8) DX = ((DX & 0x00ff) | ((val8) << 8)) 20 | 21 | #define GET_AL() ( AX & 0x00ff ) 22 | #define GET_BL() ( BX & 0x00ff ) 23 | #define GET_CL() ( CX & 0x00ff ) 24 | #define GET_DL() ( DX & 0x00ff ) 25 | #define GET_AH() ( AX >> 8 ) 26 | #define GET_BH() ( BX >> 8 ) 27 | #define GET_CH() ( CX >> 8 ) 28 | #define GET_DH() ( DX >> 8 ) 29 | 30 | #define SET_CF() FLAGS |= 0x0001 31 | #define CLEAR_CF() FLAGS &= 0xfffe 32 | #define GET_CF() (FLAGS & 0x0001) 33 | 34 | #define SET_ZF() FLAGS |= 0x0040 35 | #define CLEAR_ZF() FLAGS &= 0xffbf 36 | #define GET_ZF() (FLAGS & 0x0040) 37 | 38 | #define SCROLL_DOWN 0 39 | #define SCROLL_UP 1 40 | #define NO_ATTR 2 41 | #define WITH_ATTR 3 42 | 43 | #define SCREEN_SIZE(x,y) (((x*y*2)|0x00ff)+1) 44 | #define SCREEN_MEM_START(x,y,p) ((((x*y*2)|0x00ff)+1)*p) 45 | #define SCREEN_IO_START(x,y,p) ((((x*y)|0x00ff)+1)*p) 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /rtl/cpu/risc16/defines.v: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------------- 2 | // Optional configuration settings: 3 | // 4 | // Allow MSRs to be read as well as written. 5 | // TODO: This is still a little slow and incomplete. 6 | // `define __use_readable_MSR 7 | // 8 | // Explicitly instantiate a Xilinx BRAM for simulation and synthesis? 9 | // This is needed to load the BRAM with initial values. 10 | `define __use_bram 11 | // 12 | //--------------------------------------------------------------------------- 13 | 14 | // OPs 15 | `define RR 3'b000 16 | `define RI 3'b001 17 | `define SUBI 3'b010 18 | `define _free0_ 3'b011 19 | `define LW 3'b100 20 | `define SW 3'b101 21 | `define BX 3'b110 22 | `define I12 3'b111 23 | 24 | // FNs 25 | `define SUB 3'b000 26 | `define SBB 3'b001 27 | `define MUL 3'b010 28 | `define MSR 3'b011 29 | `define AND 3'b100 30 | `define BR 3'b101 31 | `define OR 3'b110 32 | `define XOR 3'b111 33 | 34 | // CNDs 35 | `define JNE 3'b000 36 | `define JE 3'b001 37 | `define JL 3'b010 38 | `define JG 3'b011 39 | `define JB 3'b100 40 | `define JBE 3'b101 41 | `define JA 3'b110 42 | `define JAE 3'b111 43 | 44 | `define NF 1'b0 45 | `define SF 1'b1 46 | `define NC 1'b0 47 | `define CR 1'b1 48 | `define R0 4'h0 49 | `define R1 4'h1 50 | `define R2 4'h2 51 | `define R3 4'h3 52 | `define R4 4'h4 53 | `define R5 4'h5 54 | `define R6 4'h6 55 | `define R7 4'h7 56 | `define R8 4'h8 57 | `define R9 4'h9 58 | `define RA 4'ha 59 | `define RB 4'hb 60 | `define RC 4'hc 61 | `define RD 4'hd 62 | `define RE 4'he 63 | `define RF 4'hf 64 | `define ZERO 4'h0 65 | `define ONE 4'h1 66 | `define ONE_ 4'hf 67 | -------------------------------------------------------------------------------- /sim/xilinx/RAMB36SDP_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module RAMB36SDP_tb; 3 | 4 | reg clock = 1; 5 | always #5 clock <= ~clock; 6 | 7 | reg reset = 0; 8 | 9 | reg read = 0; 10 | reg write = 0; 11 | reg regce = 0; 12 | reg [8:0] rdaddr = 0; 13 | reg [8:0] wraddr = 0; 14 | reg [71:0] datato = 0; 15 | wire [71:0] datafrom; 16 | 17 | wire [7:0] wes = {write, write, write, write, write, write, write, write}; 18 | 19 | 20 | initial begin : Sim 21 | $write ("%% "); 22 | $dumpfile ("tb.vcd"); 23 | $dumpvars; 24 | 25 | #5 26 | reset <= 1; 27 | 28 | #10 29 | reset <= 0; 30 | 31 | #10 32 | write <= 1; 33 | wraddr <= 1; 34 | datato <= $random; 35 | 36 | #10 37 | datato <= 'bx; 38 | write <= 0; 39 | read <= 1; 40 | rdaddr <= 0; 41 | 42 | #10 43 | rdaddr <= 1; 44 | 45 | #10 46 | regce <= 1; 47 | read <= 0; 48 | 49 | #10 50 | regce <= 0; 51 | 52 | #30 53 | $finish; 54 | end // Sim 55 | 56 | 57 | RAMB36SDP ram0 ( 58 | .RDCLK (clock), // 1-bit read port clock 59 | .WRCLK (clock), // 1-bit write port clock 60 | .SSR (reset), // 1-bit synchronous output set/reset input 61 | .WE ({1'bx, wes [6:0]}), // 8-bit write enable input 62 | .WREN (write), // 1-bit write port enable 63 | .RDEN (read), // 1-bit read port enable 64 | .REGCE (regce), // 1-bit register enable input 65 | .RDADDR (rdaddr), // 9-bit read port address input 66 | .WRADDR (wraddr), // 9-bit write port address input 67 | .DI (datato [63:0]), // 64-bit data input 68 | .DIP (datato [71:64]), // 8-bit parity data input 69 | .DO (datafrom [63:0]), // 64-bit data output 70 | .DOP (datafrom [71:64]) // 8-bit parity data output 71 | ); 72 | 73 | 74 | endmodule // RAMB36SDP 75 | -------------------------------------------------------------------------------- /src/fw_tta16/prepro.m4: -------------------------------------------------------------------------------- 1 | dnl # 2 | dnl # Assembly helpers. 3 | dnl # All modules should not cause hazards. 4 | dnl # 5 | dnl # Author: Patrick Suggate 6 | dnl # patrick@physics.otago.ac.nz 7 | dnl # 8 | dnl 9 | define(`arch', `architecture:$1')dnl 10 | dnl 11 | define(`NOP', ` {,,,}')dnl 12 | dnl # This could be smarter and do a check on $2 to see if a couple of NOPs 13 | dnl # can be saved. 14 | define(`mov',dnl 15 | `NOP 16 | { , , ,$2 } 17 | { , ,com ->$1\ , } 18 | NOP')dnl 19 | define(`call',dnl 20 | ` {$1 ->bra , ,pc ->r15\ , } 21 | NOP')dnl 22 | define(`branch',dnl 23 | ` {$1 ->bra , , , } 24 | NOP')dnl 25 | dnl 26 | define(`mov2r',dnl 27 | ` { , , ,$3 } 28 | { , ,com ->$1\ ,$4 } 29 | { , ,com ->$2\ , } 30 | NOP')dnl 31 | define(`mov3r',dnl 32 | ` { , , ,$4 } 33 | { , ,com ->$1\ ,$5 } 34 | { , ,com ->$2\ ,$6 } 35 | { , ,com ->$3\ , } 36 | NOP')dnl 37 | dnl 38 | define(`mov4r',dnl 39 | ` { , , ,$5 } 40 | { , ,com ->$1\ ,$6 } 41 | { , ,com ->$2\ ,$7 } 42 | { , ,com ->$3\ ,$8 } 43 | { , ,com ->$4\ , } 44 | NOP')dnl 45 | dnl 46 | define(`pushi',dnl 47 | ` { , , ,$1 } 48 | {\r14 ->wad ,1 ->sub ,com ->mem ,\r14 } 49 | { , , , } 50 | { , ,diff ->r14\ , } 51 | { , , , }')dnl 52 | dnl 53 | define(`popi',dnl 54 | ` { , , , } 55 | { ,-1 ->sub , ,\r14 } 56 | { , , , } 57 | { , ,diff ->r14\ ,diff } 58 | {com ->rad , , , } 59 | { , , ,mem } 60 | { , ,com ->$1\ , } 61 | NOP')dnl 62 | dnl 63 | define(`lea',dnl 64 | ` { , , ,eval($2/128) } 65 | { , ,com ->mul ,128 } 66 | { , , , } 67 | { ,eval($2%128) ->or , ,plo } 68 | { , , , } 69 | { , , ,bits } 70 | { , ,com ->$1\ , } 71 | NOP')dnl 72 | dnl -------------------------------------------------------------------------------- /src/drv/dump.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // Currently only 4kB of memory is mapped 9 | #define MEM_SIZE 4096 10 | 11 | static int fd; 12 | 13 | int freega_open () 14 | { 15 | // Open FreeGA for read/write 16 | fd = open ("/dev/freega", O_RDWR); 17 | if (fd == -1) { 18 | printf ("Didn't work!\n"); //ERROR: (%D)\n", errno); 19 | return 1; 20 | } 21 | 22 | return 0; 23 | } 24 | 25 | void freega_close () 26 | { 27 | close (fd); // TODO: Will never get here! 28 | } 29 | 30 | 31 | unsigned long freega_read_word (int addr) 32 | { 33 | unsigned long buf; 34 | 35 | freega_open (); 36 | lseek (fd, addr*4, SEEK_SET); 37 | read (fd, (void*) &buf, 4); 38 | freega_close (); 39 | 40 | return buf; 41 | } 42 | 43 | 44 | freega_write_word (int addr, unsigned long word) 45 | { 46 | freega_open (); 47 | lseek (fd, addr*4, SEEK_SET); 48 | write (fd, (void*) &word, 4); 49 | freega_close (); 50 | } 51 | 52 | 53 | unsigned long* freega_get (unsigned long* ar, int n) 54 | { 55 | int i; 56 | for (i=0; i=0; j-=4) 71 | printf ("%c", (hex_lut [(v >> j) & 0x0F])); 72 | printf ("\n"); 73 | } 74 | } 75 | 76 | 77 | int main (void) 78 | { 79 | int fd, i; 80 | static unsigned long ar [256]; 81 | 82 | hex_dump (freega_get (ar, 256), 256); 83 | 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /data/vgabios-0.4c/TODO: -------------------------------------------------------------------------------- 1 | Short term : 2 | ------------ 3 | 4 | General 5 | - Fix init mode (ah=00). Should use more BIOS variables 6 | - Add new functionalities and modify static functionality table 7 | - Performance : 16 bits IO 8 | 9 | v0.4 10 | - Implement the remaining functions : 11 | - chargen ax=1100, ax=1101, ax=1102, ax=1103, ax=1104, ax=1110, 12 | ax=1111, ax=1112, ax=1120, ax=1121, ax=1122, ax=1123, ax=1124 13 | 14 | v0.5 15 | - Reimplement the tables so it is compatible with the video save pointer table 16 | - Implement the remaining functions (don't know if all are needed): 17 | - set border ah=0b bh=00, set cga palette ah=0b bh=01, 18 | - display switch interface ah=12 bl=35 19 | - video refresh control ah=12 bl=36 20 | - save/restore state ah=1c 21 | 22 | v0.6 23 | - Graphic modes 24 | - Implement the remaining functions : 25 | - read/write graphic pixel ah=0c, ah=0d, 26 | 27 | v1.0 28 | - Bugfixes 29 | 30 | 31 | Long term : 32 | ----------- 33 | 34 | v2.0 35 | - upload the fonts to the "card" memory 36 | - display fonts from the "card" memory (plex86/bochs vga card needs update) 37 | 38 | ================================================================================================= 39 | VBE: 40 | ---- 41 | Short term: 42 | - bugfixes for bochs 1.4(+) support 43 | - implement remaining functions that can be done with DISPI 0xb0c0 interface 44 | (get functions for mode?, window) 45 | 46 | Long term: 47 | - extend DISPI interface (see also bochs bug [ 529554 ] unsupported VBE features DISPI update) 48 | . clear / preserve display memory upon set vbe 49 | . set/get logical scanline length (4f06) 50 | . set/get display start (4f07) 51 | - have plex86 host side display interface 52 | - support more modi (16bit/32bit modi support) 53 | - have text io functions in vbe mode 54 | 55 | -------------------------------------------------------------------------------- /sim/xilinx/RAMB16_S1_S36_testbench.v: -------------------------------------------------------------------------------- 1 | module RAMB16_S1_S36_testbench; 2 | 3 | 4 | reg clock = 1; 5 | reg reset = 1; 6 | 7 | reg dia; 8 | reg [13:0] addra; 9 | reg ena; 10 | reg wea; 11 | wire doa; 12 | 13 | reg [31:0] dib; 14 | reg [8:0] addrb; 15 | reg enb; 16 | reg web; 17 | wire [31:0] dob; 18 | 19 | 20 | always #5 clock <= ~clock; 21 | 22 | 23 | integer count; 24 | 25 | initial begin : Init 26 | $display("Time CLK RESET DI_A ADDR_A EN_A WE_A DO_A"); 27 | $monitor("%5t %1b %1b %1b %h %1b %1b %1b", $time, clock, reset, 28 | dia, addra, ena, wea, doa); 29 | 30 | #5 31 | reset <= 0; 32 | 33 | dia <= 1; 34 | addra <= 0; 35 | ena <= 0; 36 | wea <= 0; 37 | 38 | dib <= 32'h0F3C_A5F0; 39 | addrb <= 0; 40 | enb <= 1; 41 | web <= 1; 42 | #10 43 | 44 | enb <= 0; 45 | web <= 0; 46 | ena <= 1; 47 | 48 | for (count = 32; count; count = count - 1) 49 | begin 50 | #10 51 | addra <= addra + 1; 52 | end 53 | 54 | #20 55 | $finish; 56 | end 57 | 58 | 59 | RAMB16_S1_S36 U_RAMB16_S1_S36 ( 60 | .DIA(dia), //insert 1-bit data_in 61 | .ADDRA(addra[13:0]), //insert 14-bit address bus ([13:0]) 62 | .ENA(ena), //insert enable signal 63 | .WEA(wea), //insert write enable signal 64 | .SSRA(reset), //insert set/reset signal 65 | .CLKA(clock), //insert clock signal 66 | .DOA(doa), //insert 1-bit data_out 67 | 68 | .DIB(dib), //insert 32-bit data_in bus ([31:0]) 69 | .DIPB(4'bzzzz), //insert 4-bit parity data_in bus (35:32]) 70 | .ADDRB(addrb[8:0]), //insert 9-bit address bus ([8:0]) 71 | .ENB(enb), //insert enable signal 72 | .WEB(web), //insert write enable signal 73 | .SSRB(reset), //insert set/reset signal 74 | .CLKB(clock), //insert clock signal 75 | .DOB(dob) 76 | //.DOPB() //insert 4-bit parity data_out bus ([35:32]) 77 | ); 78 | 79 | endmodule // RAMB16_S1_S36_testbench 80 | -------------------------------------------------------------------------------- /src/drv/peek.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // Currently only 4kB of memory is mapped 9 | #define MEM_SIZE 4096 10 | 11 | static int fd; 12 | 13 | int freega_open () 14 | { 15 | // Open FreeGA for read/write 16 | fd = open ("/dev/freega", O_RDWR); 17 | if (fd == -1) { 18 | printf ("Didn't work!\n"); //ERROR: (%D)\n", errno); 19 | return 1; 20 | } 21 | 22 | return 0; 23 | } 24 | 25 | void freega_close () 26 | { 27 | close (fd); // TODO: Will never get here! 28 | } 29 | 30 | 31 | unsigned long freega_read_word (int addr) 32 | { 33 | unsigned long buf; 34 | 35 | freega_open (); 36 | lseek (fd, addr*4, SEEK_SET); 37 | read (fd, (void*) &buf, 4); 38 | freega_close (); 39 | 40 | return buf; 41 | } 42 | 43 | 44 | freega_write_word (int addr, unsigned long word) 45 | { 46 | freega_open (); 47 | lseek (fd, addr*4, SEEK_SET); 48 | write (fd, (void*) &word, 4); 49 | freega_close (); 50 | } 51 | 52 | 53 | char hex_lut [16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 54 | 55 | unsigned int hexchr2uint (char c) 56 | { 57 | unsigned int i; 58 | i = ((unsigned int) toupper (c)) - 48; 59 | if (i > 9) i -= 7; 60 | if (i > 15) { 61 | printf ("ERROR: Invalid hexchar to int conversion.\n"); 62 | exit (1); 63 | } 64 | return i; 65 | } 66 | 67 | 68 | unsigned int hex2uint (char* str) 69 | { 70 | int i = 0; 71 | unsigned int d = 0; 72 | 73 | while (str [i] != '\0') 74 | d = (d << 4) | hexchr2uint (str [i++]); 75 | 76 | return d; 77 | } 78 | 79 | int main (int argc, char* argv[]) 80 | { 81 | unsigned int addr, data; 82 | if (argc != 2) { 83 | printf ("USAGE: peek \n\n"); 84 | exit (1); 85 | } 86 | 87 | addr = hex2uint (argv [1]); 88 | data = freega_read_word (addr); 89 | printf ("Data at address: 0x%x is: %x\n", addr, data); 90 | 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /sim/xilinx/XORCY.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * XORCY.v - Simulates the Xilinx primitive of the same name for use * 4 | * with Icarus Verilog. * 5 | * * 6 | * Copyright (C) 2005 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | module XORCY ( O, CI, LI ); 26 | 27 | output O; 28 | input CI, LI; 29 | 30 | assign O = CI ^ LI; 31 | 32 | endmodule // XORCY 33 | -------------------------------------------------------------------------------- /src/drv/poke.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // Currently only 4kB of memory is mapped 9 | #define MEM_SIZE 4096 10 | 11 | static int fd; 12 | 13 | int freega_open () 14 | { 15 | // Open FreeGA for read/write 16 | fd = open ("/dev/freega", O_RDWR); 17 | if (fd == -1) { 18 | printf ("Didn't work!\n"); //ERROR: (%D)\n", errno); 19 | return 1; 20 | } 21 | 22 | return 0; 23 | } 24 | 25 | void freega_close () 26 | { 27 | close (fd); // TODO: Will never get here! 28 | } 29 | 30 | 31 | unsigned long freega_read_word (int addr) 32 | { 33 | unsigned long buf; 34 | 35 | freega_open (); 36 | lseek (fd, addr*4, SEEK_SET); 37 | read (fd, (void*) &buf, 4); 38 | freega_close (); 39 | 40 | return buf; 41 | } 42 | 43 | 44 | freega_write_word (int addr, unsigned long word) 45 | { 46 | freega_open (); 47 | lseek (fd, addr*4, SEEK_SET); 48 | write (fd, (void*) &word, 4); 49 | freega_close (); 50 | } 51 | 52 | 53 | char hex_lut [16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 54 | 55 | unsigned int hexchr2uint (char c) 56 | { 57 | unsigned int i; 58 | i = ((unsigned int) toupper (c)) - 48; 59 | if (i > 9) i -= 7; 60 | if (i > 15) { 61 | printf ("ERROR: Invalid hexchar to int conversion.\n"); 62 | exit (1); 63 | } 64 | return i; 65 | } 66 | 67 | 68 | unsigned int hex2uint (char* str) 69 | { 70 | int i = 0; 71 | unsigned int d = 0; 72 | 73 | while (str [i] != '\0') 74 | d = (d << 4) | hexchr2uint (str [i++]); 75 | 76 | return d; 77 | } 78 | 79 | int main (int argc, char* argv[]) 80 | { 81 | unsigned int addr, data; 82 | if (argc != 3) { 83 | printf ("USAGE: poke \n\n"); 84 | exit (1); 85 | } 86 | 87 | addr = hex2uint (argv [1]); 88 | data = hex2uint (argv [2]); 89 | printf ("Poking address: 0x%x with: %x\n", addr, data); 90 | freega_write_word (addr, data); 91 | 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /src/drv/pokeb.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // Currently only 4kB of memory is mapped 9 | #define MEM_SIZE 4096 10 | 11 | static int fd; 12 | 13 | int freega_open () 14 | { 15 | // Open FreeGA for read/write 16 | fd = open ("/dev/freega", O_RDWR); 17 | if (fd == -1) { 18 | printf ("Didn't work!\n"); //ERROR: (%D)\n", errno); 19 | return 1; 20 | } 21 | 22 | return 0; 23 | } 24 | 25 | void freega_close () 26 | { 27 | close (fd); // TODO: Will never get here! 28 | } 29 | 30 | 31 | unsigned long freega_read_word (int addr) 32 | { 33 | unsigned long buf; 34 | 35 | freega_open (); 36 | lseek (fd, addr*4, SEEK_SET); 37 | read (fd, (void*) &buf, 4); 38 | freega_close (); 39 | 40 | return buf; 41 | } 42 | 43 | 44 | freega_write_byte (int addr, unsigned long word) 45 | { 46 | freega_open (); 47 | lseek (fd, addr, SEEK_SET); 48 | write (fd, (void*) &word, 1); 49 | freega_close (); 50 | } 51 | 52 | 53 | char hex_lut [16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 54 | 55 | unsigned int hexchr2uint (char c) 56 | { 57 | unsigned int i; 58 | i = ((unsigned int) toupper (c)) - 48; 59 | if (i > 9) i -= 7; 60 | if (i > 15) { 61 | printf ("ERROR: Invalid hexchar to int conversion.\n"); 62 | exit (1); 63 | } 64 | return i; 65 | } 66 | 67 | 68 | unsigned int hex2uint (char* str) 69 | { 70 | int i = 0; 71 | unsigned int d = 0; 72 | 73 | while (str [i] != '\0') 74 | d = (d << 4) | hexchr2uint (str [i++]); 75 | 76 | return d; 77 | } 78 | 79 | int main (int argc, char* argv[]) 80 | { 81 | unsigned int addr, data; 82 | if (argc != 3) { 83 | printf ("USAGE: poke \n\n"); 84 | exit (1); 85 | } 86 | 87 | addr = hex2uint (argv [1]); 88 | data = hex2uint (argv [2]); 89 | printf ("Poking address: 0x%x with: %x\n", addr, data); 90 | freega_write_byte (addr, data); 91 | 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /sim/xilinx/BUFG.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * BUFG.v - Replicates the functionality of the Xilinx primitive of the * 4 | * same name. * 5 | * * 6 | * Copyright (C) 2005 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | `timescale 1ns / 100ps 26 | module BUFG( I, O ); 27 | 28 | input I; 29 | output O; 30 | 31 | assign O = I; 32 | 33 | endmodule // BUFG 34 | -------------------------------------------------------------------------------- /sim/xilinx/MUXF5.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * MUXF5.v - Simulates the Xilinx primitive of the same name for use * 4 | * with Icarus Verilog. * 5 | * * 6 | * Copyright (C) 2005 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | module MUXF5 ( O, I0, I1, S ); 26 | 27 | output O; 28 | input I0, I1, S; 29 | 30 | assign O = S ? I1 : I0; 31 | 32 | endmodule // MUXF5 33 | -------------------------------------------------------------------------------- /data/vgabios-0.4c/Makefile: -------------------------------------------------------------------------------- 1 | SHELL = /bin/sh 2 | 3 | CC = gcc 4 | CFLAGS = -g -O2 -Wall -Wstrict-prototypes 5 | LDFLAGS = 6 | 7 | RELEASE = `pwd | sed "s-.*/--"` 8 | RELDATE = `date '+%d %b %Y'` 9 | RELVERS = `pwd | sed "s-.*/--" | sed "s/vgabios//" | sed "s/-//"` 10 | 11 | VGABIOS_DATE = "-DVGABIOS_DATE=\"$(RELDATE)\"" 12 | 13 | all: bios 14 | 15 | 16 | bios: vgabios.bin vgabios.debug.bin 17 | 18 | clean: 19 | /bin/rm -f *.o *.s *.ld86 \ 20 | temp.awk.* vgabios*.orig _vgabios_* _vgabios-debug_* core vgabios*.bin vgabios*.txt $(RELEASE).bin *.bak 21 | 22 | dist-clean: clean 23 | 24 | release: 25 | VGABIOS_VERS=\"-DVGABIOS_VERS=\\\"$(RELVERS)\\\"\" make bios 26 | /bin/rm -f *.o *.s *.ld86 \ 27 | temp.awk.* vgabios.*.orig _vgabios_.*.c core *.bak .#* 28 | cp VGABIOS-lgpl-latest.bin ../$(RELEASE).bin 29 | cp VGABIOS-lgpl-latest.debug.bin ../$(RELEASE).debug.bin 30 | tar czvf ../$(RELEASE).tgz --exclude CVS -C .. $(RELEASE)/ 31 | 32 | vgabios.bin: vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c vbetables.h 33 | gcc -E vgabios.c $(VGABIOS_VERS) -DVBE $(VGABIOS_DATE) > _vgabios_.c 34 | bcc -o vgabios.s -C-c -D__i86__ -S -0 _vgabios_.c 35 | sed -e 's/^\.text//' -e 's/^\.data//' vgabios.s > _vgabios_.s 36 | as86 _vgabios_.s -b vgabios.bin -u -w- -g -0 -j -O -l vgabios.txt 37 | rm -f _vgabios_.s _vgabios_.c vgabios.s 38 | mv vgabios.bin VGABIOS-lgpl-latest.bin 39 | ls -l VGABIOS-lgpl-latest.bin 40 | 41 | vgabios.debug.bin: vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c vbetables.h 42 | gcc -E vgabios.c $(VGABIOS_VERS) -DVBE -DDEBUG $(VGABIOS_DATE) > _vgabios-debug_.c 43 | bcc -o vgabios-debug.s -C-c -D__i86__ -S -0 _vgabios-debug_.c 44 | sed -e 's/^\.text//' -e 's/^\.data//' vgabios-debug.s > _vgabios-debug_.s 45 | as86 _vgabios-debug_.s -b vgabios.debug.bin -u -w- -g -0 -j -O -l vgabios.debug.txt 46 | rm -f _vgabios-debug_.s _vgabios-debug_.c vgabios-debug.s 47 | mv vgabios.debug.bin VGABIOS-lgpl-latest.debug.bin 48 | ls -l VGABIOS-lgpl-latest.debug.bin 49 | -------------------------------------------------------------------------------- /sim/xilinx/IBUF.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * IBUF.v - An output buffer of a Xilinx FPGA. * 4 | * * 5 | * Copyright (C) 2007 by Patrick Suggate * 6 | * patrick@physics.otago.ac.nz * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * This program is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with this program; if not, write to the * 20 | * Free Software Foundation, Inc., * 21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 22 | ***************************************************************************/ 23 | 24 | `timescale 1ns/100ps 25 | module IBUF (I, O); 26 | input I; 27 | output O; 28 | 29 | parameter IDELAY = 2.6; // SSTL2_II output delay is about 0.8 ns? 30 | 31 | reg O; 32 | always @(I) 33 | O <= #IDELAY I; 34 | 35 | endmodule // IBUF 36 | -------------------------------------------------------------------------------- /sim/xilinx/MUXCY.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * MUXCY.v - Simulates the Xilinx primitive of the same name for use * 4 | * with Icarus Verilog. * 5 | * * 6 | * Copyright (C) 2005 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | `timescale 1ns/100ps 26 | module MUXCY ( O, CI, DI, S ); 27 | 28 | output O; 29 | input CI, DI, S; 30 | 31 | assign O = S ? CI : DI; 32 | 33 | endmodule // MUXCY 34 | -------------------------------------------------------------------------------- /sim/xilinx/LUT3.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * LUT3.v - Simulates the Xilinx primitive of the same name for use with * 4 | * Icarus Verilog. * 5 | * * 6 | * Copyright (C) 2005 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | module LUT3 ( I0, I1, I2, O ); 26 | 27 | input I0, I1, I2; 28 | output O; 29 | 30 | parameter INIT = 8'h00; 31 | 32 | // Select bit 0-7 33 | assign O = INIT [{I2, I1, I0}]; 34 | 35 | endmodule // LUT3 36 | -------------------------------------------------------------------------------- /sim/xilinx/LUT4.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * LUT4.v - Simulates the Xilinx primitive of the same name for use with * 4 | * Icarus Verilog. * 5 | * * 6 | * Copyright (C) 2005 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | module LUT4( I0, I1, I2, I3, O ); 26 | 27 | input I0, I1, I2, I3; 28 | output O; 29 | 30 | parameter INIT = 16'h0000; 31 | 32 | // Select bit 0-15 33 | assign O = INIT[{I3, I2, I1, I0}]; 34 | 35 | endmodule // LUT4 36 | -------------------------------------------------------------------------------- /sim/xilinx/BUFGMUX.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * BUFGMUX.v - Replicates the functionality of the Xilinx primitive of * 4 | * the same name. * 5 | * * 6 | * Copyright (C) 2007 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | `timescale 1ns/100ps 26 | module BUFGMUX ( 27 | O, 28 | I0, 29 | I1, 30 | S 31 | ); 32 | 33 | output O; 34 | input I0; 35 | input I1; 36 | input S; 37 | 38 | assign O = S ? I1 : I0; 39 | 40 | endmodule // BUFGMUX 41 | -------------------------------------------------------------------------------- /src/drv/newtest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // Currently only 4kB of memory is mapped 9 | // #define MEM_SIZE 8192 10 | #define MEM_SIZE 1048576 11 | // #define MEM_SIZE 8388608 12 | #define TEST_NUM 10 13 | 14 | int freega_open (int* fp) 15 | { 16 | // Open FreeGA for read/write 17 | *fp = open ("/dev/freega", O_RDWR); 18 | if (*fp == -1) { 19 | printf ("Didn't work!\n"); //ERROR: (%D)\n", errno); 20 | return 1; 21 | } 22 | 23 | return 0; 24 | } 25 | 26 | void freega_close (int fp) 27 | { 28 | close (fp); 29 | } 30 | 31 | 32 | int freega_write_blk (const int* b, const int s, int fd, const unsigned int ad) 33 | { 34 | lseek (fd, ad, SEEK_SET); 35 | write (fd, (void*) b, s*4); 36 | return 0; 37 | } 38 | 39 | 40 | int freega_read_blk (int* b, const int s, int fd, const unsigned int ad) 41 | { 42 | lseek (fd, ad, SEEK_SET); 43 | read (fd, (void*) b, s*4); // FIXME: Do some checking! 44 | return 0; 45 | } 46 | 47 | 48 | unsigned int* rnd_blk (int* b, const int s) 49 | { 50 | int i; 51 | unsigned int* buf = (unsigned int*) b; // TODO: 64-bit safe? 52 | 53 | for (i=0; i= 2). * 4 | * * 5 | * Copyright (C) 2008 by Patrick Suggate * 6 | * patrick@physics.otago.ac.nz * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * This program is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with this program; if not, write to the * 20 | * Free Software Foundation, Inc., * 21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 22 | ***************************************************************************/ 23 | 24 | `timescale 1ns/100ps 25 | module clkdiv ( 26 | clk_i, 27 | rst_i, 28 | clk_o 29 | ); 30 | 31 | parameter CLKDIVLOG2 = 3; 32 | parameter MSB = CLKDIVLOG2 - 1; 33 | 34 | input clk_i; 35 | input rst_i; 36 | output clk_o; 37 | 38 | reg [MSB:0] cnt = 0; 39 | 40 | assign clk_o = cnt [MSB]; 41 | 42 | always @(posedge clk_i) 43 | if (rst_i) cnt <= #2 0; 44 | else cnt <= #2 cnt + 1; 45 | 46 | endmodule // clkdiv 47 | -------------------------------------------------------------------------------- /sim/xilinx/RAMB16_S9_S36_testbench.v: -------------------------------------------------------------------------------- 1 | module RAMB16_S9_S36_testbench; 2 | 3 | 4 | reg clock = 1; 5 | reg reset = 1; 6 | 7 | reg [7:0] dia; 8 | reg [10:0] addra; 9 | reg ena; 10 | reg wea; 11 | wire [7:0] doa; 12 | 13 | reg [31:0] dib; 14 | reg [8:0] addrb; 15 | reg enb; 16 | reg web; 17 | wire [31:0] dob; 18 | 19 | 20 | always #5 clock <= ~clock; 21 | 22 | 23 | integer count; 24 | 25 | initial begin : Init 26 | $display("Time CLK RESET DI_A ADDR_A EN_A WE_A DO_A"); 27 | $monitor("%5t %1b %1b %1b %h %1b %1b %h", $time, clock, reset, 28 | dia, addra, ena, wea, doa); 29 | 30 | #5 31 | reset <= 0; 32 | 33 | dia <= 8'hA5; 34 | addra <= 0; 35 | ena <= 1; 36 | wea <= 1; 37 | 38 | enb <= 0; 39 | web <= 0; 40 | 41 | /* dib <= 32'h0F3C_A5F0; 42 | addrb <= 0; 43 | enb <= 1; 44 | web <= 1;*/ 45 | 46 | 47 | for (count = 32; count; count = count - 1) 48 | begin 49 | #10 50 | dia <= ~dia; 51 | addra <= addra + 1; 52 | end 53 | 54 | #10 55 | enb <= 0; 56 | web <= 0; 57 | ena <= 1; 58 | wea <= 0; 59 | addra <= 0; 60 | 61 | for (count = 32; count; count = count - 1) 62 | begin 63 | #10 64 | addra <= addra + 1; 65 | end 66 | 67 | #20 68 | $finish; 69 | end 70 | 71 | 72 | RAMB16_S9_S36 block_ram0 ( 73 | .DIA(dia), //insert 1-bit data_in 74 | .DIPA(1'bz), 75 | .ADDRA(addra[10:0]), //insert 14-bit address bus ([13:0]) 76 | .ENA(ena), //insert enable signal 77 | .WEA(wea), //insert write enable signal 78 | .SSRA(reset), //insert set/reset signal 79 | .CLKA(clock), //insert clock signal 80 | .DOA(doa), //insert 1-bit data_out 81 | //.DOPA(), 82 | 83 | .DIB(dib), //insert 32-bit data_in bus ([31:0]) 84 | .DIPB(4'bzzzz), //insert 4-bit parity data_in bus (35:32]) 85 | .ADDRB(addrb[8:0]), //insert 9-bit address bus ([8:0]) 86 | .ENB(enb), //insert enable signal 87 | .WEB(web), //insert write enable signal 88 | .SSRB(reset), //insert set/reset signal 89 | .CLKB(clock), //insert clock signal 90 | .DOB(dob) 91 | //.DOPB() //insert 4-bit parity data_out bus ([35:32]) 92 | ); 93 | 94 | endmodule // RAMB16_S9_S36_testbench 95 | -------------------------------------------------------------------------------- /sim/xilinx/OBUFT.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * OBUFT.v - An output tristate buffer for a Xilinx FPGA. * 4 | * * 5 | * Copyright (C) 2007 by Patrick Suggate * 6 | * patrick@physics.otago.ac.nz * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * This program is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with this program; if not, write to the * 20 | * Free Software Foundation, Inc., * 21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 22 | ***************************************************************************/ 23 | 24 | `timescale 1ns/100ps 25 | module OBUFT (I, T, O); 26 | input I; 27 | input T; 28 | output O; 29 | 30 | parameter SLEW = "SLOW" ; 31 | parameter IOSTANDARD = "LVCMOS33" ; 32 | parameter DRIVE = 12 ; 33 | 34 | parameter ODELAY = 9.0; // SSTL2_II output delay is about 4.6 ns? 35 | parameter ZDELAY = 1.0; 36 | 37 | reg O; 38 | always @(I, T) 39 | if (T) O <= #ZDELAY 1'bz; 40 | else O <= #ODELAY I; 41 | 42 | endmodule // OBUFT 43 | -------------------------------------------------------------------------------- /src/drv/set.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // Currently only 4kB of memory is mapped 9 | #define MEM_SIZE 4096 10 | 11 | static int fd; 12 | 13 | int freega_open () 14 | { 15 | // Open FreeGA for read/write 16 | fd = open ("/dev/freega", O_RDWR); 17 | if (fd == -1) { 18 | printf ("Didn't work!\n"); //ERROR: (%D)\n", errno); 19 | return 1; 20 | } 21 | 22 | return 0; 23 | } 24 | 25 | void freega_close () 26 | { 27 | close (fd); // TODO: Will never get here! 28 | } 29 | 30 | 31 | unsigned long freega_read_word (int addr) 32 | { 33 | unsigned long buf; 34 | 35 | freega_open (); 36 | lseek (fd, addr*4, SEEK_SET); 37 | read (fd, (void*) &buf, 4); 38 | freega_close (); 39 | 40 | return buf; 41 | } 42 | 43 | 44 | freega_write_word (int addr, unsigned long word) 45 | { 46 | freega_open (); 47 | lseek (fd, addr*4, SEEK_SET); 48 | write (fd, (void*) &word, 4); 49 | freega_close (); 50 | } 51 | 52 | 53 | unsigned long* freega_get (unsigned long* ar, int n) 54 | { 55 | int i; 56 | for (i=0; i=0; j-=4) 70 | printf ("%c", (hex_lut [(v >> j) & 0x0F])); 71 | printf ("\n"); 72 | } 73 | } 74 | 75 | 76 | int main (int argc, char* argv[]) 77 | { 78 | int fd, i = 0; 79 | static unsigned long ar [20]; 80 | unsigned int a, b; 81 | char my_data [256]; 82 | FILE* f; 83 | 84 | if (argc != 2) { 85 | printf ("USAGE: set \n\n"); 86 | exit (1); 87 | } 88 | 89 | f = fopen (argv [1], "r"); 90 | fscanf (f, "%x:%x", &a, &b); 91 | while (!feof (f)) { 92 | #ifdef __debug 93 | printf ("%x:%x\n", a, b); 94 | #endif 95 | freega_write_word (i++, b); 96 | fscanf (f, "%x:%x", &a, &b); 97 | } 98 | 99 | hex_dump (freega_get (ar, 20), 20); 100 | 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The OpenVGA Open Graphics Adapter # 2 | 3 | OpenVGA was an M.Sc project in the Elec Research Group at the University of Otago by Patrick Suggate under the supervision of Tim Molteno. 4 | 5 | OpenVGA is licensed under the GPL v3. 6 | 7 | Copyright 2009 Patrick Suggate 8 | 9 | 10 | 11 | ## What is OpenVGA? ## 12 | 13 | OpenVGA is an open-source hardware graphics adapter project. The project has a PCB design, the Verilog describing the logic within the FPGA (including processors, a memory controller, a PCI to Wishbone bridge, and a fast data-cache), a simple Linux kernel module, and some miscellaneous tools. The tools include a TTA assembler, the RISC16 assembler, a CRT simulator, and some scripts for data conversion tasks. 14 | 15 | Currently OpenVGA will display data written to it, via the PCI bus, on an attached VGA monitor. Some more work is needed to allow it to function as a PC's primary display adapter. This is mostly firmware plus a tweak to the PCI bridge so that it will request to be a VGA device on system startup. 16 | 17 | Also included in this package are components developed by others: 18 | - A VGA BIOS release, with the current version available from http://www.nongnu.org/vgabios/ 19 | - TTA assembler, written in the Mercury programming language, developed by Roy Ward who was a Ph.D student in the Elec Research Group 20 | 21 | 22 | 23 | ## Verilog Source Simulation and Synthesis Instructions ## 24 | 25 | ### Software Requirements: 26 | 27 | - Icarus Verilog for simulation. 28 | - GtkWave for displaying created waveforms. 29 | - Xilinx synthesis toolchain, currently expected to be installed to `/opt/Xilinx' 30 | The following line within rtl/makefile needs to modified if the location is different: 31 | export XILINX#/opt/Xilinx 32 | - A working Mercury compiler install if the TTA assembler needs to be (re)built, a working binary is contained within the `bin' folder though. 33 | - A working Python setup is needed to run the Python scripts within the `tools' folder. wxPython is needed to run a couple of these scripts too. 34 | - The `m4' macro processor is needed for assembling also. 35 | 36 | ### Building 37 | 38 | - Synthesising: 39 | make 40 | 41 | - To simulate: 42 | make icarus 43 | 44 | - Assembling: 45 | make assemble 46 | -------------------------------------------------------------------------------- /sim/lib/wb_sync_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module wb_sync_tb; 3 | 4 | 5 | reg clka = 1; 6 | always #5 clka = ~clka; 7 | 8 | reg clkb = 1; 9 | always #15 clkb = ~clkb; 10 | 11 | reg wb_rst = 0; 12 | 13 | wire b_cyc, b_stb, b_we; 14 | wire [24:0] b_adr; 15 | wire [3:0] b_sel; 16 | wire [31:0] b_dat; 17 | reg b_ack = 0; 18 | 19 | wire a_ack; 20 | wire [1:0] self; 21 | wire [15:0] datf; 22 | reg a_stb = 0; 23 | reg a_we = 0; 24 | reg [1:0] a_sel = 4'b11; 25 | reg [15:0] a_dat; 26 | reg [25:0] a_adr; 27 | 28 | 29 | initial begin : Sim 30 | $dumpfile ("tb.vcd"); 31 | $dumpvars; 32 | 33 | #2 wb_rst = 1; 34 | #20 wb_rst = 0; 35 | 36 | #20 a_stb = 1; 37 | while (!a_ack) #10; 38 | a_stb = 0; 39 | 40 | #10 a_stb = 1; 41 | while (!a_ack) #10; 42 | a_stb = 0; 43 | 44 | #10 a_stb = 1; a_we = 1; 45 | while (!a_ack) #10; 46 | a_stb = 0; a_we = 0; 47 | 48 | #10 a_stb = 1; a_we = 1; 49 | while (!a_ack) #10; 50 | a_stb = 0; a_we = 0; 51 | 52 | #300 $finish; 53 | end // Sim 54 | 55 | initial #4000 $finish; 56 | 57 | 58 | always @(posedge a_stb) 59 | a_dat <= #2 $random; 60 | 61 | always @(posedge a_stb) 62 | a_adr <= #2 $random; 63 | 64 | 65 | // Another dummy WB module. 66 | always @(posedge clkb) 67 | if (!b_ack && b_cyc && b_stb) 68 | b_ack <= #32 1; 69 | else 70 | b_ack <= #2 0; 71 | 72 | 73 | wb_sync #( 74 | .HIGHZ (0), 75 | .CWIDTH (16), 76 | .WWIDTH (32), 77 | .ADDRESS (25) 78 | ) SYNC0 ( 79 | .wb_rst_i (wb_rst), 80 | 81 | .a_clk_i (clka), 82 | .a_cyc_i (a_stb), 83 | .a_stb_i (a_stb), 84 | .a_we_i (a_we), 85 | .a_ack_o (a_ack), 86 | .a_rty_o (), 87 | .a_err_o (), 88 | .a_cti_i (0), // Single-word transfers 89 | .a_bte_i (0), 90 | .a_adr_i (a_adr), 91 | .a_sel_i (a_sel), 92 | .a_dat_i (a_dat), 93 | .a_sel_o (self), 94 | .a_dat_o (datf), 95 | 96 | .b_clk_i (clkb), 97 | .b_cyc_o (b_cyc), 98 | .b_stb_o (b_stb), 99 | .b_we_o (b_we), 100 | .b_ack_i (b_ack), 101 | .b_rty_i (0), 102 | .b_err_i (0), 103 | .b_cti_o (), // Single-word transfers 104 | .b_bte_o (), 105 | .b_adr_o (b_adr), 106 | .b_sel_i (0), 107 | .b_dat_i (0), 108 | .b_sel_o (b_sel), 109 | .b_dat_o (b_dat) 110 | ); 111 | 112 | 113 | endmodule // wb_sync_tb 114 | -------------------------------------------------------------------------------- /rtl/lib/mux/mux4to1.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * mux4to1.v - A simple combinatorial four-to-one multiplexer. * 4 | * * 5 | * Copyright (C) 2006 by Patrick Suggate * 6 | * patrick@physics.otago.ac.nz * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * This program is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with this program; if not, write to the * 20 | * Free Software Foundation, Inc., * 21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 22 | ***************************************************************************/ 23 | 24 | `timescale 1ns/100ps 25 | module mux4to1 #( 26 | parameter WIDTH = 16, 27 | parameter MSB = WIDTH - 1 28 | ) ( 29 | input [1:0] sel_i, 30 | 31 | input [MSB:0] in0_i, 32 | input [MSB:0] in1_i, 33 | input [MSB:0] in2_i, 34 | input [MSB:0] in3_i, 35 | 36 | output reg [MSB:0] out_o 37 | ); 38 | 39 | always @* 40 | case (sel_i) 41 | 2'b00: out_o <= #3 in0_i; 42 | 2'b01: out_o <= #3 in1_i; 43 | 2'b10: out_o <= #3 in2_i; 44 | 2'b11: out_o <= #3 in3_i; 45 | endcase 46 | 47 | endmodule // mux4to1 48 | -------------------------------------------------------------------------------- /sim/xilinx/FDRSE.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * FDRSE.v - Replicates the functionality of the Xilinx primitive of the * 4 | * same name. * 5 | * * 6 | * Copyright (C) 2008 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | // D-type Flip-flop with reset, set and clock enable. 26 | `timescale 1ns/100ps 27 | module FDRSE ( C, D, Q, R, S, CE ); 28 | 29 | input C; 30 | input D; 31 | output Q; 32 | input R; 33 | input S; 34 | input CE; 35 | 36 | parameter INIT = 1'b0; 37 | reg Q = INIT; 38 | 39 | always @(posedge C) 40 | if (R) 41 | Q <= #1 1'b0; 42 | else if (S) 43 | Q <= #1 1'b1; 44 | else if (CE) 45 | Q <= #1 D; 46 | 47 | endmodule // FDRSE 48 | -------------------------------------------------------------------------------- /sim/xilinx/MULT18X18S.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * MULT18X18S.v - Simulates the Xilinx primitive of the same name for * 4 | * use with Icarus Verilog. * 5 | * * 6 | * Copyright (C) 2005 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | module MULT18X18S( 26 | A, B, P, C, CE, R 27 | ); 28 | 29 | input [17:0] A, B; // 2's complement integers 30 | output [35:0] P; // 2's complement product 31 | 32 | input C; // Clock 33 | input CE; // Clock enable 34 | input R; // Synchronous reset 35 | 36 | reg [35:0] P = 0; 37 | 38 | always @(posedge C) 39 | begin 40 | if (R) begin 41 | P <= 0; 42 | end 43 | else begin 44 | if (~CE) 45 | P <= P; 46 | else 47 | P <= A * B; 48 | end 49 | end 50 | 51 | endmodule // MULT18X18S 52 | -------------------------------------------------------------------------------- /sim/xilinx/FDCE.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * FDCE.v - Emulates the functionality of the Xilinx primitive of the * 4 | * same name. This a really poor partial implementation so do not use * 5 | * as it is only designed to do some very basic things. * 6 | * * 7 | * Copyright (C) 2005 by Patrick Suggate * 8 | * patrick@physics.otago.ac.nz * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 2 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 24 | ***************************************************************************/ 25 | 26 | `timescale 1ns/100ps 27 | module FDCE( 28 | C, // Clock 29 | CE, // Clock enable 30 | CLR, // Asynchronous clear 31 | D, // Data in 32 | Q // Data out 33 | ); 34 | 35 | input C; 36 | input CE; 37 | input CLR; 38 | input D; 39 | output Q; 40 | 41 | parameter INIT = 1'b0; 42 | reg Q = INIT; 43 | 44 | always @(posedge C or posedge CLR) 45 | if (CLR) 46 | Q <= #1 1'b0; 47 | else if (CE) 48 | Q <= #1 D; 49 | else 50 | Q <= #1 Q; 51 | 52 | endmodule // FDCE 53 | -------------------------------------------------------------------------------- /sim/xilinx/LUT6.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * LUT6.v - Simulates the Xilinx (Virtex5) primitive of the same name * 4 | * for use with Icarus Verilog. * 5 | * * 6 | * WILL NOT SYNTHESISE! * 7 | * * 8 | * Copyright (C) 2007 by Patrick Suggate * 9 | * patrick@physics.otago.ac.nz * 10 | * * 11 | * This program is free software; you can redistribute it and/or modify * 12 | * it under the terms of the GNU General Public License as published by * 13 | * the Free Software Foundation; either version 2 of the License, or * 14 | * (at your option) any later version. * 15 | * * 16 | * This program is distributed in the hope that it will be useful, * 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 19 | * GNU General Public License for more details. * 20 | * * 21 | * You should have received a copy of the GNU General Public License * 22 | * along with this program; if not, write to the * 23 | * Free Software Foundation, Inc., * 24 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 25 | ***************************************************************************/ 26 | 27 | `timescale 1ns/100ps 28 | module LUT6 (O, I0, I1, I2, I3, I4, I5); 29 | 30 | parameter INIT = 64'h0000_0000_0000_0000; 31 | output O; 32 | input I0, I1, I2, I3, I4, I5; 33 | 34 | reg O; 35 | reg lut_rom [0:63]; 36 | 37 | integer i; 38 | initial begin : Init 39 | for (i=0; i<64; i=i+1) 40 | lut_rom [i] = INIT [i]; 41 | end // Init 42 | 43 | always @(I5, I4, I3, I2, I1, I0) 44 | O <= lut_rom [{I5, I4, I3, I2, I1, I0}]; 45 | 46 | endmodule // LUT6 47 | -------------------------------------------------------------------------------- /sim/xilinx/RAM16X1S.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * RAM16X1S.v - Emulates the functionality of the Xilinx primitive of the* 4 | * same name. This a really poor partial implementation so do not use * 5 | * as it is only designed to do some very basic things. * 6 | * * 7 | * Copyright (C) 2008 by Patrick Suggate * 8 | * patrick@physics.otago.ac.nz * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 2 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 24 | ***************************************************************************/ 25 | 26 | `timescale 1ns / 100ps 27 | module RAM16X1S( 28 | input D, 29 | input WE, 30 | input WCLK, 31 | input A0, 32 | input A1, 33 | input A2, 34 | input A3, 35 | output O 36 | ); 37 | 38 | reg dat [15:0]; 39 | wire [3:0] addr = {A0, A1, A2, A3}; 40 | 41 | assign O = dat[addr]; 42 | 43 | // Write incoming data to the RAM. 44 | always @(posedge WCLK) 45 | if (WE) dat[addr] <= D; 46 | 47 | integer ii; 48 | initial begin : Init 49 | for (ii=0; ii<16; ii=ii+1) 50 | dat[ii] = 0; 51 | end // Init 52 | 53 | endmodule // RAM16X1S 54 | -------------------------------------------------------------------------------- /src/assembler/assemble.m: -------------------------------------------------------------------------------- 1 | :- module assemble. 2 | :- interface. 3 | :- import_module io. 4 | 5 | :- pred main(io__state::di, io__state::uo) is det. 6 | 7 | :- implementation. 8 | 9 | :- import_module io, xml, xml_util, exception, string, atoken, aparse, list, asm, prettyprint, map, asm_out, char,config_asm. 10 | 11 | main(!S) :- 12 | % get command line args 13 | io__command_line_arguments(Args,!S), 14 | ( Args = [SS] -> Sarg=SS; throw("Usage: ./assemble ")), 15 | io.write_string("Reading file\n",!S), 16 | io.open_input(Sarg, ResultArg,!S), 17 | ( ResultArg = ok(ST) -> Stream=ST ; throw("Error reading input file" ++ Sarg)), 18 | io.set_input_stream(Stream,_OldStream,!S), 19 | io.read_file(Contentx,!S), 20 | ( Contentx = ok(Content); Contentx = error(Content,_Error3), throw("Error reading input file" ++ Sarg)), 21 | io.close_input(Stream,!S), 22 | io.write_string("Getting tokens\n",!S), 23 | atoken.get_token_list(Tokens,1,Content,_), 24 | %list.map(token_pair_to_string,Tokens,S1), 25 | %io.write_strings(S1,!S), 26 | io.write_string("Parsing program\n",!S), 27 | parse_program(Config,Sarg,Program,!S,Tokens,_), 28 | %number_lines(Config,Program,P2,1,init,Labels), 29 | %encode(Config,P2,P3,Labels), 30 | P3=Program, 31 | io.write_string("Parsed program\n",!S), 32 | 33 | DebugName=rstrip(is_alnum,Sarg)++"debug", 34 | fromstring(Sti,"",pretty), 35 | io.write_string("Printing debug file\n",!S), 36 | print_program(Config,P3,Sti,Sto), 37 | tostring(Sto,So), 38 | io.open_output(DebugName, DebugArg,!S), 39 | ( DebugArg = ok(SD) -> DebugStream=SD ; throw("Error writing debug file" ++ DebugName)), 40 | io.set_output_stream(DebugStream,Old1,!S), 41 | io.write_string(So,!S), 42 | io.close_output(DebugStream,!S), 43 | io.set_output_stream(Old1,_,!S), 44 | 45 | OutName=rstrip(is_alnum,Sarg)++"out", 46 | asm_to_out(Config,P3,Out1), 47 | sort_out(Out1,Out2), 48 | io.write_string("Packing\n",!S), 49 | pack(0,Config^model^program_output_min_size,Out2,Out3), 50 | fromstring(Sti2,"",pretty), 51 | io.write_string("Printing out file\n",!S), 52 | io.write_string("Printing out 1\n",!S), 53 | print_out(Config,Out3,Sti2,Sto2), 54 | io.write_string("Printing out 2\n",!S), 55 | tostring(Sto2,So2), 56 | io.open_output(OutName, OutArg,!S), 57 | ( OutArg = ok(SA) -> OutStream=SA ; throw("Error writing debug file" ++ OutName)), 58 | io.set_output_stream(OutStream,Old2,!S), 59 | io.write_string(So2,!S), 60 | io.close_output(OutStream,!S), 61 | io.set_output_stream(Old2,_,!S), 62 | 63 | io.write_string("Done\n",!S). 64 | 65 | -------------------------------------------------------------------------------- /sim/xilinx/MUXF7.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * MUXF7.v - Simulates the Xilinx primitive of the same name for use * 4 | * with Icarus Verilog. * 5 | * * 6 | * Copyright (C) 2005 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | `timescale 1ns/100ps 26 | module MUXF7 #( 27 | parameter DELAY = 1.5 28 | ) ( 29 | output O, 30 | input I0, 31 | input I1, 32 | input S 33 | ); 34 | 35 | assign #1.5 O = S ? I1 : I0; 36 | 37 | endmodule // MUXF7 38 | 39 | module MUXF7_D #( 40 | parameter DELAY = 1.5 41 | ) ( 42 | output O, 43 | output LO, 44 | input I0, 45 | input I1, 46 | input S 47 | ); 48 | 49 | assign #1.5 O = S ? I1 : I0; 50 | assign #1.5 LO = S ? I1 : I0; 51 | 52 | endmodule // MUXF7_D 53 | 54 | module MUXF7_L #( 55 | parameter DELAY = 1.5 56 | ) ( 57 | output LO, 58 | input I0, 59 | input I1, 60 | input S 61 | ); 62 | 63 | assign #1.5 LO = S ? I1 : I0; 64 | 65 | endmodule // MUXF7_L 66 | -------------------------------------------------------------------------------- /rtl/cache/cache_bram.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * cache_bram.v - Cache memory stored in Xilinx Block RAMs. * 4 | * * 5 | * Copyright (C) 2008 by Patrick Suggate * 6 | * patrick@physics.otago.ac.nz * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * This program is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with this program; if not, write to the * 20 | * Free Software Foundation, Inc., * 21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 22 | ***************************************************************************/ 23 | 24 | // Very low-tech wrapper to allow using different port widths. 25 | `timescale 1ns/100ps 26 | module cache_bram ( 27 | input reset_i, 28 | 29 | input u_clk_i, 30 | input u_write_i, // TODO: Add eviction support 31 | input [8:0] u_addr_i, 32 | input [31:0] u_data_i, 33 | 34 | input l_clk_i, 35 | input [9:0] l_addr_i, 36 | input l_write_i, 37 | input [15:0] l_data_i, // TODO 38 | output [15:0] l_data_o 39 | ); 40 | 41 | RAMB16_S18_S36 BRAM0 ( 42 | .CLKA (l_clk_i), 43 | .ENA (1'b1), 44 | .SSRA (1'b0), 45 | .WEA (l_write_i), 46 | .ADDRA (l_addr_i), 47 | .DOA (l_data_o), 48 | .DIA (l_data_i), 49 | .DIPA (2'b11), 50 | 51 | .CLKB (u_clk_i), 52 | .ENB (1'b1), 53 | .SSRB (1'b0), 54 | .WEB (u_write_i), 55 | .ADDRB (u_addr_i), 56 | .DIB (u_data_i), 57 | .DIPB (4'b1111) 58 | ); 59 | 60 | endmodule // cache_bram 61 | -------------------------------------------------------------------------------- /rtl/cpu/risc16/risc_rf.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * risc_rf.v - Register file suitable for a RISC, 2 read, 1 write port. * 4 | * * 5 | * Copyright (C) 2008 by Patrick Suggate * 6 | * patrick@physics.otago.ac.nz * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * This program is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with this program; if not, write to the * 20 | * Free Software Foundation, Inc., * 21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 22 | ***************************************************************************/ 23 | 24 | `timescale 1ns/100ps 25 | module risc_rf_async #( 26 | parameter WIDTH = 16, 27 | parameter DEPTH = 4, 28 | parameter WORDS = 1 << DEPTH, 29 | parameter MSB = WIDTH - 1, 30 | parameter ISB = DEPTH - 1 31 | ) ( 32 | input clock_i, 33 | 34 | input [ISB:0] p0_idx_i, 35 | output [MSB:0] p0_dat_o, 36 | 37 | input [ISB:0] p1_idx_i, 38 | output [MSB:0] p1_dat_o, 39 | 40 | input wr_en_i, 41 | input [ISB:0] wr_idx_i, 42 | input [MSB:0] wr_dat_i 43 | ); 44 | 45 | reg [MSB:0] bank0 [WORDS-1:0]; 46 | reg [MSB:0] bank1 [WORDS-1:0]; 47 | 48 | assign #2 p0_dat_o = bank0[p0_idx_i]; 49 | assign #2 p1_dat_o = bank1[p1_idx_i]; 50 | 51 | integer ii; 52 | initial for (ii=0; ii - Number of columns 9 | # -s - Select the column to output [1->(n-1)] 10 | # -v - Verbose. 11 | # 12 | # Example: 13 | # out2v.py -n 2 -s 0 test.out tta_asm0.v 14 | # out2v.py -n 2 -s 1 test.out tta_asm1.v 15 | # 16 | # TODO: Parity info. 17 | # 18 | import sys 19 | 20 | cols = 4 21 | sel = -1 # All 22 | mode = 'normal' 23 | 24 | if sys.argv[1] == '-n': 25 | cols = int(sys.argv[2]) 26 | del sys.argv[1:3] 27 | 28 | if sys.argv[1] == '-s': 29 | sel = int(sys.argv[2]) 30 | del sys.argv[1:3] 31 | 32 | if sys.argv[1] == '-v': 33 | mode = 'verbose' 34 | del sys.argv[1] 35 | 36 | if len (sys.argv) < 3 : 37 | sys.stderr.write ("USAGE: out2v [options] \n") 38 | sys.exit (1) 39 | 40 | fi = open (sys.argv [1], "r") 41 | fo = open (sys.argv [2], "w") 42 | 43 | # Read in data 44 | tline = fi.readline () 45 | hdata = [] 46 | while tline != '' : 47 | tline = tline.split (":")[1].strip() 48 | hline = [] 49 | mult = len (tline) / cols 50 | 51 | # Little endian 52 | for i in range ((cols-1)*mult, -1, -mult) : 53 | hline.append (tline [i:i+mult]) 54 | 55 | hdata.append (hline) 56 | tline = fi.readline () 57 | 58 | fi.close () 59 | 60 | # Perform 2D array transpose 61 | ndata = [] 62 | for i in range (0, len (hdata [0])) : 63 | ndata.append ([]) 64 | for j in range (0, len (hdata)) : 65 | ndata[i].append (hdata[j][i]) 66 | 67 | if mode=='verbose': 68 | print ndata 69 | 70 | def vdump(fh, dat): 71 | ln = 0 72 | while len(dat) > 0: 73 | so = "\t.INIT_" + hex(ln)[2:].rjust(2,'0').upper() + "\t(256'h" 74 | grab = len(dat) 75 | lim = 64/len(dat[0])-1 76 | if grab > lim: 77 | grab = lim 78 | 79 | for a in range(grab, -1, -1): 80 | so += dat.pop(a) 81 | if len(dat) > 0: 82 | so += "),\n" 83 | else: 84 | so += ")\n" 85 | fh.write(so) 86 | ln += 1 87 | 88 | if sel==-1: # Dump-all 89 | for a in range(cols): 90 | vdump(fo, ndata[a]) 91 | else: 92 | vdump(fo, ndata[sel]) 93 | 94 | ## Concat all the sub-strings into single strings, max length of 256-bit. 95 | #maxlen = len (ndata [0]) 96 | #if maxlen > (64 / len (ndata [0][0])) : 97 | #maxlen = 64 / len (ndata [0][0]) 98 | #for i in range (len (ndata)-1, -1, -1) : 99 | #fo.write ("parameter\tINIT_LINE0"+chr(64+cols-i)+"\t= 256'h") 100 | #for j in range (maxlen-1, -1, -1) : 101 | #fo.write (ndata [i][j]) 102 | ##ndata [i][j].pop() 103 | #fo.write (";\n") 104 | 105 | fo.close () 106 | print "Done" 107 | -------------------------------------------------------------------------------- /src/r16asm/CodeCleaner.py: -------------------------------------------------------------------------------- 1 | ############################################################################ 2 | # Copyright (C) 2005 by Patrick Suggate # 3 | # patrick@physics.otago.ac.nz # 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; either version 2 of the License, or # 8 | # (at your option) any later version. # 9 | # # 10 | # This program is distributed in the hope that it will be useful, # 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 13 | # GNU General Public License for more details. # 14 | # # 15 | # You should have received a copy of the GNU General Public License # 16 | # along with this program; if not, write to the # 17 | # Free Software Foundation, Inc., # 18 | # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # 19 | ############################################################################ 20 | 21 | # Removes comments 22 | class CodeCleaner: 23 | def clean(self, fi): 24 | lines = fi.readlines() 25 | lines = self.addLineNumbers(lines) 26 | #if self.cleanMultiLineComments: 27 | #lines = self.removeMultiLineComments(lines) 28 | if self.cleanSingleLineComments: 29 | lines = self.removeSingleLineComments(lines) 30 | if self.cleanWhitespaces: 31 | lines = self.removeWhitespaces(lines) 32 | return lines 33 | 34 | def addLineNumbers(self, lines): 35 | oLines = [] 36 | n = 1 37 | for line in lines: 38 | oLines.append([n, line]) 39 | n += 1 40 | return oLines 41 | 42 | def removeSingleLineComments(self, lineList): 43 | outLines = [] 44 | for line in lineList: 45 | pos = line[1].find(self.singleLineComment) 46 | if pos != -1: 47 | outLines.append([line[0], line[1][0:pos]]) 48 | else: 49 | outLines.append(line) 50 | return outLines 51 | 52 | def removeWhitespaces(self, lineList): 53 | lines = map(lambda l: [l[0], l[1].strip()], lineList) 54 | return filter(lambda l: len(l[1]) > 0, lines) 55 | 56 | singleLineComment = ";" 57 | multiLineCommentStart = "/*" 58 | multiLineCommentEnd = "*/" 59 | cleanSingleLineComments = True; 60 | cleanMultiLineComments = False; # TODO 61 | cleanWhitespaces = True; 62 | # endclass CodeCleaner 63 | -------------------------------------------------------------------------------- /rtl/video/video_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module video_tb; 3 | 4 | parameter WIDTH = 32; 5 | parameter ADDRESS = 21; 6 | parameter FBSIZE = 18; 7 | 8 | parameter MSB = WIDTH - 1; 9 | parameter ASB = ADDRESS - 1; 10 | 11 | 12 | reg clock = 1; 13 | always #10 clock <= ~clock; // 50 MHz 14 | 15 | reg mem_clk = 1; 16 | always #7.5 mem_clk <= ~mem_clk; // 66.667 MHz 17 | 18 | reg cpu_clk = 1; 19 | always #3 cpu_clk <= ~cpu_clk; // 167 MHz 20 | 21 | wire dot_clk, chr_clk; 22 | reg reset_n = 1; 23 | 24 | wire hsync, vsync, de; 25 | wire [7:0] red, green, blue; 26 | 27 | 28 | initial begin : Sim 29 | $write ("%% "); 30 | $dumpfile ("tb.vcd"); 31 | $dumpvars;// (1, CNTRL0, ddr_cke); 32 | 33 | #5 reset_n <= 0; 34 | #200 reset_n <= 1; 35 | 36 | #60000 37 | $finish; 38 | end // Sim 39 | 40 | 41 | wire v_read, v_rack, v_ready; 42 | wire [ASB:0] v_addr; 43 | wire [MSB:0] v_data_from; 44 | 45 | vga_top #( 46 | .WIDTH (WIDTH), 47 | .ADDRESS (ADDRESS), 48 | .FBSIZE (FBSIZE) 49 | ) VGATOP0 ( 50 | .sys_clk_i (clock), 51 | .cpu_clk_i (cpu_clk), 52 | .mem_clk_i (mem_clk), 53 | .dot_clk_o (dot_clk), 54 | .chr_clk_o (chr_clk), 55 | .reset_ni (reset_n), 56 | 57 | .mem_read_o (v_read), 58 | .mem_rack_i (v_rack), 59 | .mem_ready_i (v_ready), 60 | .mem_addr_o (v_addr), 61 | .mem_data_i (v_data_from), 62 | 63 | .hsync_o (hsync), 64 | .vsync_o (vsync), 65 | .red_o (red), 66 | .green_o (green), 67 | .blue_o (blue), 68 | .de_o (de) 69 | ); 70 | 71 | 72 | wire b_read, b_write, b_rack, b_wack, b_busy; 73 | wire [3:0] b_bes_n; 74 | wire [ASB:0] b_addr; 75 | wire [MSB:0] b_data_to; 76 | reg b_ready = 0; 77 | reg [MSB:0] b_data_from; 78 | 79 | burst_ctrl #( 80 | .WIDTH (WIDTH), 81 | .ADDRESS (ADDRESS), 82 | .BURST (8), 83 | .BBITS (3) 84 | ) BC0 ( 85 | .clock_i (mem_clk), 86 | .reset_ni (reset_n), 87 | 88 | .usr_read_i (v_read), 89 | .usr_write_i (0), 90 | .usr_rack_o (v_rack), 91 | .usr_wack_o (), 92 | .usr_ready_o (v_ready), 93 | .usr_busy_o (), 94 | .usr_addr_i (v_addr), 95 | .usr_bes_ni (4'hF), 96 | .usr_data_i (0), 97 | .usr_data_o (v_data_from), 98 | 99 | .mem_read_o (b_read), 100 | .mem_write_o (b_write), 101 | .mem_rack_i (b_rack), 102 | .mem_wack_i (b_wack), 103 | .mem_ready_i (b_ready), 104 | .mem_busy_i (b_busy), 105 | .mem_addr_o (b_addr), 106 | .mem_bes_no (b_bes_n), 107 | .mem_data_o (b_data_to), 108 | .mem_data_i (b_data_from) 109 | ); 110 | 111 | 112 | // Random data makeriser!! 113 | assign b_rack = b_read; 114 | assign b_wack = b_write; // Bottomless trap hole 115 | assign b_busy = 0; 116 | 117 | always @(posedge mem_clk) 118 | if (!reset_n) b_ready <= #2 0; 119 | else b_ready <= #2 b_read; 120 | 121 | always @(posedge mem_clk) 122 | if (!reset_n) b_data_from <= #2 0; 123 | else if (b_read) b_data_from <= #2 $random; 124 | 125 | 126 | endmodule // video_tb 127 | -------------------------------------------------------------------------------- /sim/pci/cfgspace_tb.v: -------------------------------------------------------------------------------- 1 | module cfgspace_tb; 2 | 3 | reg clock = 1; 4 | always #15 clock <= ~clock; 5 | 6 | reg reset_n = 1; 7 | 8 | 9 | reg frame_n = 1; 10 | wire devsel_n; 11 | reg irdy_n = 1; 12 | wire trdy_n; 13 | reg [3:0] cbe_n = 4'hF; 14 | reg [31:0] ad; 15 | wire [31:0] data; 16 | reg idsel = 0; 17 | 18 | wire active; // Controls the output muxes and tri-states 19 | wire memen; // Requested memory is configured? 20 | wire [19:0] addr; // Configured base address 21 | 22 | wire [31:0] adz = active ? data : ad; 23 | 24 | 25 | `define PCI_CFGREAD 4'b1010 26 | `define PCI_CFGWRITE 4'b1011 27 | 28 | 29 | initial begin : Sim 30 | $display ("Time CLK RST# FRAME# DEVSEL# IRDY# TRDY# C/BE# AD IDSEL active memen addr"); 31 | $monitor ("%5t %b %b %b %b %b %b %b %h %b %b %b %h", 32 | $time, clock, reset_n, 33 | frame_n, devsel_n, irdy_n, trdy_n, cbe_n, adz, idsel, 34 | active, memen, addr 35 | ); 36 | 37 | #10 38 | reset_n <= 0; 39 | ad <= 0; 40 | 41 | #30 42 | reset_n <= 1; 43 | 44 | 45 | // Read device ID 46 | #30 47 | frame_n <= 0; 48 | cbe_n <= `PCI_CFGREAD; 49 | idsel <= 1; 50 | ad <= 0; 51 | 52 | #30 53 | frame_n <= 1; 54 | cbe_n <= 4'b0; 55 | idsel <= 0; 56 | irdy_n <= 0; 57 | 58 | #60 59 | irdy_n <= 1; 60 | 61 | 62 | // Configure the device base address 63 | #30 64 | frame_n <= 0; 65 | cbe_n <= `PCI_CFGWRITE; 66 | idsel <= 1; 67 | ad <= 32'h0_0010; 68 | 69 | #30 70 | frame_n <= 1; 71 | cbe_n <= 4'b0; 72 | idsel <= 0; 73 | ad <= 32'h000D_E000; // Use x86 baseaddr DE00:0000 74 | irdy_n <= 0; 75 | 76 | #60 77 | irdy_n <= 1; 78 | 79 | 80 | // Read back the base address 81 | #30 82 | frame_n <= 0; 83 | cbe_n <= `PCI_CFGREAD; 84 | idsel <= 1; 85 | ad <= 32'h0_0010; 86 | 87 | #30 88 | frame_n <= 1; 89 | cbe_n <= 4'b0; 90 | idsel <= 0; 91 | irdy_n <= 0; 92 | 93 | #60 94 | irdy_n <= 1; 95 | 96 | 97 | // Enable the device 98 | #30 99 | frame_n <= 0; 100 | cbe_n <= `PCI_CFGWRITE; 101 | idsel <= 1; 102 | ad <= 32'h0_0004; 103 | 104 | #30 105 | frame_n <= 1; 106 | cbe_n <= 4'b0; 107 | idsel <= 0; 108 | ad <= 32'h0000_0002; 109 | irdy_n <= 0; 110 | 111 | #60 112 | irdy_n <= 1; 113 | 114 | 115 | // Finished 116 | #90 117 | $finish; 118 | end // Sim 119 | 120 | 121 | cfgspace CFG0 ( 122 | .pci_clk_i (clock), 123 | .pci_rst_ni (reset_n), 124 | 125 | .pci_frame_ni (frame_n), 126 | .pci_devsel_no (devsel_n), 127 | .pci_irdy_ni (irdy_n), 128 | .pci_trdy_no (trdy_n), 129 | 130 | .pci_cbe_ni (cbe_n), 131 | .pci_ad_i (ad), 132 | .pci_ad_o (data), 133 | 134 | .pci_idsel_i (idsel), 135 | 136 | .active_o (active), 137 | .memen_o (memen), 138 | .addr_o (addr) 139 | ); 140 | 141 | 142 | endmodule // cfgspace_tb 143 | -------------------------------------------------------------------------------- /rtl/cpu/fastbits.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * fastbits.v - Performs logical bitwise operations, and sets the zero * 4 | * flag, using just 17 LUTs. * 5 | * * 6 | * Copyright (C) 2008 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | `timescale 1ns/100ps 26 | module fastbits #( 27 | parameter WIDTH = 16, 28 | parameter MSB = WIDTH - 1 29 | ) ( 30 | input [MSB:0] a_i, 31 | input [MSB:0] b_i, 32 | input [1:0] m_i, 33 | output [MSB:0] b_no, 34 | output z_o 35 | ); 36 | 37 | wire [WIDTH:0] c; 38 | 39 | assign c[0] = 1'b1; 40 | assign z_o = c[WIDTH]; 41 | 42 | genvar ii; 43 | generate 44 | for (ii=0; ii 127 : # White 53 | pixels |= 1 54 | # endif 55 | index += 1 56 | # endfor 57 | pixelRow += chr(pixels) 58 | # endfor 59 | font.append(pixelRow) 60 | row = in_file.read(128) 61 | # endwhile 62 | 63 | for ii in range(15,-1,-1) : 64 | for jj in range(16) : 65 | for kk in range(15,-1,-1) : 66 | out_file.write(font[ii * 16 + kk][jj]) 67 | 68 | # endfor 69 | 70 | in_file.close() 71 | out_file.close() 72 | 73 | # end main 74 | 75 | 76 | if __name__ == "__main__" : 77 | main(sys.argv) 78 | -------------------------------------------------------------------------------- /src/assembler/prettyprint.m: -------------------------------------------------------------------------------- 1 | :- module prettyprint. 2 | :- interface. 3 | :- import_module string, list. 4 | 5 | :- type style_t ---> pretty ; flat. 6 | 7 | :- type spaced_t ---> space; nospace. 8 | :- type pr_state ---> s(style_t, spaced_t, int, list(int), int, string). 9 | 10 | :- pred print(string::in, spaced_t::in, pr_state::in, pr_state::out) is det. 11 | :- pred pS(string::in, pr_state::in, pr_state::out) is det. 12 | :- pred pN(string::in, pr_state::in, pr_state::out) is det. 13 | :- pred force_space(pr_state::in, pr_state::out) is det. 14 | :- pred force_nospace(pr_state::in, pr_state::out) is det. 15 | 16 | :- pred fromstring(pr_state::out,string::in,style_t::in) is det. 17 | :- pred tostring(pr_state::in,string::out) is det. 18 | 19 | :- pred newline(pr_state::in, pr_state::out) is det. 20 | 21 | :- pred entab(int::in,pr_state::in, pr_state::out) is det. 22 | 23 | :- pred detab(pr_state::in, pr_state::out) is det. 24 | 25 | :- pred print_with_sep(string,pred(X,pr_state,pr_state),list(X),pr_state,pr_state). 26 | :- mode print_with_sep(in, pred(in, in, out) is det, in, in, out) is det. 27 | 28 | :- pred print_with_pred_sep(pred(pr_state,pr_state),pred(X,pr_state,pr_state),list(X),pr_state,pr_state). 29 | :- mode print_with_pred_sep(pred(in, out) is det, pred(in, in, out) is det, 30 | in, in, out) is det. 31 | 32 | :- pred isempty(pr_state::in) is semidet. 33 | 34 | :- pred print_int(int::in, pr_state::in, pr_state::out) is det. 35 | 36 | %-----------------------------------------------------------------------------% 37 | :- implementation. 38 | :- import_module list,int. 39 | %-----------------------------------------------------------------------------% 40 | 41 | print_with_sep(_,_,[]) --> {true}. 42 | print_with_sep(_,Pred,[H]) --> Pred(H). 43 | print_with_sep(Sep,Pred,[H|[H2|T]]) --> Pred(H),pN(Sep),print_with_sep(Sep,Pred,[H2|T]). 44 | 45 | print_with_pred_sep(_,_,[]) --> {true}. 46 | print_with_pred_sep(Sep,Pred,[H|T],!S) :- Pred(H,!S),foldl((pred(X::in,Y::in,Z::out) is det :- Sep(Y,Y1),Pred(X,Y1,Z)),T,!S). 47 | %print_with_pred_sep(Sep,Pred,[H|[H2|T]],) --> Pred(H),Sep,print_with_pred_sep(Sep,Pred,[H2|T]). 48 | 49 | entab(Add,s(X,Sp,T1,Tabs,Nl,In),s(X,Sp,T0,[T1|Tabs],Nl,In)) :- T0 is T1+Add. 50 | 51 | detab(s(X,Sp,T0,[],Nl,In),s(X,Sp,T0,[],Nl,In)). 52 | detab(s(X,Sp,_,[T1|Tabs],Nl,In),s(X,Sp,T1,Tabs,Nl,In)). 53 | 54 | newline(s(flat,Sp,T1,Tabs,Nl,In),s(flat,Sp,T1,Tabs,Nl,In)). 55 | newline(s(pretty,Sp,T1,Tabs,Nl,In),s(pretty,Sp,T1,Tabs,Nl+1,In)). 56 | 57 | print(S,Sp1,s(Style,Sp2,T1,Tabs,Nl,In),s(Style,Sp1,T1,Tabs,0,Out)) :- 58 | ( Nl=0 -> 59 | Pad1 = "", Pad2 = "" 60 | ; string.pad_right("",'\n',Nl,Pad1),string.pad_right("",' ',T1,Pad2)), 61 | ( Sp1=space,Sp2=space,Nl=0 -> Space=" " ; Space=""), 62 | Out = In ++ Pad1 ++ Pad2 ++ Space ++ S. 63 | 64 | pS(S) --> print(S,space). 65 | pN(S) --> print(S,nospace). 66 | force_space --> print(" ",nospace). 67 | force_nospace --> print("",nospace). 68 | 69 | fromstring(P,S,State) :- P=s(State,nospace,0,[],0,S). 70 | 71 | tostring(State,S) :- pN("",State,s(_,_,_,_,_,S)). 72 | 73 | isempty(s(_,_,_,_,_,"")). 74 | 75 | print_int(N) --> pS(int_to_string(N)). -------------------------------------------------------------------------------- /rtl/mem/rfc.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * rfc.v - Generates the refreshes for a SDRAM or DDR SDRAM or DDR2 * 4 | * SDRAM low-level controller. * 5 | * * 6 | * Copyright (C) 2008 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | `timescale 1ns/100ps 26 | module rfc ( 27 | clk_i, 28 | rst_i, 29 | en_i, 30 | req_o, 31 | gnt_i, 32 | rfc_o 33 | ); 34 | 35 | parameter INIT = 1; 36 | parameter RFC_TIMER = 780; // 50 MHz 37 | parameter TIMER_BITS = 10; 38 | parameter tRFC = 4; // 64 ns refresh 39 | parameter TSB = TIMER_BITS - 1; 40 | 41 | input clk_i; 42 | input rst_i; 43 | input en_i; 44 | output req_o; 45 | input gnt_i; 46 | output rfc_o; 47 | 48 | reg rfc_o = INIT; 49 | reg [TSB:0] cnt = 0; 50 | reg [2:0] trfc = 0; 51 | reg [1:0] owing = 2; 52 | 53 | assign #2 req_o = (owing != 0); 54 | 55 | 56 | // Refresh event logic. 57 | wire #2 rfc_trigger = (cnt == RFC_TIMER - 1); 58 | always @(posedge clk_i) 59 | if (rst_i) cnt <= #2 0; 60 | else if (rfc_trigger) cnt <= #2 0; 61 | else cnt <= #2 cnt + 1; 62 | 63 | always @(posedge clk_i) 64 | if (rst_i) owing <= #2 2; 65 | else if (gnt_i && trfc == 0) begin 66 | if (!rfc_trigger) 67 | owing <= #2 owing - 1; 68 | end else if (rfc_trigger) 69 | owing <= #2 owing + 1; 70 | 71 | always @(posedge clk_i) 72 | if (trfc != 0) trfc <= #2 trfc - 1; 73 | else if (gnt_i) trfc <= #2 tRFC - 1; 74 | 75 | always @(posedge clk_i) 76 | if (rst_i) rfc_o <= #2 0; 77 | else if (gnt_i && trfc == 0) rfc_o <= #2 1; 78 | else if (trfc == 0) rfc_o <= #2 0; 79 | 80 | endmodule // rfc 81 | -------------------------------------------------------------------------------- /sim/cpu/tta16/tta16_tile_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module tta16_tile_tb; 3 | 4 | `define IO_DECODE_BITS 20:18 5 | `define IO_FLUSH 3'b1_10__ 6 | `define IO_DMA 3'b1_00__ 7 | `define IO_CRTC 3'b0_00__ 8 | `define IO_SPROM 3'b0_01__ 9 | `define IO_LEDS 3'b0_10__ 10 | 11 | reg wb_clk = 1; 12 | reg cpu_clk = 1; 13 | reg reset = 0; 14 | reg cache_reset = 0; 15 | 16 | always #15 wb_clk = ~wb_clk; 17 | always #5 cpu_clk = ~cpu_clk; 18 | 19 | 20 | wire mem_cyc, mem_stb, mem_we; 21 | reg mem_ack = 0; 22 | reg mem_rty = 0; 23 | reg mem_err = 0; 24 | wire [2:0] mem_cti; 25 | wire [1:0] mem_bte; 26 | wire [20:0] mem_adr; 27 | wire [3:0] mem_sel_f; 28 | wire [31:0] mem_dat_f; 29 | reg [3:0] mem_sel_t; 30 | reg [31:0] mem_dat_t; 31 | 32 | wire io_cyc, io_stb, io_we; 33 | reg io_ack = 0; 34 | reg io_rty = 0; 35 | reg io_err = 0; 36 | wire [2:0] io_cti; 37 | wire [1:0] io_bte; 38 | wire [20:0] io_adr; 39 | wire [1:0] io_sel_f; 40 | wire [15:0] io_dat_f; 41 | reg [1:0] io_sel_t; 42 | reg [15:0] io_dat_t; 43 | 44 | 45 | initial begin : Sim 46 | $dumpfile ("tb.vcd"); 47 | $dumpvars; 48 | 49 | #22 reset = 1; 50 | #160 reset = 0; 51 | 52 | #2400 53 | $display ("Test Completed."); 54 | $finish; 55 | end // Sim 56 | 57 | 58 | initial begin : Safety_Net 59 | #15000 60 | $display ("ERROR: Unclean exit"); 61 | $finish; 62 | end // Safety_Net 63 | 64 | 65 | always @(posedge wb_clk) 66 | if (reset) 67 | mem_ack <= #2 0; 68 | else if (mem_cyc && mem_stb) begin 69 | // Atomic transaction or end of burst. 70 | if (mem_ack && (mem_cti == 3'b000 || mem_cti == 3'b111)) 71 | mem_ack <= #2 0; 72 | else 73 | mem_ack <= #2 1; 74 | end 75 | 76 | 77 | always @(posedge wb_clk) 78 | if (reset) 79 | io_ack <= #2 0; 80 | else if (io_cyc && io_stb && !io_ack) // Atomic only 81 | io_ack <= #2 1; 82 | else 83 | io_ack <= #2 0; 84 | 85 | always @(posedge wb_clk) 86 | if (reset) 87 | cache_reset <= #2 0; 88 | else if (io_cyc && io_stb && (io_adr[`IO_DECODE_BITS] == `IO_FLUSH) && !cache_reset) 89 | cache_reset <= #2 1; 90 | else 91 | cache_reset <= #2 0; 92 | 93 | 94 | tta16_tile #( 95 | .ADDRESS (23) 96 | ) TTA0 ( 97 | .wb_rst_i (reset), 98 | .wb_clk_i (wb_clk), // 50 MHz 99 | .cpu_clk_i (cpu_clk), // 150 MHz, sync with WB clock 100 | .cache_rst_i (cache_reset), 101 | 102 | .mem_cyc_o (mem_cyc), 103 | .mem_stb_o (mem_stb), 104 | .mem_we_o (mem_we), 105 | .mem_ack_i (mem_ack), 106 | .mem_rty_i (mem_rty), 107 | .mem_err_i (mem_err), 108 | .mem_cti_o (mem_cti), 109 | .mem_bte_o (mem_bte), 110 | .mem_adr_o (mem_adr), 111 | .mem_sel_o (mem_sel_f), 112 | .mem_dat_o (mem_dat_f), 113 | .mem_sel_i (mem_sel_t), 114 | .mem_dat_i (mem_dat_t), 115 | 116 | .io_cyc_o (io_cyc), 117 | .io_stb_o (io_stb), 118 | .io_we_o (io_we), 119 | .io_ack_i (io_ack), 120 | .io_rty_i (io_rty), 121 | .io_err_i (io_err), 122 | .io_cti_o (io_cti), 123 | .io_bte_o (io_bte), 124 | .io_adr_o (io_adr), 125 | .io_sel_o (io_sel_f), 126 | .io_dat_o (io_dat_f), 127 | .io_sel_i (io_sel_t), 128 | .io_dat_i (io_dat_t) 129 | ); 130 | 131 | 132 | endmodule // tta16_tile_tb 133 | -------------------------------------------------------------------------------- /sim/cpu/risc16/risc16_tile_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module risc16_tile_tb; 3 | 4 | `define IO_DECODE_BITS 20:18 5 | `define IO_FLUSH 3'b1_10__ 6 | `define IO_DMA 3'b1_00__ 7 | `define IO_CRTC 3'b0_00__ 8 | `define IO_SPROM 3'b0_01__ 9 | `define IO_LEDS 3'b0_10__ 10 | 11 | reg wb_clk = 1; 12 | reg cpu_clk = 1; 13 | reg reset = 0; 14 | reg cache_reset = 0; 15 | 16 | always #15 wb_clk = ~wb_clk; 17 | always #5 cpu_clk = ~cpu_clk; 18 | 19 | 20 | wire mem_cyc, mem_stb, mem_we; 21 | reg mem_ack = 0; 22 | reg mem_rty = 0; 23 | reg mem_err = 0; 24 | wire [2:0] mem_cti; 25 | wire [1:0] mem_bte; 26 | wire [20:0] mem_adr; 27 | wire [3:0] mem_sel_f; 28 | wire [31:0] mem_dat_f; 29 | reg [3:0] mem_sel_t; 30 | reg [31:0] mem_dat_t; 31 | 32 | wire io_cyc, io_stb, io_we; 33 | reg io_ack = 0; 34 | reg io_rty = 0; 35 | reg io_err = 0; 36 | wire [2:0] io_cti; 37 | wire [1:0] io_bte; 38 | wire [20:0] io_adr; 39 | wire [1:0] io_sel_f; 40 | wire [15:0] io_dat_f; 41 | reg [1:0] io_sel_t; 42 | reg [15:0] io_dat_t; 43 | 44 | 45 | initial begin : Sim 46 | $dumpfile ("tb.vcd"); 47 | $dumpvars; 48 | 49 | #22 reset = 1; 50 | #160 reset = 0; 51 | 52 | #2400 53 | $display ("Test Completed."); 54 | $finish; 55 | end // Sim 56 | 57 | 58 | initial begin : Safety_Net 59 | #15000 60 | $display ("ERROR: Unclean exit"); 61 | $finish; 62 | end // Safety_Net 63 | 64 | 65 | always @(posedge wb_clk) 66 | if (reset) 67 | mem_ack <= #2 0; 68 | else if (mem_cyc && mem_stb) begin 69 | // Atomic transaction or end of burst. 70 | if (mem_ack && (mem_cti == 3'b000 || mem_cti == 3'b111)) 71 | mem_ack <= #2 0; 72 | else 73 | mem_ack <= #2 1; 74 | end 75 | 76 | 77 | always @(posedge wb_clk) 78 | if (reset) 79 | io_ack <= #2 0; 80 | else if (io_cyc && io_stb && !io_ack) // Atomic only 81 | io_ack <= #2 1; 82 | else 83 | io_ack <= #2 0; 84 | 85 | always @(posedge wb_clk) 86 | if (reset) 87 | cache_reset <= #2 0; 88 | else if (io_cyc && io_stb && (io_adr[`IO_DECODE_BITS] == `IO_FLUSH) && !cache_reset) 89 | cache_reset <= #2 1; 90 | else 91 | cache_reset <= #2 0; 92 | 93 | 94 | risc16_tile #( 95 | .ADDRESS (23) 96 | ) TTA0 ( 97 | .wb_rst_i (reset), 98 | .wb_clk_i (wb_clk), // 50 MHz 99 | .cpu_clk_i (cpu_clk), // 150 MHz, sync with WB clock 100 | .cache_rst_i (cache_reset), 101 | 102 | .mem_cyc_o (mem_cyc), 103 | .mem_stb_o (mem_stb), 104 | .mem_we_o (mem_we), 105 | .mem_ack_i (mem_ack), 106 | .mem_rty_i (mem_rty), 107 | .mem_err_i (mem_err), 108 | .mem_cti_o (mem_cti), 109 | .mem_bte_o (mem_bte), 110 | .mem_adr_o (mem_adr), 111 | .mem_sel_o (mem_sel_f), 112 | .mem_dat_o (mem_dat_f), 113 | .mem_sel_i (mem_sel_t), 114 | .mem_dat_i (mem_dat_t), 115 | 116 | .io_cyc_o (io_cyc), 117 | .io_stb_o (io_stb), 118 | .io_we_o (io_we), 119 | .io_ack_i (io_ack), 120 | .io_rty_i (io_rty), 121 | .io_err_i (io_err), 122 | .io_cti_o (io_cti), 123 | .io_bte_o (io_bte), 124 | .io_adr_o (io_adr), 125 | .io_sel_o (io_sel_f), 126 | .io_dat_o (io_dat_f), 127 | .io_sel_i (io_sel_t), 128 | .io_dat_i (io_dat_t) 129 | ); 130 | 131 | 132 | endmodule // risc16_tile_tb 133 | -------------------------------------------------------------------------------- /rtl/lib/counter/bin2gray.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * bin2gray.v - Converts binary numbers of parameterizable width, * 4 | * `WIDTH', to gray encoded numbers. * 5 | * * 6 | * Copyright (C) 2007 by Patrick Suggate * 7 | * patrick@physics.otago.ac.nz * 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU General Public License as published by * 11 | * the Free Software Foundation; either version 2 of the License, or * 12 | * (at your option) any later version. * 13 | * * 14 | * This program is distributed in the hope that it will be useful, * 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | * GNU General Public License for more details. * 18 | * * 19 | * You should have received a copy of the GNU General Public License * 20 | * along with this program; if not, write to the * 21 | * Free Software Foundation, Inc., * 22 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 23 | ***************************************************************************/ 24 | 25 | // Where: 26 | // g_n = b_n 27 | // g_i = b_i ^ b_(i+1) | i < n 28 | 29 | `timescale 1ns/100ps 30 | module bin2gray ( 31 | bin_i, 32 | gray_o 33 | ); 34 | 35 | parameter WIDTH = 4; 36 | 37 | input [WIDTH-1:0] bin_i; 38 | output [WIDTH-1:0] gray_o; 39 | 40 | wire [WIDTH-2:0] lower = bin_i [WIDTH-2:0]; 41 | wire [WIDTH-2:0] upper = bin_i [WIDTH-1:1]; 42 | wire [WIDTH-2:0] gray; 43 | 44 | // `define __nasty_hack 45 | `ifdef __nasty_hack 46 | // This version of Icarus doesn't like arrays of instances. :( 47 | bin2gray_digit B2G0 ( 48 | .b0_i (lower [0]), 49 | .b1_i (upper [0]), 50 | .g_o (gray [0]) 51 | ); 52 | 53 | bin2gray_digit B2G1 ( 54 | .b0_i (lower [1]), 55 | .b1_i (upper [1]), 56 | .g_o (gray [1]) 57 | ); 58 | 59 | bin2gray_digit B2G2 ( 60 | .b0_i (lower [2]), 61 | .b1_i (upper [2]), 62 | .g_o (gray [2]) 63 | ); 64 | 65 | `else 66 | // Array of instances of digit conversions. 67 | bin2gray_digit B2G [WIDTH-2:0] ( 68 | .b0_i (lower), 69 | .b1_i (upper), 70 | .g_o (gray) 71 | ); 72 | `endif 73 | 74 | assign gray_o = {bin_i [WIDTH-1], gray}; 75 | 76 | endmodule // bin2gray 77 | 78 | 79 | // This is so an array-of-instances can be used. 80 | module bin2gray_digit ( 81 | b0_i, 82 | b1_i, 83 | g_o 84 | ); 85 | 86 | input b0_i; 87 | input b1_i; 88 | output g_o; 89 | 90 | assign g_o = b0_i ^ b1_i; 91 | 92 | endmodule // bin2gray_digit 93 | -------------------------------------------------------------------------------- /rtl/lib/wb_leds.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * wb_leds.v - Wishbone bus connected LEDs. * 4 | * * 5 | * Copyright (C) 2008 by Patrick Suggate * 6 | * patrick@physics.otago.ac.nz * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * This program is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with this program; if not, write to the * 20 | * Free Software Foundation, Inc., * 21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 22 | ***************************************************************************/ 23 | 24 | // `define __use_random 25 | 26 | `timescale 1ns/100ps 27 | module wb_leds #( 28 | parameter HIGHZ = 0, 29 | parameter WIDTH = 16, 30 | parameter LEDS = 2, 31 | parameter ENABLES = WIDTH / 8, 32 | parameter MSB = WIDTH - 1, 33 | parameter ESB = ENABLES - 1, 34 | parameter LSB = LEDS - 1 35 | ) ( 36 | input wb_clk_i, 37 | input wb_rst_i, 38 | 39 | input wb_cyc_i, 40 | input wb_stb_i, 41 | input wb_we_i, 42 | output wb_ack_o, 43 | output wb_rty_o, 44 | output wb_err_o, 45 | input [ESB:0] wb_sel_i, 46 | input [MSB:0] wb_dat_i, 47 | output [ESB:0] wb_sel_o, 48 | output [MSB:0] wb_dat_o, 49 | 50 | output [LSB:0] leds_o 51 | ); 52 | 53 | reg ack = 0; 54 | reg [MSB:0] dat = 0; 55 | 56 | 57 | assign leds_o = dat[LSB:0]; 58 | 59 | assign #2 wb_ack_o = HIGHZ ? (ack ? 1'b1 : 'bz) : ack ; 60 | assign #2 wb_rty_o = HIGHZ ? (ack ? 0 : 'bz) : 0 ; 61 | assign #2 wb_err_o = HIGHZ ? (ack ? 0 : 'bz) : 0 ; 62 | assign #2 wb_sel_o = HIGHZ ? (ack ? {ENABLES{ack}} : 'bz) : {ENABLES{ack}} ; 63 | assign #2 wb_dat_o = HIGHZ ? (ack ? dat : 'bz) : dat ; 64 | 65 | 66 | always @(posedge wb_clk_i) 67 | if (wb_rst_i) 68 | ack <= #2 0; 69 | else if (wb_cyc_i && wb_stb_i && !ack) 70 | ack <= #2 1; 71 | else 72 | ack <= #2 0; 73 | 74 | 75 | // TODO: Byte-enables 76 | always @(posedge wb_clk_i) 77 | if (wb_rst_i) dat <= #2 0; 78 | else if (wb_cyc_i && wb_stb_i && wb_we_i) begin 79 | `ifdef __use_random 80 | dat <= #2 $random; 81 | `else 82 | dat <= #2 wb_dat_i; 83 | `endif 84 | end 85 | 86 | 87 | endmodule // wb_leds 88 | -------------------------------------------------------------------------------- /rtl/video/vga16.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * vga16.v - Drives a VGA monitor in 16-bit mode. * 4 | * * 5 | * Copyright (C) 2008 by Patrick Suggate * 6 | * patrick@physics.otago.ac.nz * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * This program is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with this program; if not, write to the * 20 | * Free Software Foundation, Inc., * 21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 22 | ***************************************************************************/ 23 | 24 | `timescale 1ns/100ps 25 | module vga16 ( 26 | input clk_i, 27 | input rst_i, 28 | 29 | input hsync_i, 30 | input vsync_i, 31 | input hblank_i, 32 | input vblank_i, 33 | input de_i, 34 | output read_o, 35 | input [31:0] data_i, 36 | 37 | output reg [7:0] r_o, 38 | output reg [7:0] g_o, 39 | output reg [7:0] b_o, 40 | output reg vsync_o = 1, 41 | output reg hsync_o = 1, 42 | output reg de_o = 0 43 | ); 44 | 45 | 46 | reg [15:0] upper_word; 47 | reg odd = 1; 48 | 49 | 50 | // assign addr_o [ASB:FBSIZE] = FBOFF; 51 | assign #2 read_o = (de_i && odd); 52 | 53 | 54 | // Make sure all output signals are free from combinatorial delays and 55 | // therefore in phase. 56 | always @(posedge clk_i) 57 | if (rst_i) 58 | {hsync_o, vsync_o, de_o} <= #2 3'b110; 59 | else begin 60 | hsync_o <= #2 hsync_i; 61 | vsync_o <= #2 vsync_i; 62 | de_o <= #2 de_i; 63 | end 64 | 65 | 66 | //--------------------------------------------------------------------------- 67 | // Display DATAPATH: 68 | // The memory controller fetches data with a width of 32-bits, but the 69 | // display uses 16-bit colour data. 70 | always @(posedge clk_i) 71 | if (rst_i) odd <= #2 0; 72 | else if (hsync_i) odd <= #2 0; 73 | else if (de_i) odd <= #2 ~odd; 74 | 75 | always @(posedge clk_i) 76 | if (!odd) upper_word <= #2 data_i [31:16]; 77 | 78 | always @(posedge clk_i) 79 | if (hblank_i || vblank_i) 80 | {r_o, g_o, b_o} <= #2 0; 81 | else begin 82 | b_o <= #2 {odd ? upper_word [15:11] : data_i [15:11], 3'b000}; 83 | g_o <= #2 {odd ? upper_word [10:5] : data_i [10:5], 2'b00}; 84 | r_o <= #2 {odd ? upper_word [4:0] : data_i [4:0], 3'b000}; 85 | end 86 | 87 | 88 | endmodule // vga16 89 | -------------------------------------------------------------------------------- /sim/xilinx/RAM16X1D.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * RAM16X1D.v - Emulates the functionality of the Xilinx primitive of the* 4 | * same name. This a really poor partial implementation so do not use * 5 | * as it is only designed to do some very basic things. * 6 | * * 7 | * Copyright (C) 2005 by Patrick Suggate * 8 | * patrick@physics.otago.ac.nz * 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU General Public License as published by * 12 | * the Free Software Foundation; either version 2 of the License, or * 13 | * (at your option) any later version. * 14 | * * 15 | * This program is distributed in the hope that it will be useful, * 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 18 | * GNU General Public License for more details. * 19 | * * 20 | * You should have received a copy of the GNU General Public License * 21 | * along with this program; if not, write to the * 22 | * Free Software Foundation, Inc., * 23 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 24 | ***************************************************************************/ 25 | 26 | `timescale 1ns / 100ps 27 | module RAM16X1D( 28 | D, 29 | WE, 30 | WCLK, 31 | A0, 32 | A1, 33 | A2, 34 | A3, 35 | DPRA0, 36 | DPRA1, 37 | DPRA2, 38 | DPRA3, 39 | SPO, 40 | DPO 41 | ); 42 | 43 | input D; 44 | input WE; 45 | input WCLK; 46 | input A0; 47 | input A1; 48 | input A2; 49 | input A3; 50 | input DPRA0; 51 | input DPRA1; 52 | input DPRA2; 53 | input DPRA3; 54 | output SPO; 55 | output DPO; 56 | 57 | 58 | // 16-bits of RAM, initialise to zero 59 | reg r_data[0:15]; // Allowed? 60 | 61 | 62 | // Turn the incoming address bits into an address bus 63 | wire [3:0] w_addr = {A0, A1, A2, A3}; 64 | wire [3:0] r_addr = {DPRA0, DPRA1, DPRA2, DPRA3}; 65 | 66 | 67 | // Output the bit-values 68 | assign SPO = r_data[w_addr]; 69 | assign DPO = r_data[r_addr]; 70 | 71 | 72 | // Write incoming data to the dual-port RAM 73 | always @(posedge WCLK) 74 | begin 75 | if (WE) 76 | r_data[w_addr] <= D; 77 | else 78 | r_data[w_addr] <= r_data[w_addr]; 79 | end 80 | 81 | 82 | initial begin : Init 83 | fill_mem(1); 84 | end // Init 85 | 86 | 87 | // Used to intialise the memory for a test bench 88 | task fill_mem; 89 | input mode; 90 | integer n, mode; 91 | 92 | begin : Fill_Memory 93 | 94 | for (n = 0; n < 16; n = n+1) 95 | begin 96 | case (mode) 97 | default: r_data[n] = 'b0; 98 | 1: r_data[n] = $random; 99 | 2: r_data[n] = 'b1; 100 | endcase 101 | end 102 | end // Fill_Memory 103 | endtask // fill_mem 104 | 105 | endmodule // RAM16X1D 106 | -------------------------------------------------------------------------------- /sim/pci/wb_pci_top_tb.v: -------------------------------------------------------------------------------- 1 | //`define _use_SRAM 2 | `timescale 1ns/100ps 3 | module wb_pci_top_tb; 4 | 5 | parameter ADDRESS = 25; 6 | parameter ASB = ADDRESS - 1; 7 | 8 | reg clk33 = 1; 9 | always #15 clk33 <= ~clk33; 10 | 11 | reg clk50 = 1; 12 | always #10 clk50 <= ~clk50; 13 | 14 | 15 | wire pci_clk = clk33; 16 | wire wb_clk = clk50; 17 | 18 | 19 | // These are control signals for the PCI stress-testing module. 20 | reg start = 0; 21 | wire done; 22 | 23 | 24 | // PCI signals. 25 | reg pci_rst_n = 1; 26 | wire pci_frame_n, pci_devsel_n; 27 | wire pci_irdy_n, pci_trdy_n; 28 | wire pci_stop_n, pci_idsel; 29 | wire [3:0] pci_cbe_n; 30 | wire [31:0] pci_adz; 31 | 32 | // Wishbone Signals. 33 | reg wb_rst = 0; 34 | wire wb_cyc_f, wb_stb_f, wb_we_f; 35 | wire wb_ack_t, wb_rty_t, wb_err_t; 36 | wire [2:0] wb_cti_f; 37 | wire [1:0] wb_bte_f; 38 | wire [ASB:0] wb_adr_f; 39 | wire [3:0] wb_sel_f, wb_sel_t; 40 | wire [31:0] wb_dat_f, wb_dat_t; 41 | 42 | 43 | initial begin : Sim 44 | $dumpfile ("tb.vcd"); 45 | $dumpvars; 46 | 47 | #2 pci_rst_n <= 0; wb_rst <= 1; 48 | #60 pci_rst_n <= 1; wb_rst <= 0; 49 | 50 | #30 start <= 1; 51 | #60 start <= 0; 52 | 53 | #60 54 | while (!done) #30 ; 55 | 56 | #60 57 | $display ("Test completed."); 58 | $finish; 59 | end 60 | 61 | 62 | initial begin : Safety_Net 63 | #15000 64 | $display ("ERROR: Unclean exit"); 65 | $finish; 66 | end // Safety_Net 67 | 68 | 69 | // Simulation PCI master. 70 | pci_stresstest STRESSTEST0 ( 71 | .pci_clk_i (pci_clk), 72 | .pci_rst_ni (pci_rst_n), 73 | 74 | .start_i (start), 75 | .done_o (done), 76 | 77 | .pci_frame_no (pci_frame_n), 78 | .pci_devsel_ni (pci_devsel_n), 79 | .pci_irdy_no (pci_irdy_n), 80 | .pci_trdy_ni (pci_trdy_n), 81 | .pci_stop_ni (pci_stop_n), 82 | .pci_idsel_o (pci_idsel), 83 | .pci_cbe_no (pci_cbe_n), 84 | .pci_ad_io (pci_adz) 85 | ); 86 | 87 | 88 | // Wishbone slave device. 89 | wb_bram4k #( 90 | .HIGHZ (0) 91 | ) BRAM ( 92 | .wb_clk_i (wb_clk), 93 | .wb_rst_i (wb_rst), 94 | .wb_cyc_i (wb_cyc_f), 95 | .wb_stb_i (wb_stb_f), 96 | .wb_we_i (wb_we_f), 97 | .wb_ack_o (wb_ack_t), 98 | .wb_err_o (wb_err_t), 99 | .wb_cti_i (wb_cti_f), 100 | .wb_bte_i (wb_bte_f), 101 | .wb_adr_i (wb_adr_f), 102 | .wb_sel_i (wb_sel_f), 103 | .wb_dat_i (wb_dat_f), 104 | .wb_dat_o (wb_dat_t), 105 | .wb_sel_o (wb_sel_t) 106 | ); 107 | 108 | 109 | wb_pci_top #( 110 | .ADDRESS (ADDRESS) 111 | ) PCITOP0 ( 112 | .pci_clk_i (pci_clk), 113 | .pci_rst_ni (pci_rst_n), 114 | .pci_frame_ni (pci_frame_n), 115 | .pci_devsel_no (pci_devsel_n), 116 | .pci_irdy_ni (pci_irdy_n), 117 | .pci_trdy_no (pci_trdy_n), 118 | .pci_idsel_i (pci_idsel), 119 | .pci_cbe_ni (pci_cbe_n), 120 | .pci_ad_io (pci_adz), 121 | .pci_stop_no (pci_stop_n), 122 | .pci_par_io (pci_par), 123 | .pci_inta_no (pci_inta_n), 124 | .pci_req_no (pci_req_n), 125 | .pci_gnt_ni (pci_gnt_n), 126 | 127 | .enable_i (1'b1), 128 | .enabled_o (pci_enabled), 129 | .pci_disable_o (pci_disable), 130 | 131 | .wb_clk_i (wb_clk), // Wishbone Master 132 | .wb_rst_i (wb_rst), 133 | 134 | .wb_cyc_o (wb_cyc_f), 135 | .wb_stb_o (wb_stb_f), 136 | .wb_we_o (wb_we_f), 137 | .wb_ack_i (wb_ack_t), 138 | .wb_rty_i (wb_rty_t), 139 | .wb_err_i (wb_err_t), 140 | .wb_cti_o (wb_cti_f), 141 | .wb_bte_o (wb_bte_f), 142 | .wb_adr_o (wb_adr_f), 143 | 144 | .wb_sel_o (wb_sel_f), 145 | .wb_dat_o (wb_dat_f), 146 | .wb_sel_i (wb_sel_t), 147 | .wb_dat_i (wb_dat_t) 148 | ); 149 | 150 | 151 | endmodule // wb_pci_top_tb 152 | -------------------------------------------------------------------------------- /rtl/cpu/risc16/risc_mem_wb.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * risc_mem_wb.v - Lightweight CPU->WB interface. * 4 | * * 5 | * Copyright (C) 2008 by Patrick Suggate * 6 | * patrick@physics.otago.ac.nz * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * This program is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with this program; if not, write to the * 20 | * Free Software Foundation, Inc., * 21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 22 | ***************************************************************************/ 23 | 24 | // TODO: Currently the `wb' and `cpu' clocks have to be the same. 25 | // TODO: `HIGHZ'. 26 | // TODO: Currently the bus-widths have to be the same. 27 | 28 | `timescale 1ns/100ps 29 | module risc_mem_wb #( 30 | parameter HIGHZ = 0, 31 | parameter WIDTH = 16, 32 | parameter ADDRESS = 25, 33 | parameter WBBITS = WIDTH, 34 | // parameter WBBITS = 32, 35 | parameter ENABLES = WBBITS / 8, 36 | parameter MSB = WIDTH - 1, 37 | parameter ESB = ENABLES - 1, 38 | parameter ASB = ADDRESS - 1, 39 | parameter WSB = WBBITS - 1 40 | ) ( 41 | input cpu_clk_i, 42 | input cpu_rst_i, 43 | 44 | input frame_i, 45 | input write_i, 46 | output ready_o, 47 | input [ASB:0] addr_i, 48 | input [MSB:0] data_i, 49 | output [MSB:0] data_o, 50 | 51 | output reg wb_cyc_o = 0, 52 | output reg [1:0] wb_stb_o = 0, 53 | output reg wb_we_o = 0, 54 | input wb_ack_i, 55 | input wb_rty_i, 56 | input wb_err_i, 57 | output [2:0] wb_cti_o, // Single-word transfers 58 | output [1:0] wb_bte_o, 59 | output reg [ASB:0] wb_adr_o, 60 | output [ESB:0] wb_sel_o, 61 | output reg [WSB:0] wb_dat_o, 62 | input [ESB:0] wb_sel_i, 63 | input [WSB:0] wb_dat_i 64 | ); 65 | 66 | assign data_o = wb_dat_i; 67 | assign ready_o = wb_ack_i; 68 | 69 | assign wb_cti_o = 0; 70 | assign wb_bte_o = 0; 71 | assign wb_sel_o = {ENABLES{1'b1}}; 72 | 73 | always @(posedge cpu_clk_i) 74 | if (cpu_rst_i) 75 | {wb_cyc_o, wb_stb_o, wb_we_o} <= #2 4'b0000; 76 | else if (!wb_cyc_o) begin 77 | wb_cyc_o <= #2 frame_i; 78 | if (frame_i) 79 | wb_stb_o <= #2 addr_i[ASB] ? 2'b10 : 2'b01 ; 80 | else 81 | wb_stb_o <= #2 0; 82 | wb_we_o <= #2 write_i; 83 | wb_adr_o <= #2 addr_i; 84 | wb_dat_o <= #2 data_i; 85 | end else if (wb_ack_i) begin 86 | wb_cyc_o <= #2 0; 87 | wb_stb_o <= #2 0; 88 | wb_we_o <= #2 0; 89 | end 90 | 91 | endmodule // risc_mem_wb 92 | -------------------------------------------------------------------------------- /sim/cpu/risc16/risc_mem_wb.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * risc_mem_wb.v - Lightweight CPU->WB interface. * 4 | * * 5 | * Copyright (C) 2008 by Patrick Suggate * 6 | * patrick@physics.otago.ac.nz * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * This program is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with this program; if not, write to the * 20 | * Free Software Foundation, Inc., * 21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 22 | ***************************************************************************/ 23 | 24 | // TODO: Currently the `wb' and `cpu' clocks have to be the same. 25 | // TODO: `HIGHZ'. 26 | // TODO: Currently the bus-widths have to be the same. 27 | 28 | `timescale 1ns/100ps 29 | module risc_mem_wb #( 30 | parameter HIGHZ = 0, 31 | parameter WIDTH = 16, 32 | parameter ADDRESS = 25, 33 | parameter WBBITS = WIDTH, 34 | // parameter WBBITS = 32, 35 | parameter ENABLES = WBBITS / 8, 36 | parameter MSB = WIDTH - 1, 37 | parameter ESB = ENABLES - 1, 38 | parameter ASB = ADDRESS - 1, 39 | parameter WSB = WBBITS - 1 40 | ) ( 41 | input cpu_clk_i, 42 | input cpu_rst_i, 43 | 44 | input frame_i, 45 | input write_i, 46 | output ready_o, 47 | input [ASB:0] addr_i, 48 | input [MSB:0] data_i, 49 | output [MSB:0] data_o, 50 | 51 | output reg wb_cyc_o = 0, 52 | output reg [1:0] wb_stb_o = 0, 53 | output reg wb_we_o = 0, 54 | input wb_ack_i, 55 | input wb_rty_i, 56 | input wb_err_i, 57 | output [2:0] wb_cti_o, // Single-word transfers 58 | output [1:0] wb_bte_o, 59 | output reg [ASB:0] wb_adr_o, 60 | output [ESB:0] wb_sel_o, 61 | output reg [WSB:0] wb_dat_o, 62 | input [ESB:0] wb_sel_i, 63 | input [WSB:0] wb_dat_i 64 | ); 65 | 66 | assign data_o = wb_dat_i; 67 | assign ready_o = wb_ack_i; 68 | 69 | assign wb_cti_o = 0; 70 | assign wb_bte_o = 0; 71 | assign wb_sel_o = {ENABLES{1'b1}}; 72 | 73 | always @(posedge cpu_clk_i) 74 | if (cpu_rst_i) 75 | {wb_cyc_o, wb_stb_o, wb_we_o} <= #2 4'b0000; 76 | else if (!wb_cyc_o) begin 77 | wb_cyc_o <= #2 frame_i; 78 | if (frame_i) 79 | wb_stb_o <= #2 addr_i[ASB] ? 2'b10 : 2'b01 ; 80 | else 81 | wb_stb_o <= #2 0; 82 | wb_we_o <= #2 write_i; 83 | wb_adr_o <= #2 addr_i; 84 | wb_dat_o <= #2 data_i; 85 | end else if (wb_ack_i) begin 86 | wb_cyc_o <= #2 0; 87 | wb_stb_o <= #2 0; 88 | wb_we_o <= #2 0; 89 | end 90 | 91 | endmodule // risc_mem_wb 92 | -------------------------------------------------------------------------------- /rtl/cpu/risc16/branch.v: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * * 3 | * branch.v - Updates the PC and by decoding the incoming instructions. * 4 | * * 5 | * Copyright (C) 2008 by Patrick Suggate * 6 | * patrick@physics.otago.ac.nz * 7 | * * 8 | * This program is free software; you can redistribute it and/or modify * 9 | * it under the terms of the GNU General Public License as published by * 10 | * the Free Software Foundation; either version 2 of the License, or * 11 | * (at your option) any later version. * 12 | * * 13 | * This program is distributed in the hope that it will be useful, * 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 | * GNU General Public License for more details. * 17 | * * 18 | * You should have received a copy of the GNU General Public License * 19 | * along with this program; if not, write to the * 20 | * Free Software Foundation, Inc., * 21 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 22 | ***************************************************************************/ 23 | 24 | `include "defines.v" 25 | 26 | `timescale 1ns/100ps 27 | module branch #( 28 | parameter INIT = 0, 29 | parameter ADDRESS = 11, 30 | parameter DELAYS = 2, 31 | parameter ASB = ADDRESS - 1, 32 | parameter DSB = DELAYS - 1 33 | ) ( 34 | input clock_i, 35 | input reset_i, 36 | input enable_i, 37 | 38 | output [ASB:0] pc_prev_o, 39 | input [ASB:0] pc_next_i, 40 | input b_rel_i, 41 | input b_abs_i, 42 | input [ASB:0] addr_i, 43 | input [2:0] flags_i, // {N, C, Z} 44 | input [2:0] cnd_i, 45 | output branch_o, 46 | output [ASB:0] pc_ao 47 | ); 48 | 49 | reg [ASB:0] pc = INIT; 50 | reg [DSB:0] branching = 0; 51 | 52 | wire bra; 53 | 54 | assign pc_prev_o = pc; 55 | assign #2 pc_ao = bra ? addr_i : pc_next_i ; 56 | assign branch_o = branching[DSB]; 57 | 58 | assign #3 bra = b_abs_i || (b_rel_i && 59 | ((cnd_i==`JNE && !flags_i[0]) || // Not Zero 60 | (cnd_i==`JE && flags_i[0]) || 61 | (cnd_i==`JL && flags_i[2]) || // Neg 62 | (cnd_i==`JG && !flags_i[2]) || 63 | (cnd_i==`JB && flags_i[1]) || // Carry 64 | (cnd_i==`JBE && (flags_i[1] || flags_i[0])) || 65 | (cnd_i==`JA && (!flags_i[1] || !flags_i[0])) || 66 | (cnd_i==`JAE && !flags_i[1]))); 67 | 68 | // This causes the pipeline to throw away three instructions upon branch. 69 | always @(posedge clock_i) 70 | if (reset_i) 71 | branching <= #2 0; 72 | else if (enable_i) begin 73 | if (bra && !branching[DSB]) 74 | branching <= #2 {DELAYS{1'b1}}; 75 | else 76 | branching <= #2 {branching[DSB-1:0], 1'b0}; 77 | end 78 | // else begin 79 | // if (bra && !branching[DSB]) 80 | // branching <= #2 {DELAYS{1'b1}}; 81 | // else 82 | // branching <= #2 {branching[DSB-1:0], 1'b0}; 83 | // end 84 | 85 | always @(posedge clock_i) 86 | if (reset_i) 87 | pc <= #2 INIT; 88 | else if (enable_i) 89 | pc <= #2 pc_ao; 90 | 91 | endmodule // branch 92 | -------------------------------------------------------------------------------- /sim/Makefile: -------------------------------------------------------------------------------- 1 | ######################################################### 2 | # User settings start here 3 | ######################################################### 4 | 5 | RTL_PATH=../rtl 6 | LIB_PATH=${RTL_PATH}/lib 7 | SIM_PATH=. 8 | MEM_PATH=${RTL_PATH}/mem 9 | WBC_PATH=${LIB_PATH} 10 | CPU_PATH=${RTL_PATH}/cpu 11 | TTA_PATH=${CPU_PATH}/tta16 12 | RISC_PATH=${CPU_PATH}/risc16 13 | CACHE_PATH=${RTL_PATH}/cache 14 | PCI_PATH=${RTL_PATH}/pci 15 | VID_PATH=${RTL_PATH}/video 16 | XPATH=${SIM_PATH}/xilinx 17 | 18 | LIB_FILES=${LIB_PATH}/fifo/async/afifo16.v ${LIB_PATH}/fifo/async/afifo2k.v ${LIB_PATH}/counter/bin2gray.v ${WBC_PATH}/wb_mux4to1.v ${LIB_PATH}/mux/mux4to1.v ${LIB_PATH}/mfsr/mfsr7.v ${LIB_PATH}/mfsr/mfsr8.v ${LIB_PATH}/mfsr/mfsr9.v ${LIB_PATH}/mfsr/mfsr10.v ${LIB_PATH}/mfsr/mfsr11.v ${WBC_PATH}/wb_leds.v ${LIB_PATH}/counter/fib/fib20.v ${LIB_PATH}/clock/clkdiv.v 19 | 20 | CACHE_FILES=${CACHE_PATH}/wb_simple_cache.v ${CACHE_PATH}/wb_cache_flush.v ${CACHE_PATH}/fetch_wb.v ${CACHE_PATH}/tag_ram.v ${CACHE_PATH}/cache_bram.v 21 | 22 | RISC_FILES=${RISC_PATH}/risc16_tile.v ${RISC_PATH}/risc16.v ${RISC_PATH}/fetch.v ${RISC_PATH}/risc_rf.v ${RISC_PATH}/risc_mem_wb.v ${RISC_PATH}/decode.v ${RISC_PATH}/execute.v ${RISC_PATH}/branch.v ${RISC_PATH}/memory.v ${RISC_PATH}/risc_alu.v ${CACHE_FILES} ${CPU_PATH}/fastbits.v ${WBC_PATH}/wb_dma.v ${WBC_PATH}/pre_read.v ${WBC_PATH}/wb_sync.v 23 | 24 | TTA_FILES=${TTA_PATH}/tta16_tile.v ${TTA_PATH}/tta16.v ${CACHE_FILES} ${CPU_PATH}/fastbits.v ${WBC_PATH}/wb_dma.v ${WBC_PATH}/pre_read.v ${WBC_PATH}/wb_sync.v ${TTA_PATH}/tta_stream8to8.v ${TTA_PATH}/tta_stream4to4.v ${TTA_PATH}/tta_stream4to8.v 25 | # ${CPU_PATH}/tta/tta_stream8to32.v 26 | 27 | MEM_FILES=${MEM_PATH}/wb_sdram_ctrl.v ${MEM_PATH}/ddr_datapath.v ${MEM_PATH}/rfc.v 28 | 29 | WBC_FILES=${WBC_PATH}/wb_sprom.v ${PCI_PATH}/wb_pci_top.v ${PCI_PATH}/cfgspace.v ${PCI_PATH}/wb_pci_mem.v 30 | 31 | VID_FILES=${VID_PATH}/wb_video_top.v ${VID_PATH}/wb_vga_ctrl.v ${VID_PATH}/wb_crtc.v ${VID_PATH}/crtc.v ${VID_PATH}/prefetch.v ${VID_PATH}/vga16.v ${VID_PATH}/wb_redraw.v 32 | 33 | COMMON_FILES=${RTL_PATH}/freega_top.v ${RTL_PATH}/freega_io.v ${LIB_FILES} ${TTA_FILES} ${WBC_FILES} ${VID_FILES} ${MEM_FILES} 34 | IFILES=${COMMON_FILES} freega_tb.v ${SIM_PATH}/pci/pci_stresstest.v ${SIM_PATH}/pci/pci_testblock.v ${SIM_PATH}/pci/pci_gencmds.v ${LIB_PATH}/fifo/sync/sfifo2k.v ${SIM_PATH}/mem/mt48lc4m16a2.v ${XPATH}/IBUF.v ${XPATH}/OBUF.v ${XPATH}/BUFG.v ${XPATH}/BUFGMUX.v ${XPATH}/DCM.v ${XPATH}/RAMB16_S36_S36.v ${XPATH}/OFDDRTRSE.v ${XPATH}/IFDDRRSE.v ${XPATH}/MUXCY.v ${XPATH}/RAMB16_S18_S18.v ${XPATH}/RAMB16_S18_S36.v ${XPATH}/RAMB16_S9_S9.v ${XPATH}/FDRSE.v ${XPATH}/RAM16X1S.v 35 | 36 | # (optional) Name of top module. Defaults to name of first file with suffix removed 37 | ICARUS_TOP_MODULE=freega_tb 38 | 39 | 40 | ######################################################### 41 | # Advanced user settings 42 | ######################################################### 43 | 44 | ICARUS_OPTIONS= 45 | 46 | ######################################################### 47 | # User settings end here 48 | ######################################################### 49 | 50 | all: icarus 51 | 52 | clean: 53 | rm -rf icarus.out tb.vcd 54 | @md5sum Makefile > make.md5 55 | 56 | clean_test: 57 | ifneq '$(shell cat make.md5)' '$(shell md5sum Makefile)' 58 | @echo 'Makefile changed: making clean' 59 | make clean 60 | else 61 | endif 62 | 63 | test: 64 | echo ${TEST} 65 | 66 | ######################################################### 67 | 68 | icarus: clean_test ${XFILES} 69 | iverilog -Wall -D__icarus -o icarus.out -s ${ICARUS_TOP_MODULE} ${ICARUS_OPTIONS} ${IFILES} 70 | -------------------------------------------------------------------------------- /sim/mem/wb_sdram_ctrl_tb.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/100ps 2 | module wb_sdram_ctrl_tb; 3 | 4 | reg clk50 = 1; 5 | always #10 clk50 <= ~clk50; // 50 MHz 6 | 7 | reg clk100 = 1; 8 | always #5 clk100 <= ~clk100; 9 | 10 | reg reset = 1; 11 | 12 | reg m_cyc = 0; 13 | reg m_stb = 0; 14 | reg m_we = 0; 15 | wire m_ack, m_rty, m_err; 16 | reg [2:0] m_cti = 0; 17 | reg [1:0] m_bte = 0; 18 | reg [20:0] m_adr = 0; 19 | reg [3:0] m_sel_t = 0; 20 | reg [31:0] m_dat_t = 0; 21 | wire [3:0] m_sel_f; 22 | wire [31:0] m_dat_f; 23 | 24 | 25 | // SDRAM signals. 26 | wire sdr_clk, sdr_cke; 27 | wire sdr_cs_n, sdr_ras_n, sdr_cas_n, sdr_we_n; 28 | wire [1:0] sdr_ba; 29 | wire [12:0] sdr_a; 30 | wire [1:0] sdr_dm; 31 | wire [15:0] sdr_dq; 32 | 33 | 34 | integer ii; 35 | initial begin : Sim 36 | $dumpfile ("tb.vcd"); 37 | $dumpvars; 38 | 39 | #2 reset = 1; 40 | #20 reset = 0; 41 | 42 | // Wait for the SDRAM to finish initialising. 43 | while (!m_ack) begin 44 | m_cyc = 0; m_stb = 0; 45 | 46 | #20 m_cyc = 1; m_stb = 1; 47 | while (!m_ack && !m_rty) #20 ; 48 | end 49 | m_cyc = 0; m_stb = 0; 50 | 51 | // Write 16 words. 52 | #40 m_cti = 3'b010; 53 | m_cyc = 1; 54 | m_stb = 1; 55 | m_we = 1; 56 | m_adr = 0; 57 | m_sel_t = 4'b1111; 58 | m_dat_t = $random; 59 | for (ii=1; ii<16; ii=ii+1) begin 60 | #20 ; 61 | while (!m_ack) #20 ; 62 | if (ii==15) m_cti = 3'b111; 63 | m_adr[3:0] = ii[3:0]; 64 | m_dat_t = $random; 65 | end 66 | #20 m_cyc = 0; m_stb = 0; m_we = 0; 67 | 68 | // Read back 16 words. 69 | #40 m_cti = 3'b010; 70 | m_cyc = 1; 71 | m_stb = 1; 72 | m_we = 0; 73 | m_adr = 0; 74 | for (ii=1; ii<16; ii=ii+1) begin 75 | #20 ; 76 | while (!m_ack) #20 ; 77 | if (ii==15) m_cti = 3'b111; 78 | m_adr[3:0] = ii[3:0]; 79 | end 80 | #20 m_cyc = 0; m_stb = 0; 81 | 82 | // Read just one word. 83 | #20 m_cti = 0; 84 | m_cyc = 1; m_stb = 1; m_we = 0; m_adr = 0; 85 | while (!m_ack) #20 ; 86 | m_cyc = 0; m_stb = 0; 87 | 88 | 89 | #600 90 | $display ("Test completed."); 91 | $finish; 92 | end 93 | 94 | 95 | initial begin : Safety_Net 96 | #750000 97 | // #27500 98 | $display ("ERROR: Unclean exit"); 99 | $finish; 100 | end // Safety_Net 101 | 102 | 103 | assign sdr_a[12] = 0; 104 | wb_sdram_ctrl #( 105 | .ADDRESS (21), // 8 MB (2Mx32) 106 | .HIGHZ (0), 107 | .RFC_PERIOD (30), // 100 MHz timings (off 50 MHz sys clock) 108 | // .RFC_PERIOD (780), // 100 MHz timings (off 50 MHz sys clock) 109 | .tRAS (3), 110 | .tRC (3), 111 | .tRFC (3) 112 | ) SDRCTRL ( 113 | .sdr_clk_i (clk100), 114 | .wb_clk_i (clk50), 115 | .wb_clk_ni (~clk50), 116 | .wb_rst_i (reset), 117 | .wb_cyc_i (m_cyc), 118 | .wb_stb_i (m_stb), 119 | .wb_we_i (m_we), 120 | .wb_ack_o (m_ack), 121 | .wb_rty_o (m_rty), 122 | .wb_err_o (m_err), 123 | .wb_cti_i (m_cti), 124 | .wb_bte_i (m_bte), 125 | .wb_adr_i (m_adr), 126 | .wb_sel_i (m_sel_t), 127 | .wb_dat_i (m_dat_t), 128 | .wb_sel_o (m_sel_f), 129 | .wb_dat_o (m_dat_f), 130 | 131 | // SDRAM pins. 132 | .CLK (sdr_clk), 133 | .CKE (sdr_cke), 134 | .CS_n (sdr_cs_n), 135 | .RAS_n (sdr_ras_n), 136 | .CAS_n (sdr_cas_n), 137 | .WE_n (sdr_we_n), 138 | .BA (sdr_ba), 139 | .A (sdr_a[11:0]), 140 | .DM (sdr_dm), 141 | .DQ (sdr_dq) 142 | ); 143 | 144 | 145 | mt48lc4m16a2 MEM0 ( 146 | .Dq (sdr_dq), 147 | .Addr (sdr_a[11:0]), 148 | .Ba (sdr_ba), 149 | .Clk (sdr_clk), 150 | .Cke (sdr_cke), 151 | .Cs_n (sdr_cs_n), 152 | .Ras_n (sdr_ras_n), 153 | .Cas_n (sdr_cas_n), 154 | .We_n (sdr_we_n), 155 | .Dqm (sdr_dm) 156 | ); 157 | 158 | 159 | endmodule // wb_sdram_ctrl_tb 160 | --------------------------------------------------------------------------------