├── Octavo ├── Tests │ ├── AOM │ │ ├── test_harness │ │ │ ├── empty.mem │ │ │ ├── Generic_test_harness.qpf │ │ │ └── run_test_harness │ │ └── test_bench │ │ │ ├── empty.mem │ │ │ └── run_test_bench │ ├── Octavo │ │ ├── test_bench │ │ │ ├── hailstone-s │ │ │ │ ├── LOG │ │ │ │ │ ├── LOG.lint │ │ │ │ │ ├── LOG.verilate │ │ │ │ │ └── LOG.compile │ │ │ │ ├── RUN │ │ │ │ │ ├── VDUT │ │ │ │ │ ├── DO.mem │ │ │ │ │ ├── PC.mem │ │ │ │ │ ├── PC_prev.mem │ │ │ │ │ └── OD.mem │ │ │ │ ├── NOTES │ │ │ │ ├── run_test_bench │ │ │ │ └── test_bench.cpp │ │ │ ├── array-reverse-3 │ │ │ │ ├── LOG │ │ │ │ │ ├── LOG.verilate │ │ │ │ │ ├── LOG.output │ │ │ │ │ └── LOG.compile │ │ │ │ ├── RUN │ │ │ │ │ ├── VDUT │ │ │ │ │ ├── DO.mem │ │ │ │ │ ├── PC.mem │ │ │ │ │ ├── PC_prev.mem │ │ │ │ │ └── OD.mem │ │ │ │ ├── NOTES │ │ │ │ ├── suppressed_warnings │ │ │ │ ├── run_test_bench │ │ │ │ └── verilator_parameters │ │ │ ├── hailstone-arrays │ │ │ │ ├── LOG │ │ │ │ │ ├── LOG.lint │ │ │ │ │ ├── LOG.verilate │ │ │ │ │ └── LOG.compile │ │ │ │ ├── RUN │ │ │ │ │ ├── DO.mem │ │ │ │ │ ├── PC.mem │ │ │ │ │ ├── PC_prev.mem │ │ │ │ │ └── OD.mem │ │ │ │ ├── run_test_bench │ │ │ │ └── verilator_parameters │ │ │ └── .gitignore │ │ └── test_harness │ │ │ ├── Generic_test_harness.qpf │ │ │ ├── run_test_harness │ │ │ ├── DO.mem │ │ │ ├── PC.mem │ │ │ ├── PC_prev.mem │ │ │ └── OD.mem │ ├── Datapath │ │ └── test_harness │ │ │ ├── Datapath_test_harness.qpf │ │ │ └── run_test_harness │ ├── Instruction_Memory │ │ └── test_harness │ │ │ ├── Generic_test_harness.qpf │ │ │ ├── run_test_harness │ │ │ └── empty.cmem │ ├── Triadic_ALU │ │ ├── test_harness │ │ │ ├── Triadic_ALU_test_harness.qpf │ │ │ └── run_test_harness │ │ └── test_bench │ │ │ └── run_test_bench │ ├── Address_Decoders │ │ ├── test_harness │ │ │ ├── Address_Decoders_test_harness.qpf │ │ │ ├── run_test_harness │ │ │ └── Address_Decoders_test_harness.v │ │ └── test_bench │ │ │ ├── run_test_bench │ │ │ └── Address_Decoders_test_bench.v │ ├── Accelerators │ │ ├── Sliding_Window │ │ │ ├── run_test_bench │ │ │ ├── Sliding_Window.qpf │ │ │ └── Sliding_Window_test_bench.v │ │ ├── Array_Reverse_IO │ │ │ ├── run_test_bench │ │ │ ├── Array_Reverse_IO.qpf │ │ │ └── Array_Reverse_IO_test_bench.v │ │ ├── Add_Reducer │ │ │ ├── run_test_bench │ │ │ ├── Add_Reducer_test_harness.qpf │ │ │ └── Add_Reducer_test_bench.v │ │ └── Accumulator │ │ │ ├── run_test_bench │ │ │ ├── Accumulator_test_harness.qpf │ │ │ └── Accumulator_test_bench.v │ ├── controller_test_bench.v │ └── alu_test_bench.v ├── Diagrams │ ├── .gitignore │ ├── topdf.sh │ ├── topng.sh │ ├── triadic.fig │ ├── Address_Splitter.fig │ └── IO_Ready.fig ├── Assembler │ ├── .gitignore │ ├── benchmarks │ │ ├── hailstone-a │ │ │ └── run_assembler │ │ ├── hailstone-s │ │ │ ├── run_assembler │ │ │ ├── DO.mem │ │ │ ├── PC.mem │ │ │ ├── PC_prev.mem │ │ │ └── OD.mem │ │ ├── array-reverse-3 │ │ │ ├── run_assembler │ │ │ ├── DO.mem │ │ │ ├── PC.mem │ │ │ ├── PC_prev.mem │ │ │ ├── array-reverse-3.asm │ │ │ └── OD.mem │ │ ├── hailstone-arrays │ │ │ ├── run_assembler │ │ │ ├── DO.mem │ │ │ ├── PC.mem │ │ │ ├── PC_prev.mem │ │ │ └── OD.mem │ │ └── common │ │ │ ├── conditions.asm │ │ │ └── opcodes.asm │ ├── README.md │ ├── archive │ │ ├── tally_pc.sh │ │ ├── branching_flags.py │ │ ├── check_hailstone.py │ │ ├── generate_hailstone_numbers.py │ │ ├── generate_hailstone_numbers_modified.py │ │ ├── README.md │ │ ├── opcodes.py │ │ └── memory_map.py │ ├── Utility.py │ ├── Debug.py │ ├── Parser.py │ └── Assembler.py ├── Issues │ ├── README.md │ └── backup-issues.sh ├── Source │ ├── R_Flags.v │ ├── Split_Extractor.v │ ├── IO_All_Ready.v │ ├── Sentinel_Value_Check.v │ ├── Global_Defines.vh │ ├── Instruction_Field_Extractor.v │ ├── Triadic_ALU_Operations.vh │ ├── IO_Write_Predication.v │ ├── Accelerators │ │ └── Array_Reverse_IO.v │ ├── IO_Active.v │ └── Memory_IO_Predication.v └── README.md ├── .gitignore ├── Parts ├── SimSynth │ ├── load_bitstream_quartus │ ├── simulation_defines.vh │ └── simulation_clock.v ├── NoC │ ├── README.md │ ├── skid_buffer_example.v │ ├── skid_buffer_datapath.v │ ├── Master_AXI_Sequencer_Read.v │ ├── skid_buffer.v │ └── Master_AXI_Sequencer_Write.v ├── TestHarness │ ├── README.md │ ├── harness_output_register.v │ ├── harness_input_register.v │ └── harness_example.v ├── README.md ├── Misc │ ├── clog2_function.vh │ ├── Inverter.v │ ├── Register_Array.v │ ├── master_reset.v │ ├── Word_OR_Reducer.v │ └── Annuller.v ├── CDC │ ├── pulse_to_level_example.v │ ├── cdc_synchronizer_example.v │ ├── posedge_pulse_generator_example.v │ ├── cdc_pulse_synchronizer_example.v │ ├── pulse_to_level.v │ ├── posedge_pulse_generator.v │ └── cdc_synchronizer.v ├── verilinter ├── Arbiters │ ├── Round_Robin_Arbiter_Example.v │ ├── Priority_Arbiter.v │ ├── Thermometer_Mask.v │ ├── Priority_Selector.v │ └── Round_Robin_Arbiter.v ├── ALU │ ├── Carryin_Calculator.v │ ├── Dyadic_Boolean_Operations.vh │ ├── Dyadic_Boolean_Operator.v │ ├── AddSub_Ripple_Carry.v │ └── AddSub_Ripple_Carry_NoCarry.v ├── Multithreading │ ├── Delay_Line_Example.v │ ├── Thread_Number_Example.v │ ├── Delay_Line.v │ └── Thread_Number.v ├── Multiplexers │ ├── Bitwise_2to1_Mux_Example.v │ ├── One_Hot_Mux_Example.v │ ├── Addressed_Mux.v │ ├── Bitwise_2to1_Mux.v │ ├── Translated_Addressed_Mux_Example.v │ ├── One_Hot_Mux.v │ └── Translated_Addressed_Mux.v ├── Branching │ └── Condition_Predicate_Operations.vh ├── Address_Decode │ ├── Binary_to_N_Decoder.v │ ├── Address_Range_Decoder_Arithmetic.v │ ├── Address_Splitter.v │ └── Address_Range_Decoder_Static.v ├── Counters │ ├── UpDown_Counter_Example.v │ ├── Down_Counter_Zero_Example.v │ ├── UpDown_Counter.v │ └── Down_Counter_Zero.v ├── Memory │ ├── generate_init_file.py │ ├── RAM_SDP_Example.v │ ├── RAM_TDP_Example.v │ └── RAM_SDP_Composite_Example.v └── Multipliers │ └── Multiplier_Generic.v ├── Tests ├── Word_OR_Reducer │ ├── test_harness │ │ ├── Word_OR_Reducer_test_harness.qpf │ │ ├── run_test_harness │ │ └── Word_OR_Reducer_test_harness.v │ └── test_bench │ │ ├── run_test_bench │ │ └── Word_OR_Reducer_test_bench.v ├── README.md ├── Dyadic_Boolean_Operator │ ├── test_harness │ │ ├── Dyadic_Boolean_Operator_test_harness.qpf │ │ ├── run_test_harness │ │ └── Dyadic_Boolean_Operator_test_harness.v │ └── test_bench │ │ ├── run_test_bench │ │ └── Dyadic_Boolean_Operator_test_bench.v ├── .gitignore └── skid_buffer │ ├── simulation_clock.v │ ├── DUT.v │ └── skid_buffer.qpf ├── README.md └── LICENSE /Octavo/Tests/AOM/test_harness/empty.mem: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.bak 3 | *.py[cod] 4 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-s/LOG/LOG.lint: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Octavo/Diagrams/.gitignore: -------------------------------------------------------------------------------- 1 | *.bak 2 | *.png 3 | *.pdf 4 | 5 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/array-reverse-3/LOG/LOG.verilate: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-arrays/LOG/LOG.lint: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-s/LOG/LOG.verilate: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-arrays/LOG/LOG.verilate: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Octavo/Assembler/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.swp 3 | *.swo 4 | LOG.* 5 | 6 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/.gitignore: -------------------------------------------------------------------------------- 1 | *.vcd 2 | **/obj_dir 3 | 4 | -------------------------------------------------------------------------------- /Parts/SimSynth/load_bitstream_quartus: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | quartus_pgm -z -m JTAG -o "p;$1" 3 | 4 | -------------------------------------------------------------------------------- /Octavo/Tests/AOM/test_harness/Generic_test_harness.qpf: -------------------------------------------------------------------------------- 1 | 2 | PROJECT_REVISION = "Generic_test_harness" 3 | 4 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_harness/Generic_test_harness.qpf: -------------------------------------------------------------------------------- 1 | 2 | PROJECT_REVISION = "Generic_test_harness" 3 | 4 | -------------------------------------------------------------------------------- /Octavo/Issues/README.md: -------------------------------------------------------------------------------- 1 | 2 | Just a small script to dump issues and comments and check them in, as backup. 3 | 4 | -------------------------------------------------------------------------------- /Octavo/Tests/Datapath/test_harness/Datapath_test_harness.qpf: -------------------------------------------------------------------------------- 1 | 2 | PROJECT_REVISION = "Datapath_test_harness" 3 | 4 | -------------------------------------------------------------------------------- /Octavo/Diagrams/topdf.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | for i in $* 4 | do 5 | echo $i 6 | epstopdf $i 7 | done 8 | 9 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/hailstone-a/run_assembler: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | python3 ../../Assembler.py hailstone-a.asm 4 | 5 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/hailstone-s/run_assembler: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | python3 ../../Assembler.py hailstone-s.asm 4 | 5 | -------------------------------------------------------------------------------- /Octavo/Tests/Instruction_Memory/test_harness/Generic_test_harness.qpf: -------------------------------------------------------------------------------- 1 | 2 | PROJECT_REVISION = "Generic_test_harness" 3 | 4 | -------------------------------------------------------------------------------- /Octavo/Tests/Triadic_ALU/test_harness/Triadic_ALU_test_harness.qpf: -------------------------------------------------------------------------------- 1 | 2 | PROJECT_REVISION = "Triadic_ALU_test_harness" 3 | 4 | -------------------------------------------------------------------------------- /Parts/NoC/README.md: -------------------------------------------------------------------------------- 1 | 2 | Building blocks for Network-on-Chip, independent of the particular bus/interconnect protocol. 3 | 4 | -------------------------------------------------------------------------------- /Tests/Word_OR_Reducer/test_harness/Word_OR_Reducer_test_harness.qpf: -------------------------------------------------------------------------------- 1 | 2 | PROJECT_REVISION = "Word_OR_Reducer_test_harness" 3 | 4 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/array-reverse-3/run_assembler: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | python3 ../../Assembler.py array-reverse-3.asm 4 | 5 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/hailstone-arrays/run_assembler: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | python3 ../../Assembler.py hailstone-arrays.asm 4 | 5 | -------------------------------------------------------------------------------- /Octavo/Tests/Address_Decoders/test_harness/Address_Decoders_test_harness.qpf: -------------------------------------------------------------------------------- 1 | 2 | PROJECT_REVISION = "Address_Decoders_test_harness" 3 | 4 | -------------------------------------------------------------------------------- /Octavo/Tests/AOM/test_harness/run_test_harness: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | quartus_sh --flow compile Generic_test_harness 2>&1 | tee LOG_QUARTUS 4 | 5 | -------------------------------------------------------------------------------- /Octavo/Tests/Datapath/test_harness/run_test_harness: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | quartus_sh --flow compile Datapath_test_harness 2>&1 | tee LOG_QUARTUS 4 | 5 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-s/RUN/VDUT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laforest/Octavo/HEAD/Octavo/Tests/Octavo/test_bench/hailstone-s/RUN/VDUT -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_harness/run_test_harness: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | quartus_sh --flow compile Generic_test_harness 2>&1 | tee LOG_QUARTUS 4 | 5 | -------------------------------------------------------------------------------- /Tests/README.md: -------------------------------------------------------------------------------- 1 | 2 | Contains one-off test benches and test harnesses, built as-needed when developing new parts. Not guaranteed to be current. 3 | 4 | -------------------------------------------------------------------------------- /Tests/Dyadic_Boolean_Operator/test_harness/Dyadic_Boolean_Operator_test_harness.qpf: -------------------------------------------------------------------------------- 1 | 2 | PROJECT_REVISION = "Dyadic_Boolean_Operator_test_harness" 3 | 4 | -------------------------------------------------------------------------------- /Octavo/Tests/Instruction_Memory/test_harness/run_test_harness: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | quartus_sh --flow compile Generic_test_harness 2>&1 | tee LOG_QUARTUS 4 | 5 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/array-reverse-3/RUN/VDUT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laforest/Octavo/HEAD/Octavo/Tests/Octavo/test_bench/array-reverse-3/RUN/VDUT -------------------------------------------------------------------------------- /Octavo/Tests/Triadic_ALU/test_harness/run_test_harness: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | quartus_sh --flow compile Triadic_ALU_test_harness 2>&1 | tee LOG_QUARTUS 4 | 5 | -------------------------------------------------------------------------------- /Tests/Word_OR_Reducer/test_harness/run_test_harness: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | quartus_sh --flow compile Word_OR_Reducer_test_harness 2>&1 | tee LOG_QUARTUS 4 | 5 | -------------------------------------------------------------------------------- /Octavo/Tests/Address_Decoders/test_harness/run_test_harness: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | quartus_sh --flow compile Address_Decoders_test_harness 2>&1 | tee LOG_QUARTUS 4 | 5 | -------------------------------------------------------------------------------- /Tests/Dyadic_Boolean_Operator/test_harness/run_test_harness: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | quartus_sh --flow compile Dyadic_Boolean_Operator_test_harness 2>&1 | tee LOG_QUARTUS 4 | 5 | -------------------------------------------------------------------------------- /Octavo/Assembler/README.md: -------------------------------------------------------------------------------- 1 | 2 | First draft of new assembler for Octavo. 3 | Just a simple one for initial hardware testing and benchmarking. 4 | *Not ready yet. Work in progress* 5 | 6 | 7 | -------------------------------------------------------------------------------- /Octavo/Diagrams/topng.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | for i in $* 4 | do 5 | echo $i 6 | j=`basename $i .eps`.png 7 | convert -density 600 -alpha off -depth 1 $i $j 8 | done 9 | 10 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_harness/DO.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 07c 4 | 0f8 5 | 174 6 | 1f0 7 | 26c 8 | 2e8 9 | 364 10 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_harness/PC.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Tests/.gitignore: -------------------------------------------------------------------------------- 1 | # Quartus output files 2 | **/dse/** 3 | **/db/** 4 | **/incremental_db/** 5 | *.rpt 6 | *.summary 7 | *.smsg 8 | *.done 9 | *.pin 10 | *.dse 11 | *.qws 12 | *.log 13 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/hailstone-s/DO.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 07c 4 | 0f8 5 | 174 6 | 1f0 7 | 26c 8 | 2e8 9 | 364 10 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/hailstone-s/PC.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_harness/PC_prev.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/array-reverse-3/DO.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 07c 4 | 0f8 5 | 174 6 | 1f0 7 | 26c 8 | 2e8 9 | 364 10 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/array-reverse-3/PC.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/hailstone-arrays/DO.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 07c 4 | 0f8 5 | 174 6 | 1f0 7 | 26c 8 | 2e8 9 | 364 10 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/hailstone-arrays/PC.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/hailstone-s/PC_prev.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/array-reverse-3/PC_prev.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/hailstone-arrays/PC_prev.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/array-reverse-3/RUN/DO.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 07c 4 | 0f8 5 | 174 6 | 1f0 7 | 26c 8 | 2e8 9 | 364 10 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/array-reverse-3/RUN/PC.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-s/RUN/DO.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 07c 4 | 0f8 5 | 174 6 | 1f0 7 | 26c 8 | 2e8 9 | 364 10 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-s/RUN/PC.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/array-reverse-3/RUN/PC_prev.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-arrays/RUN/DO.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 07c 4 | 0f8 5 | 174 6 | 1f0 7 | 26c 8 | 2e8 9 | 364 10 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-arrays/RUN/PC.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-s/RUN/PC_prev.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-arrays/RUN/PC_prev.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 000 3 | 000 4 | 000 5 | 000 6 | 000 7 | 000 8 | 000 9 | 000 10 | -------------------------------------------------------------------------------- /Octavo/Assembler/archive/tally_pc.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Simply tallies all entries of form "# PC: " 4 | # Used to measure ALU efficiency 5 | 6 | grep PC: LOG | sed -r -e's/^# PC: +//' | sort -n | uniq -c | gview - 7 | 8 | -------------------------------------------------------------------------------- /Octavo/Assembler/archive/branching_flags.py: -------------------------------------------------------------------------------- 1 | # /usr/bin/python 2 | 3 | # Branch conditions and their encodings 4 | # We use the old opcode mnemonics for reference 5 | 6 | JMP, JZE, JNZ, JPO, JNE, JUND1, JUND2, JEV = range(0,8) 7 | 8 | -------------------------------------------------------------------------------- /Octavo/Issues/backup-issues.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | wget https://api.github.com/repos/laforest/octavo/issues?state=all -O issues.json 4 | wget https://api.github.com/repos/laforest/octavo/issues/comments -O issues-comments.json 5 | 6 | -------------------------------------------------------------------------------- /Octavo/Assembler/archive/check_hailstone.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | 3 | import sys 4 | 5 | n = int(sys.argv[1]) 6 | while (n > 1): 7 | if(n % 2 == 0): 8 | n = n / 2 9 | else: 10 | n = (3*n + 1) / 2 11 | print "%d " % n, 12 | 13 | -------------------------------------------------------------------------------- /Octavo/Assembler/archive/generate_hailstone_numbers.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | 3 | import sys 4 | 5 | n = int(sys.argv[1]) 6 | while (n > 1): 7 | if(n % 2 == 0): 8 | n = n / 2 9 | else: 10 | n = 3*n + 1 11 | print "%d" % n 12 | 13 | -------------------------------------------------------------------------------- /Octavo/Assembler/archive/generate_hailstone_numbers_modified.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | 3 | import sys 4 | 5 | n = int(sys.argv[1]) 6 | while (n > 1): 7 | if(n % 2 == 0): 8 | n = n / 2 9 | else: 10 | n = (3*n + 1) / 2 11 | print "%d " % n, 12 | 13 | -------------------------------------------------------------------------------- /Octavo/Assembler/archive/README.md: -------------------------------------------------------------------------------- 1 | 2 | This is the old pseudo-assembler for Octavo. 3 | *Don't use it, it's no longer valid.* 4 | Kept here for now since it contains all the past benchmarks and other useful data. 5 | These will get re-implemented when a new, real assembler is made. 6 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | * Parts: Library of Verilog modules for all kinds of functions tailored to FPGAs. 3 | * Tests: various one-off test benches and test harnesse, written as-needed. 4 | * Octavo: sources, diagrams, assembler, etc.. for the Octavo soft-CPU. Details: http://fpgacpu.ca/octavo/ 5 | 6 | -------------------------------------------------------------------------------- /Parts/TestHarness/README.md: -------------------------------------------------------------------------------- 1 | 2 | The test harness exists solely to isolate I/O to prevent overly optimistic 3 | optimizations (and thus timing results). It also reduces the number of pins to 4 | 1 bit per I/O to prevent running out during testing. The test harness is not 5 | usable for simulation, as the I/O values are mangled to nonsense. 6 | 7 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/array-reverse-3/NOTES: -------------------------------------------------------------------------------- 1 | Simulation cycles from gtkwave, from first write to output to the next: 1246 / 8 = 155.75 2 | Cycles, as output by test bench: 1280 - 24 = 1256 / 8 = 157 3 | Cycles, calculated (3 per swap, times 49 swaps, plus 6 init = 153 4 | 5 | Divided by 100 array items: 1.56, 1.56, and 1.53 cycles/item 6 | 7 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-s/NOTES: -------------------------------------------------------------------------------- 1 | gtkwave cycles: 8979ns / 2 ns/cycle = 4489 cycles 2 | cycles per thread : 4489 / 8 = 561.1 cycles 3 | cycles per result: 561.1 / 100 = 5.611 cycles 4 | (Fmax 222 MHz) 5 | One cycle slower than in thesis due to NOP waiting for Multiplier accelerator. 6 | Ratio: 5.611 / 4.55 = 1.23x slower. (ouch) 7 | 8 | -------------------------------------------------------------------------------- /Parts/README.md: -------------------------------------------------------------------------------- 1 | 2 | Contains a library of Verilog modules to implement all kinds of functions. 3 | The code is optimized for speed on FPGAs. 4 | 5 | If you are adding to this library, your code must be Verilator-clean. 6 | The verilinter script will do the checking for you, and automatically look-up any needed sub-modules in the Parts library. 7 | 8 | -------------------------------------------------------------------------------- /Octavo/Tests/AOM/test_bench/empty.mem: -------------------------------------------------------------------------------- 1 | 00000 2 | 00000 3 | 00000 4 | 00000 5 | 00000 6 | 00000 7 | 00000 8 | 00000 9 | 00000 10 | 00000 11 | 00000 12 | 00000 13 | 00000 14 | 00000 15 | 00000 16 | 00000 17 | 00000 18 | 00000 19 | 00000 20 | 00000 21 | 00000 22 | 00000 23 | 00000 24 | 00000 25 | 00000 26 | 00000 27 | 00000 28 | 00000 29 | 00000 30 | 00000 31 | 00000 32 | 00000 33 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/array-reverse-3/suppressed_warnings: -------------------------------------------------------------------------------- 1 | 2 | // These warnings are suppresed to allow compilation to complete. 3 | // After looking them over, the remaining ones are due to style or disagreement 4 | // on programming practice, but should synthesize correctly. 5 | // Do not apply them when linting. 6 | 7 | -Wno-BLKSEQ 8 | -Wno-COMBDLY 9 | -Wno-INITIALDLY 10 | -Wno-PINCONNECTEMPTY 11 | -Wno-UNUSED 12 | -Wno-WIDTH 13 | 14 | -------------------------------------------------------------------------------- /Parts/Misc/clog2_function.vh: -------------------------------------------------------------------------------- 1 | 2 | // Ceiling of logarithm, base 2 3 | // Taken from Verilog-2001 standard example 4 | // Since $clog2() doesn't exist prior to Verilog-2005 (and thus, SystemVerilog) 5 | 6 | function integer clog2; 7 | input integer value; 8 | begin 9 | value = value - 1; 10 | for (clog2 = 0; value > 0; clog2 = clog2 + 1) begin 11 | value = value >> 1; 12 | end 13 | end 14 | endfunction 15 | 16 | -------------------------------------------------------------------------------- /Octavo/Assembler/archive/opcodes.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | 3 | # Opcodes, assigned their integer values, carefully chosen. 4 | # XOR must always be 0, since XOR, O, O, O makes a useful NOP 5 | 6 | # XOR, AND, OR, SUB, ADD, UND1, UND2, UND3, MHS, MLS, MHU, JMP, JZE, JNZ, JPO, JNE = range(16) 7 | 8 | # Jumps no longer exist as opcodes, see branching_flags.py 9 | 10 | XOR, AND, OR, SUB, ADD, UND1, UND2, UND3, MHS, MLS, MHU, UND4, UND5, UND6, UND7, UND8 = range(16) 11 | 12 | -------------------------------------------------------------------------------- /Octavo/Tests/Instruction_Memory/test_harness/empty.cmem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 00000 3 | 00000 4 | 00000 5 | 00000 6 | 00000 7 | 00000 8 | 00000 9 | 00000 10 | 00000 11 | 00000 12 | 00000 13 | 00000 14 | 00000 15 | 00000 16 | 00000 17 | 00000 18 | 00000 19 | 00000 20 | 00000 21 | 00000 22 | 00000 23 | 00000 24 | 00000 25 | 00000 26 | 00000 27 | 00000 28 | 00000 29 | 00000 30 | 00000 31 | 00000 32 | 00000 33 | 00000 34 | -------------------------------------------------------------------------------- /Parts/CDC/pulse_to_level_example.v: -------------------------------------------------------------------------------- 1 | 2 | `default_nettype none 3 | 4 | module pulse_to_level_example 5 | // No parameters 6 | ( 7 | input wire clock, 8 | input wire clear, 9 | input wire pulse_in, 10 | output reg level_out 11 | ); 12 | 13 | pulse_to_level 14 | example 15 | ( 16 | .clock (clock), 17 | .clear (clear), 18 | .pulse_in (pulse_in), 19 | .level_out (level_out) 20 | ); 21 | 22 | endmodule 23 | 24 | -------------------------------------------------------------------------------- /Parts/verilinter: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Lint files as Verilog-2001, finding submodules as needed in whole Parts repo 4 | 5 | ALL_FILES=$@ 6 | 7 | # Where is this repo located (absolute path) 8 | GIT_ROOT=$(git rev-parse --show-toplevel) 9 | 10 | # Find all directories and prepend "-y" to each 11 | SEARCH_DIRS=$(find ${GIT_ROOT}/Parts -type d -exec echo "-y" {} \;) 12 | 13 | for FILE in ${ALL_FILES} 14 | do 15 | verilator -Wall +1364-2001ext+v ${SEARCH_DIRS} --lint-only ${FILE} 16 | done 17 | 18 | -------------------------------------------------------------------------------- /Parts/CDC/cdc_synchronizer_example.v: -------------------------------------------------------------------------------- 1 | 2 | module cdc_synchronizer_example 3 | #( 4 | parameter EXTRA_DEPTH = 3 5 | ) 6 | ( 7 | input wire sync_bit_from, 8 | input wire clock_to, 9 | output reg sync_bit_to 10 | ); 11 | 12 | cdc_synchronizer 13 | #( 14 | .EXTRA_DEPTH (EXTRA_DEPTH) 15 | ) 16 | example 17 | ( 18 | .sync_bit_from (sync_bit_from), 19 | .clock_to (clock_to), 20 | .sync_bit_to (sync_bit_to) 21 | ); 22 | 23 | endmodule 24 | 25 | -------------------------------------------------------------------------------- /Parts/CDC/posedge_pulse_generator_example.v: -------------------------------------------------------------------------------- 1 | 2 | module posedge_pulse_generator_example 3 | #( 4 | parameter PULSE_LENGTH = 3 5 | ) 6 | ( 7 | input wire clock, 8 | input wire level_in, 9 | output reg pulse_out 10 | ); 11 | 12 | posedge_pulse_generator 13 | #( 14 | .PULSE_LENGTH (PULSE_LENGTH) 15 | ) 16 | example 17 | ( 18 | .clock (clock), 19 | .level_in (level_in), 20 | .pulse_out (pulse_out) 21 | ); 22 | 23 | endmodule 24 | 25 | -------------------------------------------------------------------------------- /Parts/Arbiters/Round_Robin_Arbiter_Example.v: -------------------------------------------------------------------------------- 1 | 2 | module Round_Robin_Arbiter_Example 3 | #( 4 | parameter WORD_WIDTH = 17 5 | ) 6 | ( 7 | input wire clock, 8 | input wire [WORD_WIDTH-1:0] requests, 9 | output reg [WORD_WIDTH-1:0] grant 10 | ); 11 | 12 | Round_Robin_Arbiter 13 | #( 14 | .WORD_WIDTH (WORD_WIDTH) 15 | ) 16 | Example 17 | ( 18 | .clock (clock), 19 | .requests (requests), 20 | .grant (grant) 21 | ); 22 | 23 | endmodule 24 | 25 | -------------------------------------------------------------------------------- /Parts/ALU/Carryin_Calculator.v: -------------------------------------------------------------------------------- 1 | 2 | // Infers carry-in to each bit position given both addends A/B and their sum S. 3 | 4 | `default_nettype none 5 | 6 | module Carryin_Calculator 7 | #( 8 | parameter WORD_WIDTH = 0 9 | ) 10 | ( 11 | input wire [WORD_WIDTH-1:0] A, 12 | input wire [WORD_WIDTH-1:0] B, 13 | input wire [WORD_WIDTH-1:0] S, 14 | output reg [WORD_WIDTH-1:0] Cin 15 | ); 16 | 17 | initial begin 18 | Cin = 0; 19 | end 20 | 21 | always @(*) begin 22 | Cin = A ^ B ^ S; 23 | end 24 | 25 | endmodule 26 | 27 | -------------------------------------------------------------------------------- /Parts/Multithreading/Delay_Line_Example.v: -------------------------------------------------------------------------------- 1 | `default_nettype none 2 | 3 | module Delay_Line_Example 4 | #( 5 | parameter DEPTH = 5, 6 | parameter WIDTH = 42 7 | ) 8 | ( 9 | input wire clock, 10 | input wire [WIDTH-1:0] in, 11 | output reg [WIDTH-1:0] out 12 | ); 13 | 14 | Delay_Line 15 | #( 16 | .DEPTH (DEPTH), 17 | .WIDTH (WIDTH) 18 | ) 19 | Example 20 | ( 21 | .clock (clock), 22 | .in (in), 23 | .out (out) 24 | ); 25 | 26 | endmodule 27 | 28 | -------------------------------------------------------------------------------- /Parts/Misc/Inverter.v: -------------------------------------------------------------------------------- 1 | 2 | // Inverts a value (bitwise NOT if enabled) 3 | 4 | // We put something this simple into a module since it conveys intent, 5 | // and avoids an RTL schematic cluttered with a bunch of XOR gates. 6 | 7 | `default_nettype none 8 | 9 | module Inverter 10 | #( 11 | parameter WORD_WIDTH = 0 12 | ) 13 | ( 14 | input wire invert, 15 | input wire [WORD_WIDTH-1:0] in, 16 | output reg [WORD_WIDTH-1:0] out 17 | ); 18 | 19 | always @(*) begin 20 | out = (invert == 1'b1) ? ~in : in; 21 | end 22 | 23 | endmodule 24 | 25 | -------------------------------------------------------------------------------- /Tests/skid_buffer/simulation_clock.v: -------------------------------------------------------------------------------- 1 | 2 | // Clock generator for simulation 3 | 4 | `default_nettype none 5 | 6 | `timescale 1 ns / 1 ps 7 | 8 | module simulation_clock 9 | #( 10 | parameter CLOCK_PERIOD = 10 11 | ) 12 | ( 13 | output reg clock 14 | ); 15 | 16 | localparam HALF_PERIOD = CLOCK_PERIOD / 2; 17 | 18 | // NOTE: clock is deliberately left uninitialized, and thus X in most 19 | // simulators, and will not trigger a (X -> 0) edge until after the 20 | // simulated clock half-period delay. 21 | 22 | always begin 23 | #HALF_PERIOD clock = (clock === 1'b0); 24 | end 25 | 26 | endmodule 27 | 28 | -------------------------------------------------------------------------------- /Parts/Arbiters/Priority_Arbiter.v: -------------------------------------------------------------------------------- 1 | 2 | // Simple priority arbiter. 3 | // Returns the LSB set, where bit 0 has highest priority 4 | // Core logic from Hacker's Delight, Chapter 2. 5 | 6 | `default_nettype none 7 | 8 | module Priority_Arbiter 9 | #( 10 | parameter WORD_WIDTH = 0 11 | ) 12 | ( 13 | input wire [WORD_WIDTH-1:0] requests, 14 | output reg [WORD_WIDTH-1:0] grant 15 | ); 16 | 17 | localparam ZERO = {WORD_WIDTH{1'b0}}; 18 | 19 | initial begin 20 | grant = ZERO; 21 | end 22 | 23 | always @(*) begin 24 | grant = requests & -requests; 25 | end 26 | 27 | endmodule 28 | 29 | -------------------------------------------------------------------------------- /Parts/Multiplexers/Bitwise_2to1_Mux_Example.v: -------------------------------------------------------------------------------- 1 | 2 | `default_nettype none 3 | 4 | module Bitwise_2to1_Mux_Example 5 | #( 6 | parameter WORD_WIDTH = 36 7 | ) 8 | ( 9 | input wire [WORD_WIDTH-1:0] select_mask, 10 | input wire [WORD_WIDTH-1:0] in1, 11 | input wire [WORD_WIDTH-1:0] in2, 12 | output wire [WORD_WIDTH-1:0] out 13 | ); 14 | 15 | Bitwise_2to1_Mux 16 | #( 17 | .WORD_WIDTH (WORD_WIDTH) 18 | ) 19 | Example 20 | ( 21 | .select_mask (select_mask), 22 | .in1 (in1), 23 | .in2 (in2), 24 | .out (out) 25 | ); 26 | 27 | endmodule 28 | 29 | -------------------------------------------------------------------------------- /Parts/CDC/cdc_pulse_synchronizer_example.v: -------------------------------------------------------------------------------- 1 | 2 | module cdc_pulse_synchronizer_example 3 | #( 4 | parameter PULSE_LENGTH = 3, 5 | parameter EXTRA_DEPTH = 1 6 | ) 7 | ( 8 | input wire clock_from, 9 | input wire pulse_from, 10 | input wire clock_to, 11 | output wire pulse_to 12 | ); 13 | 14 | cdc_pulse_synchronizer 15 | #( 16 | .PULSE_LENGTH (PULSE_LENGTH), 17 | .EXTRA_DEPTH (EXTRA_DEPTH) 18 | ) 19 | example 20 | ( 21 | .clock_from (clock_from), 22 | .pulse_from (pulse_from), 23 | .clock_to (clock_to), 24 | .pulse_to (pulse_to) 25 | ); 26 | 27 | endmodule 28 | 29 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/array-reverse-3/LOG/LOG.output: -------------------------------------------------------------------------------- 1 | 24: ffffffff 2 | 25: ffffffff 3 | 26: ffffffff 4 | 27: ffffffff 5 | 28: ffffffff 6 | 29: ffffffff 7 | 30: ffffffff 8 | 31: ffffffff 9 | 1280: ffffffff 10 | 1281: ffffffff 11 | 1282: ffffffff 12 | 1283: ffffffff 13 | 1284: ffffffff 14 | 1285: ffffffff 15 | 1286: ffffffff 16 | 1287: ffffffff 17 | 2536: ffffffff 18 | 2537: ffffffff 19 | 2538: ffffffff 20 | 2539: ffffffff 21 | 2540: ffffffff 22 | 2541: ffffffff 23 | 2542: ffffffff 24 | 2543: ffffffff 25 | 3792: ffffffff 26 | 3793: ffffffff 27 | 3794: ffffffff 28 | 3795: ffffffff 29 | 3796: ffffffff 30 | 3797: ffffffff 31 | 3798: ffffffff 32 | 3799: ffffffff 33 | Simulation terminated normally at cycle 5000 34 | -------------------------------------------------------------------------------- /Parts/CDC/pulse_to_level.v: -------------------------------------------------------------------------------- 1 | 2 | // Latch pulse to level, until cleared 3 | 4 | `default_nettype none 5 | 6 | module pulse_to_level 7 | // No parameters 8 | ( 9 | input wire clock, 10 | input wire clear, 11 | input wire pulse_in, 12 | output reg level_out 13 | ); 14 | 15 | initial begin 16 | level_out = 1'b0; 17 | end 18 | 19 | reg level_out_internal = 1'b0; 20 | 21 | always @(*) begin 22 | level_out_internal = pulse_in | level_out; 23 | level_out_internal = (clear == 1'b1) ? 1'b0 : level_out_internal; 24 | end 25 | 26 | always @(posedge clock) begin 27 | level_out <= level_out_internal; 28 | end 29 | 30 | endmodule 31 | 32 | -------------------------------------------------------------------------------- /Parts/Multiplexers/One_Hot_Mux_Example.v: -------------------------------------------------------------------------------- 1 | 2 | `default_nettype none 3 | 4 | module One_Hot_Mux_Example 5 | #( 6 | parameter WORD_WIDTH = 32, 7 | parameter WORD_COUNT = 7, 8 | 9 | parameter TOTAL_WIDTH = WORD_COUNT * WORD_WIDTH 10 | ) 11 | ( 12 | input wire [WORD_COUNT-1:0] selectors, 13 | input wire [TOTAL_WIDTH-1:0] in, 14 | output wire [WORD_WIDTH-1:0] out 15 | ); 16 | 17 | One_Hot_Mux 18 | #( 19 | .WORD_WIDTH (WORD_WIDTH), 20 | .WORD_COUNT (WORD_COUNT) 21 | ) 22 | Example 23 | ( 24 | .selectors (selectors), 25 | .in (in), 26 | .out (out) 27 | ); 28 | 29 | endmodule 30 | 31 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/common/conditions.asm: -------------------------------------------------------------------------------- 1 | 2 | # Define branch conditions 3 | # The first available branch detector slot is assigned to a branch init, and consecutive branch inits are placed in decreasing priority branch detector slots. 4 | # By convention, if a or b is unused, then configure it as the selector with an all-zero value. (others will work, but make the binary values messier to look at) 5 | 6 | # a b Op 7 | 8 | jmp condition a_negative b_lessthan always_one # Jump always 9 | bsa condition a_sentinel b_lessthan a # Jump on Branch Sentinel A match 10 | ctz condition a_negative b_counter not_b # Jump on Counter reaching Zero (N-1 for N passes) 11 | 12 | -------------------------------------------------------------------------------- /Parts/Multiplexers/Addressed_Mux.v: -------------------------------------------------------------------------------- 1 | 2 | // Generic multiplexer 3 | // Pass a concatenation to "in" with the zeroth element on the right. 4 | 5 | `default_nettype none 6 | 7 | module Addressed_Mux 8 | #( 9 | parameter WORD_WIDTH = 0, 10 | parameter ADDR_WIDTH = 0, 11 | parameter INPUT_COUNT = 0, 12 | 13 | // Not for instantiation 14 | parameter TOTAL_WIDTH = WORD_WIDTH * INPUT_COUNT 15 | ) 16 | ( 17 | input wire [ADDR_WIDTH-1:0] addr, 18 | input wire [TOTAL_WIDTH-1:0] in, 19 | output reg [WORD_WIDTH-1:0] out 20 | ); 21 | 22 | always @(*) begin 23 | out = in[(addr * WORD_WIDTH) +: WORD_WIDTH]; 24 | end 25 | 26 | endmodule 27 | 28 | -------------------------------------------------------------------------------- /Parts/SimSynth/simulation_defines.vh: -------------------------------------------------------------------------------- 1 | 2 | // Simulation parameters and helper functions 3 | 4 | // This timescale matches the Altera libraries 5 | // synopsys translate_off 6 | `timescale 1 ps / 1 ps 7 | // synopsys translate_on 8 | 9 | // Drive the clock delay loop 10 | // Let's assume "100 MHz", in nanoseconds 11 | `define CLOCK_HALF_PERIOD_NS 5 12 | `define NS_TO_PS(ns) (1000*ns) 13 | `define DELAY_CLOCK_HALF_PERIOD #`NS_TO_PS(`CLOCK_HALF_PERIOD_NS) 14 | 15 | // Wait n cycles 16 | `define WAIT_CYCLES(n) repeat (n) begin @(posedge clock); end 17 | 18 | // Wait until posedge at cycle n 19 | // (define clock and cycle in test bench) 20 | `define UNTIL_DONE_CYCLE(n) wait (cycle == n); @(posedge clock); 21 | 22 | -------------------------------------------------------------------------------- /Parts/Branching/Condition_Predicate_Operations.vh: -------------------------------------------------------------------------------- 1 | 2 | // See Condition_Predicate.v 3 | 4 | `ifndef CONDITION_PREDICATE_OPERATIONS 5 | `define CONDITION_PREDICATE_OPERATIONS 6 | 7 | // Never changes 8 | `define GROUP_SELECTOR_WIDTH 2 9 | 10 | // First, the A/B group condition flag selectors 11 | 12 | `define A_GROUP_NEGATIVE 2'd0 13 | `define A_GROUP_CARRYOUT 2'd1 14 | `define A_GROUP_SENTINEL 2'd2 15 | `define A_GROUP_EXTERNAL 2'd3 16 | 17 | `define B_GROUP_LESSTHAN 2'd0 18 | `define B_GROUP_COUNTER 2'd1 19 | `define B_GROUP_SENTINEL 2'd2 20 | `define B_GROUP_EXTERNAL 2'd3 21 | 22 | // Second, for the combining stage 23 | 24 | `include "Dyadic_Boolean_Operations.vh" 25 | 26 | `endif 27 | -------------------------------------------------------------------------------- /Octavo/Source/R_Flags.v: -------------------------------------------------------------------------------- 1 | 2 | // Simple flag generator. 3 | // Moved out of Triadic_ALU because word-wide operations like NOR-reduction 4 | // cannot be folded into a 4:1 MUX, as the 6-LUT is already fully used. 5 | // This created a critical path, with no room to pipeline in the ALU. 6 | // Place this in the middle of the R feedback pipeline instead. 7 | 8 | `default_nettype none 9 | 10 | module R_Flags 11 | #( 12 | parameter WORD_WIDTH = 0 13 | ) 14 | ( 15 | input wire [WORD_WIDTH-1:0] R, 16 | output reg R_zero, 17 | output reg R_negative 18 | ); 19 | 20 | initial begin 21 | R_zero = 1'b0; 22 | R_negative = 1'b0; 23 | end 24 | 25 | always @(*) begin 26 | R_zero = ~|R; 27 | R_negative = R[WORD_WIDTH-1]; 28 | end 29 | 30 | endmodule 31 | 32 | -------------------------------------------------------------------------------- /Parts/SimSynth/simulation_clock.v: -------------------------------------------------------------------------------- 1 | 2 | // Clock generator for simulation 3 | 4 | // The following are handy to use with the resulting clock: 5 | 6 | // `define WAIT_CYCLES(n) repeat (n) begin @(posedge clock); end 7 | 8 | // time cycle = 0; 9 | // `define UNTIL_CYCLE(n) wait (cycle == n); 10 | 11 | `default_nettype none 12 | 13 | `timescale 1 ns / 1 ps 14 | 15 | module simulation_clock 16 | #( 17 | parameter CLOCK_PERIOD = 0 18 | ) 19 | ( 20 | output reg clock 21 | ); 22 | 23 | localparam HALF_PERIOD = CLOCK_PERIOD / 2; 24 | 25 | // NOTE: clock is deliberately left uninitialized, and thus X in most 26 | // simulators, and will not trigger a (X -> 0) edge until after the 27 | // simulated clock half-period delay. 28 | 29 | always begin 30 | #HALF_PERIOD clock = (clock === 1'b0); 31 | end 32 | 33 | endmodule 34 | 35 | -------------------------------------------------------------------------------- /Octavo/Source/Split_Extractor.v: -------------------------------------------------------------------------------- 1 | 2 | // Extracts the "split" bit from the ALU control bits. The split bit changes 3 | // the write addressing mode, using the D operand as two separate halves. This 4 | // affects multiple modules later on. 5 | 6 | // FIXME This is a hack, but no clean solution presents itself. See 7 | // Triadic_ALU_Operations.vh and Triadic_ALU_Forward_Path.v for control bits 8 | // ordering. 9 | 10 | // For now, the split bit is the MSB. 11 | 12 | `default_nettype none 13 | 14 | module Split_Extractor 15 | #( 16 | parameter WORD_WIDTH = 0 17 | ) 18 | ( 19 | input wire [WORD_WIDTH-1:0] control, 20 | output reg split 21 | ); 22 | 23 | initial begin 24 | split = 1'b0; 25 | end 26 | 27 | always @(*) begin 28 | split = control [WORD_WIDTH-1]; 29 | end 30 | 31 | endmodule 32 | 33 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-arrays/run_test_bench: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -x 4 | 5 | TOP=DUT 6 | EXEC=V${TOP} 7 | LOGS=${PWD}/LOG 8 | RUNS=RUN 9 | 10 | # Clean up 11 | rm -rf obj_dir 12 | rm ${LOGS}/* 13 | 14 | # Check the code. A different number of warnings is a flag to check things. 15 | verilator -F verilator_parameters --lint-only -cc ${TOP}.v &> ${LOGS}/LOG.lint 16 | 17 | # Verilate the design and compile design library. Logfile should be empty! 18 | verilator -F verilator_parameters -cc ${TOP}.v --exe test_bench.cpp 2>&1 | tee ${LOGS}/LOG.verilate 19 | 20 | # Compile into a test bench executable 21 | pushd obj_dir 22 | make -j 4 -f ${EXEC}.mk 2>&1 | tee ${LOGS}/LOG.compile 23 | popd 24 | 25 | # Copy executable over, and run it 26 | cp obj_dir/${EXEC} ${RUNS}/ 27 | 28 | pushd ${RUNS} 29 | time ./${EXEC} 2>&1 | tee ${LOGS}/LOG.output 30 | popd 31 | 32 | 33 | -------------------------------------------------------------------------------- /Parts/CDC/posedge_pulse_generator.v: -------------------------------------------------------------------------------- 1 | 2 | // Posedge Pulse Generator 3 | // Convert a rising edge to a pulse. 4 | // No output on falling edge. 5 | 6 | `default_nettype none 7 | 8 | module posedge_pulse_generator 9 | #( 10 | parameter PULSE_LENGTH = 0 11 | ) 12 | ( 13 | input wire clock, 14 | input wire level_in, 15 | output reg pulse_out 16 | ); 17 | 18 | initial begin 19 | pulse_out = 0; 20 | end 21 | 22 | wire level_delayed; 23 | 24 | Delay_Line 25 | #( 26 | .DEPTH (PULSE_LENGTH), 27 | .WIDTH (1) 28 | ) 29 | pulse_length_adjuster 30 | ( 31 | .clock (clock), 32 | .in (level_in), 33 | .out (level_delayed) 34 | ); 35 | 36 | always @(*) begin 37 | pulse_out = (level_in == 1'b1) && (level_delayed == 1'b0); 38 | end 39 | 40 | endmodule 41 | 42 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/array-reverse-3/run_test_bench: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -x 4 | 5 | TOP=DUT 6 | EXEC=V${TOP} 7 | LOGS=${PWD}/LOG 8 | RUNS=RUN 9 | 10 | # Clean up 11 | rm -rf obj_dir 12 | rm ${LOGS}/* 13 | 14 | # Check the code. A different number of warnings is a flag to check things. 15 | verilator -F verilator_parameters --lint-only -cc ${TOP}.v &> ${LOGS}/LOG.lint 16 | 17 | # Verilate the design and compile design library. Logfile should be empty! 18 | verilator -F verilator_parameters -F suppressed_warnings -cc ${TOP}.v --exe test_bench.cpp 2>&1 | tee ${LOGS}/LOG.verilate 19 | 20 | # Compile into a test bench executable 21 | pushd obj_dir 22 | make -j 4 -f ${EXEC}.mk 2>&1 | tee ${LOGS}/LOG.compile 23 | popd 24 | 25 | # Copy executable over, and run it 26 | cp obj_dir/${EXEC} ${RUNS}/ 27 | 28 | pushd ${RUNS} 29 | time ./${EXEC} 2>&1 | tee ${LOGS}/LOG.output 30 | popd 31 | 32 | 33 | -------------------------------------------------------------------------------- /Parts/NoC/skid_buffer_example.v: -------------------------------------------------------------------------------- 1 | 2 | module skid_buffer_example 3 | #( 4 | parameter WORD_WIDTH = 36 5 | ) 6 | ( 7 | input wire clock, 8 | 9 | input wire s_valid, 10 | output wire s_ready, 11 | input wire [WORD_WIDTH-1:0] s_data, 12 | 13 | output wire m_valid, 14 | input wire m_ready, 15 | output wire [WORD_WIDTH-1:0] m_data 16 | ); 17 | 18 | skid_buffer 19 | #( 20 | .WORD_WIDTH (WORD_WIDTH) 21 | ) 22 | example 23 | ( 24 | .clock (clock), 25 | 26 | .s_valid (s_valid), 27 | .s_ready (s_ready), 28 | .s_data (s_data), 29 | 30 | .m_valid (m_valid), 31 | .m_ready (m_ready), 32 | .m_data (m_data) 33 | ); 34 | 35 | endmodule 36 | 37 | -------------------------------------------------------------------------------- /Parts/TestHarness/harness_output_register.v: -------------------------------------------------------------------------------- 1 | 2 | // Reduces a word-wide register into a single bit. This prevents 3 | // optimizations, and allows testing without running out of pins. 4 | 5 | `default_nettype none 6 | 7 | module harness_output_register 8 | #( 9 | parameter integer WIDTH = 0 10 | ) 11 | ( 12 | input wire clock, 13 | input wire [WIDTH-1:0] in, 14 | input wire wren, 15 | output reg out 16 | ); 17 | 18 | // -------------------------------------------------------------------- 19 | 20 | localparam ZERO = {WIDTH{1'b0}}; 21 | 22 | reg [WIDTH-1:0] out_reg = ZERO; 23 | 24 | always @(posedge clock) begin 25 | out_reg <= (wren == 1'b1) ? in : out_reg; 26 | end 27 | 28 | always @(*) begin 29 | out = &out_reg; 30 | end 31 | 32 | endmodule 33 | 34 | -------------------------------------------------------------------------------- /Parts/Multithreading/Thread_Number_Example.v: -------------------------------------------------------------------------------- 1 | 2 | `default_nettype none 3 | 4 | module Thread_Number_Example 5 | #( 6 | parameter INITIAL_THREAD = 5, 7 | parameter THREAD_COUNT = 8, 8 | parameter THREAD_COUNT_WIDTH = 3 // clog2(THREAD_COUNT) 9 | ) 10 | ( 11 | input wire clock, 12 | output wire [THREAD_COUNT_WIDTH-1:0] current_thread, 13 | output wire [THREAD_COUNT_WIDTH-1:0] next_thread 14 | ); 15 | 16 | Thread_Number 17 | #( 18 | .INITIAL_THREAD (INITIAL_THREAD), 19 | .THREAD_COUNT (THREAD_COUNT), 20 | .THREAD_COUNT_WIDTH (THREAD_COUNT_WIDTH) 21 | ) 22 | Example 23 | ( 24 | .clock (clock), 25 | .current_thread (current_thread), 26 | .next_thread (next_thread) 27 | ); 28 | 29 | endmodule 30 | 31 | -------------------------------------------------------------------------------- /Tests/Word_OR_Reducer/test_bench/run_test_bench: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | INSTALL_BASE="/home/laforest/Octavo/Octavo" 4 | 5 | TOP_LEVEL_MODULE="Word_OR_Reducer_test_bench" 6 | TESTBENCH="./${TOP_LEVEL_MODULE}.v" 7 | 8 | LPM_LIBRARY="$QUARTUS_BASE/quartus/eda/sim_lib/220model.v" 9 | ALT_LIBRARY="$QUARTUS_BASE/quartus/eda/sim_lib/altera_mf.v" 10 | 11 | SIM_DEFS="$INSTALL_BASE/Parts/SimSynth/simulation_defines.vh" 12 | 13 | SOURCES="$INSTALL_BASE/Parts/Misc/Word_OR_Reducer.v" 14 | 15 | VLIB="work" 16 | 17 | VSIM_ACTIONS="vcd file $TOP_LEVEL_MODULE.vcd ; vcd add -r /* ; run -all ; quit" 18 | 19 | rm $TOP_LEVEL_MODULE.wlf $TOP_LEVEL_MODULE.vcd 20 | vlib $VLIB 2>&1 > LOG 21 | vlog -mfcu -incr -lint $LPM_LIBRARY $ALT_LIBRARY $SOURCES $SIM_DEFS $TESTBENCH 2>&1 >> LOG 22 | vsim -voptargs="+acc" -c -do "$VSIM_ACTIONS" $TOP_LEVEL_MODULE 2>&1 >> LOG 23 | vcd2wlf $TOP_LEVEL_MODULE.vcd $TOP_LEVEL_MODULE.wlf 2>&1 >> LOG 24 | rm vsim.wlf 25 | 26 | -------------------------------------------------------------------------------- /Octavo/Assembler/Utility.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python3 2 | 3 | from bitstring import BitArray 4 | 5 | 6 | class Utility: 7 | """Common utility functions for all other classes.""" 8 | 9 | def __init__ (self): 10 | pass 11 | 12 | def try_int (self, value): 13 | """Wrapper around int() to deal with non-numeric strings and provide debug info.""" 14 | if value is None: 15 | return None 16 | if type(value) == int: 17 | return value 18 | if type(value) == BitArray: 19 | return value 20 | try: 21 | value = int(value, 0) 22 | except ValueError: 23 | # Assume it's a label string. Leave it alone and pass it back out for later resolution. 24 | pass 25 | except TypeError: 26 | print("\nInvalid type for int() conversion. Input {0} of type {1}.\n".format(value, type(value))) 27 | raise TypeError 28 | return value 29 | 30 | -------------------------------------------------------------------------------- /Octavo/Source/IO_All_Ready.v: -------------------------------------------------------------------------------- 1 | 2 | // Simply ANDs all the masked Empty/Full bits, producing the global signal 3 | // that all I/O ports addressed by an instruction are ready. 4 | 5 | // EF bits from write ports must be inverted first, since EMPTY (0) is their 6 | // ready state. 7 | 8 | `default_nettype none 9 | 10 | module IO_All_Ready 11 | #( 12 | parameter READ_PORT_COUNT = 0, 13 | parameter WRITE_PORT_COUNT = 0 14 | ) 15 | ( 16 | input wire [READ_PORT_COUNT-1:0] read_EF, 17 | input wire [WRITE_PORT_COUNT-1:0] write_EF, 18 | output reg IO_ready 19 | ); 20 | 21 | initial begin 22 | IO_ready = 0; 23 | end 24 | 25 | reg read_ready = 0; 26 | reg write_ready = 0; 27 | 28 | always @(*) begin 29 | read_ready = &read_EF; 30 | write_ready = &(~write_EF); 31 | IO_ready = read_ready & write_ready; 32 | end 33 | 34 | endmodule 35 | 36 | -------------------------------------------------------------------------------- /Octavo/Tests/Accelerators/Sliding_Window/run_test_bench: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | INSTALL_BASE="/home/laforest/Octavo/Octavo" 4 | 5 | TOP_LEVEL_MODULE="Sliding_Window_test_bench" 6 | TESTBENCH="./${TOP_LEVEL_MODULE}.v" 7 | 8 | LPM_LIBRARY="$QUARTUS_BASE/linux/quartus/eda/sim_lib/220model.v" 9 | ALT_LIBRARY="$QUARTUS_BASE/linux/quartus/eda/sim_lib/altera_mf.v" 10 | 11 | OCTAVO="$INSTALL_BASE/Octavo/Misc/params.v \ 12 | ./Sliding_Window.v \ 13 | " 14 | 15 | #VLIB="work" 16 | 17 | #VSIM_ACTIONS="vcd file $TOP_LEVEL_MODULE.vcd ; vcd add -r /* ; run -all ; quit" 18 | 19 | #rm $TOP_LEVEL_MODULE.wlf $TOP_LEVEL_MODULE.vcd 20 | #vlib $VLIB 2>&1 > LOG 21 | #vlog -mfcu -incr -lint $LPM_LIBRARY $ALT_LIBRARY $OCTAVO $TESTBENCH 2>&1 >> LOG 22 | #vsim -voptargs="+acc" -c -do "$VSIM_ACTIONS" $TOP_LEVEL_MODULE 2>&1 >> LOG 23 | #vcd2wlf $TOP_LEVEL_MODULE.vcd $TOP_LEVEL_MODULE.wlf 2>&1 >> LOG 24 | #rm vsim.wlf 25 | 26 | iverilog -o foo $OCTAVO $TESTBENCH 2>&1 >> LOG 27 | vvp foo 28 | 29 | -------------------------------------------------------------------------------- /Tests/skid_buffer/DUT.v: -------------------------------------------------------------------------------- 1 | 2 | `default_nettype none 3 | 4 | module DUT 5 | #( 6 | parameter WORD_WIDTH = 64 7 | ) 8 | ( 9 | input wire clock, 10 | 11 | // Slave interface 12 | input wire s_valid, 13 | output wire s_ready, 14 | input wire [WORD_WIDTH-1:0] s_data, 15 | 16 | // Master interface 17 | output wire m_valid, 18 | input wire m_ready, 19 | output wire [WORD_WIDTH-1:0] m_data 20 | ); 21 | 22 | skid_buffer 23 | #( 24 | .WORD_WIDTH (WORD_WIDTH) 25 | ) 26 | skid_buffer 27 | ( 28 | .clock (clock), 29 | 30 | .s_valid (s_valid), 31 | .s_ready (s_ready), 32 | .s_data (s_data), 33 | 34 | .m_valid (m_valid), 35 | .m_ready (m_ready), 36 | .m_data (m_data) 37 | ); 38 | 39 | endmodule 40 | 41 | -------------------------------------------------------------------------------- /Parts/TestHarness/harness_input_register.v: -------------------------------------------------------------------------------- 1 | 2 | // Expands a single input bit into a word, so that no hardware gets optimized 3 | // away during synthesis. Allows testing without running out of pins. 4 | 5 | `default_nettype none 6 | 7 | module harness_input_register 8 | #( 9 | parameter integer WIDTH = 0 10 | ) 11 | ( 12 | input wire clock, 13 | input wire in, 14 | input wire rden, 15 | output reg [WIDTH-1:0] out 16 | ); 17 | 18 | // -------------------------------------------------------------------- 19 | 20 | localparam ZERO = {WIDTH{1'b0}}; 21 | localparam SHORT_ZERO = {WIDTH-1{1'b0}}; 22 | 23 | reg [WIDTH-1:0] in_extended = ZERO; 24 | 25 | always @(*) begin 26 | in_extended = {SHORT_ZERO, in}; 27 | end 28 | 29 | always @(posedge clock) begin 30 | out <= (rden == 1'b1) ? (out << 1 | in_extended) : out; 31 | end 32 | endmodule 33 | 34 | -------------------------------------------------------------------------------- /Octavo/Tests/Accelerators/Array_Reverse_IO/run_test_bench: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | INSTALL_BASE="/home/laforest/Octavo/Octavo" 4 | 5 | NAME="Array_Reverse_IO" 6 | TOP_LEVEL_MODULE="${NAME}_test_bench" 7 | TESTBENCH="./${TOP_LEVEL_MODULE}.v" 8 | 9 | LPM_LIBRARY="$QUARTUS_BASE/linux/quartus/eda/sim_lib/220model.v" 10 | ALT_LIBRARY="$QUARTUS_BASE/linux/quartus/eda/sim_lib/altera_mf.v" 11 | 12 | OCTAVO="${INSTALL_BASE}/Octavo/Misc/params.v \ 13 | ./${NAME}.v \ 14 | " 15 | 16 | VLIB="work" 17 | 18 | VSIM_ACTIONS="vcd file $TOP_LEVEL_MODULE.vcd ; vcd add -r /* ; run -all ; quit" 19 | 20 | rm $TOP_LEVEL_MODULE.wlf $TOP_LEVEL_MODULE.vcd 21 | vlib $VLIB 2>&1 > LOG 22 | vlog -mfcu -incr -lint $LPM_LIBRARY $ALT_LIBRARY $OCTAVO $TESTBENCH 2>&1 >> LOG 23 | vsim -voptargs="+acc" -c -do "$VSIM_ACTIONS" $TOP_LEVEL_MODULE 2>&1 >> LOG 24 | vcd2wlf $TOP_LEVEL_MODULE.vcd $TOP_LEVEL_MODULE.wlf 2>&1 >> LOG 25 | rm vsim.wlf 26 | 27 | # Fails cryptically on Altera libraries 28 | #iverilog -o foo $OCTAVO $TESTBENCH 2>&1 >> LOG 29 | #vvp foo 30 | 31 | -------------------------------------------------------------------------------- /Parts/Address_Decode/Binary_to_N_Decoder.v: -------------------------------------------------------------------------------- 1 | 2 | // Generates a bit vector of up to 2^N bits with one bit set representing the 3 | // binary value fed to it. 4 | 5 | // The output vector width may be more or less than all possible binary values. 6 | // If the binary value does not map to any of the output bits, the vector 7 | // stays at zero. 8 | 9 | // This may fail for binary words of more than 32 bits. 10 | 11 | `default_nettype none 12 | 13 | module Binary_to_N_Decoder 14 | #( 15 | parameter BINARY_WIDTH = 0, 16 | parameter OUTPUT_WIDTH = 0 17 | ) 18 | ( 19 | input wire [BINARY_WIDTH-1:0] in, 20 | output reg [OUTPUT_WIDTH-1:0] out 21 | ); 22 | 23 | initial begin 24 | out = {OUTPUT_WIDTH{1'b0}}; 25 | end 26 | 27 | integer count; 28 | 29 | always @(*) begin 30 | for(count = 0; count < OUTPUT_WIDTH; count = count + 1) begin 31 | out[count +: 1] = (count[BINARY_WIDTH-1:0] == in); 32 | end 33 | end 34 | 35 | endmodule 36 | 37 | -------------------------------------------------------------------------------- /Parts/Multiplexers/Bitwise_2to1_Mux.v: -------------------------------------------------------------------------------- 1 | 2 | // Selects each bit from two sources, based on a mask of same size. 3 | 4 | `default_nettype none 5 | 6 | module Bitwise_2to1_Mux 7 | #( 8 | parameter WORD_WIDTH = 0 9 | ) 10 | ( 11 | input wire [WORD_WIDTH-1:0] select_mask, 12 | input wire [WORD_WIDTH-1:0] in1, 13 | input wire [WORD_WIDTH-1:0] in2, 14 | output wire [WORD_WIDTH-1:0] out 15 | ); 16 | 17 | // One mux per bit pair 18 | 19 | generate 20 | genvar j; 21 | for(j = 0; j < WORD_WIDTH; j = j+1) begin: per_bit 22 | Addressed_Mux 23 | #( 24 | .WORD_WIDTH (1), 25 | .ADDR_WIDTH (1), 26 | .INPUT_COUNT (2) 27 | ) 28 | Mux 29 | ( 30 | .addr (select_mask[j]), 31 | .in ({in2[j],in1[j]}), 32 | .out (out[j]) 33 | ); 34 | end 35 | endgenerate 36 | 37 | endmodule 38 | 39 | -------------------------------------------------------------------------------- /Octavo/Tests/Accelerators/Add_Reducer/run_test_bench: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | INSTALL_BASE="/home/laforest/Octavo/Octavo" 4 | 5 | TOP_LEVEL_MODULE="Add_Reducer_test_bench" 6 | TESTBENCH="./${TOP_LEVEL_MODULE}.v" 7 | 8 | LPM_LIBRARY="$QUARTUS_BASE/linux/quartus/eda/sim_lib/220model.v" 9 | ALT_LIBRARY="$QUARTUS_BASE/linux/quartus/eda/sim_lib/altera_mf.v" 10 | 11 | OCTAVO="$INSTALL_BASE/Octavo/Misc/params.v \ 12 | $INSTALL_BASE/Octavo/Misc/delay_line.v \ 13 | $INSTALL_BASE/Octavo/DataPath/ALU/AddSub_Ripple_Carry.v \ 14 | ./Add_Reducer.v \ 15 | " 16 | 17 | #VLIB="work" 18 | 19 | #VSIM_ACTIONS="vcd file $TOP_LEVEL_MODULE.vcd ; vcd add -r /* ; run -all ; quit" 20 | 21 | #rm $TOP_LEVEL_MODULE.wlf $TOP_LEVEL_MODULE.vcd 22 | #vlib $VLIB 2>&1 > LOG 23 | #vlog -mfcu -incr -lint $LPM_LIBRARY $ALT_LIBRARY $OCTAVO $TESTBENCH 2>&1 >> LOG 24 | #vsim -voptargs="+acc" -c -do "$VSIM_ACTIONS" $TOP_LEVEL_MODULE 2>&1 >> LOG 25 | #vcd2wlf $TOP_LEVEL_MODULE.vcd $TOP_LEVEL_MODULE.wlf 2>&1 >> LOG 26 | #rm vsim.wlf 27 | 28 | iverilog -o foo $OCTAVO $TESTBENCH 2>&1 >> LOG 29 | vvp foo 30 | 31 | -------------------------------------------------------------------------------- /Tests/Dyadic_Boolean_Operator/test_bench/run_test_bench: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | INSTALL_BASE="/home/laforest/Octavo/Octavo" 4 | 5 | TOP_LEVEL_MODULE="Dyadic_Boolean_Operator_test_bench" 6 | TESTBENCH="./${TOP_LEVEL_MODULE}.v" 7 | 8 | LPM_LIBRARY="$QUARTUS_BASE/quartus/eda/sim_lib/220model.v" 9 | ALT_LIBRARY="$QUARTUS_BASE/quartus/eda/sim_lib/altera_mf.v" 10 | 11 | SIM_DEFS="$INSTALL_BASE/Parts/SimSynth/simulation_defines.vh" 12 | 13 | SOURCES="$INSTALL_BASE/Parts/Multiplexers/Addressed_Mux.v \ 14 | $INSTALL_BASE/Parts/ALU/Dyadic_Boolean_Operations.vh \ 15 | $INSTALL_BASE/Parts/ALU/Dyadic_Boolean_Operator.v 16 | " 17 | 18 | VLIB="work" 19 | 20 | VSIM_ACTIONS="vcd file $TOP_LEVEL_MODULE.vcd ; vcd add -r /* ; run -all ; quit" 21 | 22 | rm $TOP_LEVEL_MODULE.wlf $TOP_LEVEL_MODULE.vcd 23 | vlib $VLIB 2>&1 > LOG 24 | vlog -mfcu -incr -lint $LPM_LIBRARY $ALT_LIBRARY $SOURCES $SIM_DEFS $TESTBENCH 2>&1 >> LOG 25 | vsim -voptargs="+acc" -c -do "$VSIM_ACTIONS" $TOP_LEVEL_MODULE 2>&1 >> LOG 26 | vcd2wlf $TOP_LEVEL_MODULE.vcd $TOP_LEVEL_MODULE.wlf 2>&1 >> LOG 27 | rm vsim.wlf 28 | 29 | -------------------------------------------------------------------------------- /Parts/ALU/Dyadic_Boolean_Operations.vh: -------------------------------------------------------------------------------- 1 | 2 | // See Dyadic_Boolean_Operator.v 3 | 4 | `ifndef DYADIC_OPERATIONS 5 | `define DYADIC_OPERATIONS 6 | 7 | // Number of bits to define dyadic operations, never changes. 8 | `define DYADIC_CTRL_WIDTH 4 9 | `define DYADIC_CTRL_ADDR_WIDTH 2 10 | 11 | // These assume A op B, where A is the MSB into the dyadic operator. 12 | 13 | `define DYADIC_ALWAYS_ZERO 4'b0000 14 | `define DYADIC_A_AND_B 4'b1000 15 | `define DYADIC_A_AND_NOT_B 4'b0100 16 | `define DYADIC_A 4'b1100 17 | `define DYADIC_NOT_A_AND_B 4'b0010 18 | `define DYADIC_B 4'b1010 19 | `define DYADIC_A_XOR_B 4'b0110 20 | `define DYADIC_A_OR_B 4'b1110 21 | `define DYADIC_A_NOR_B 4'b0001 22 | `define DYADIC_A_XNOR_B 4'b1001 23 | `define DYADIC_NOT_B 4'b0101 24 | `define DYADIC_A_OR_NOT_B 4'b1101 25 | `define DYADIC_NOT_A 4'b0011 26 | `define DYADIC_NOT_A_OR_B 4'b1011 27 | `define DYADIC_A_NAND_B 4'b0111 28 | `define DYADIC_ALWAYS_ONE 4'b1111 29 | 30 | `endif 31 | 32 | -------------------------------------------------------------------------------- /Parts/Multiplexers/Translated_Addressed_Mux_Example.v: -------------------------------------------------------------------------------- 1 | 2 | `default_nettype none 3 | 4 | module Translated_Addressed_Mux_Example 5 | #( 6 | parameter WORD_WIDTH = 36, 7 | parameter ADDR_WIDTH = 11, 8 | parameter INPUT_COUNT = 8, 9 | parameter INPUT_BASE_ADDR = 123, 10 | parameter INPUT_ADDR_WIDTH = 3, // clog2(INPUT_COUNT) 11 | 12 | parameter TOTAL_WIDTH = INPUT_COUNT * WORD_WIDTH 13 | ) 14 | ( 15 | input wire [ADDR_WIDTH-1:0] addr, 16 | input wire [TOTAL_WIDTH-1:0] in, 17 | output wire [WORD_WIDTH-1:0] out 18 | ); 19 | 20 | Translated_Addressed_Mux 21 | #( 22 | .WORD_WIDTH (WORD_WIDTH), 23 | .ADDR_WIDTH (ADDR_WIDTH), 24 | .INPUT_COUNT (INPUT_COUNT), 25 | .INPUT_BASE_ADDR (INPUT_BASE_ADDR), 26 | .INPUT_ADDR_WIDTH (INPUT_ADDR_WIDTH) 27 | ) 28 | Example 29 | ( 30 | .addr (addr), 31 | .in (in), 32 | .out (out) 33 | ); 34 | 35 | endmodule 36 | 37 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-s/run_test_bench: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -x -e 4 | 5 | TOP=DUT 6 | EXEC=V${TOP} 7 | LOGS=${PWD}/LOG 8 | RUNS=RUN 9 | 10 | # Where is this repo located (absolute path) 11 | GIT_ROOT=$(git rev-parse --show-toplevel) 12 | 13 | # Find all directories and prepend "-y" to each 14 | SEARCH_DIRS=$(find ${GIT_ROOT}/Parts -type d -exec echo "-y" {} \;) 15 | 16 | # Clean up 17 | rm -rf obj_dir 18 | rm ${LOGS}/* 19 | 20 | # Check the code. A different number of warnings is a flag to check things. 21 | verilator -Wall +1364-2001ext+v ${SEARCH_DIRS} --lint-only -cc ${TOP}.v &> ${LOGS}/LOG.lint 22 | 23 | # Verilate the design and compile design library. Logfile should be empty! 24 | verilator -trace -Wall +1364-2001ext+v ${SEARCH_DIRS} -cc ${TOP}.v --exe test_bench.cpp 2>&1 | tee ${LOGS}/LOG.verilate 25 | 26 | # Compile into a test bench executable 27 | pushd obj_dir 28 | make -j 4 -f ${EXEC}.mk 2>&1 | tee ${LOGS}/LOG.compile 29 | popd 30 | 31 | # Copy executable over, and run it 32 | cp obj_dir/${EXEC} ${RUNS}/ 33 | 34 | pushd ${RUNS} 35 | time ./${EXEC} 2>&1 | tee ${LOGS}/LOG.output 36 | popd 37 | 38 | 39 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/array-reverse-3/verilator_parameters: -------------------------------------------------------------------------------- 1 | 2 | // Global options to Verilator. 3 | // Leave -Wall in to have new warnings show up. 4 | // Place ignored warnings in suppresed_warnings 5 | 6 | -trace 7 | -Wall 8 | --default-language 1364-2001 9 | -y /home/laforest/Octavo/Octavo/Parts/Accelerators 10 | -y /home/laforest/Octavo/Octavo/Parts/Address_Decode 11 | -y /home/laforest/Octavo/Octavo/Parts/Addressing 12 | -y /home/laforest/Octavo/Octavo/Parts/ALU 13 | -y /home/laforest/Octavo/Octavo/Parts/Arbiters 14 | -y /home/laforest/Octavo/Octavo/Parts/Branching 15 | -y /home/laforest/Octavo/Octavo/Parts/Controlpath 16 | -y /home/laforest/Octavo/Octavo/Parts/Counters 17 | -y /home/laforest/Octavo/Octavo/Parts/Datapath 18 | -y /home/laforest/Octavo/Octavo/Parts/IO_Predication 19 | -y /home/laforest/Octavo/Octavo/Parts/Misc 20 | -y /home/laforest/Octavo/Octavo/Parts/Memory 21 | -y /home/laforest/Octavo/Octavo/Parts/Multiplexers 22 | -y /home/laforest/Octavo/Octavo/Parts/Multithreading 23 | -y /home/laforest/Octavo/Octavo/Parts/Octavo 24 | -y /home/laforest/Octavo/Octavo/Parts/SimSynth 25 | -y /home/laforest/Octavo/Octavo/Parts/TestHarness 26 | 27 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-arrays/verilator_parameters: -------------------------------------------------------------------------------- 1 | 2 | // Global options to Verilator. 3 | // Leave -Wall in to have new warnings show up. 4 | // Place ignored warnings in suppresed_warnings 5 | 6 | -trace 7 | -Wall 8 | --default-language 1364-2001 9 | -y /home/laforest/Octavo/Octavo/Parts/Accelerators 10 | -y /home/laforest/Octavo/Octavo/Parts/Address_Decode 11 | -y /home/laforest/Octavo/Octavo/Parts/Addressing 12 | -y /home/laforest/Octavo/Octavo/Parts/ALU 13 | -y /home/laforest/Octavo/Octavo/Parts/Arbiters 14 | -y /home/laforest/Octavo/Octavo/Parts/Branching 15 | -y /home/laforest/Octavo/Octavo/Parts/Controlpath 16 | -y /home/laforest/Octavo/Octavo/Parts/Counters 17 | -y /home/laforest/Octavo/Octavo/Parts/Datapath 18 | -y /home/laforest/Octavo/Octavo/Parts/IO_Predication 19 | -y /home/laforest/Octavo/Octavo/Parts/Misc 20 | -y /home/laforest/Octavo/Octavo/Parts/Memory 21 | -y /home/laforest/Octavo/Octavo/Parts/Multiplexers 22 | -y /home/laforest/Octavo/Octavo/Parts/Multithreading 23 | -y /home/laforest/Octavo/Octavo/Parts/Octavo 24 | -y /home/laforest/Octavo/Octavo/Parts/SimSynth 25 | -y /home/laforest/Octavo/Octavo/Parts/TestHarness 26 | 27 | -------------------------------------------------------------------------------- /Octavo/Tests/Accelerators/Accumulator/run_test_bench: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | INSTALL_BASE="/home/laforest/Octavo/Octavo" 4 | 5 | TOP_LEVEL_MODULE="Accumulator_test_bench" 6 | TESTBENCH="./${TOP_LEVEL_MODULE}.v" 7 | 8 | LPM_LIBRARY="$QUARTUS_BASE/linux/quartus/eda/sim_lib/220model.v" 9 | ALT_LIBRARY="$QUARTUS_BASE/linux/quartus/eda/sim_lib/altera_mf.v" 10 | 11 | OCTAVO="$INSTALL_BASE/Octavo/Misc/params.v \ 12 | $INSTALL_BASE/Octavo/Misc/delay_line.v \ 13 | $INSTALL_BASE/Octavo/Misc/Instruction_Annuller.v \ 14 | $INSTALL_BASE/Octavo/DataPath/ALU/AddSub_Ripple_Carry.v \ 15 | ./Accumulator.v \ 16 | " 17 | 18 | VLIB="work" 19 | 20 | VSIM_ACTIONS="vcd file $TOP_LEVEL_MODULE.vcd ; vcd add -r /* ; run -all ; quit" 21 | 22 | rm $TOP_LEVEL_MODULE.wlf $TOP_LEVEL_MODULE.vcd 23 | vlib $VLIB 2>&1 > LOG 24 | vlog -mfcu -incr -lint $LPM_LIBRARY $ALT_LIBRARY $OCTAVO $TESTBENCH 2>&1 >> LOG 25 | vsim -voptargs="+acc" -c -do "$VSIM_ACTIONS" $TOP_LEVEL_MODULE 2>&1 >> LOG 26 | vcd2wlf $TOP_LEVEL_MODULE.vcd $TOP_LEVEL_MODULE.wlf 2>&1 >> LOG 27 | rm vsim.wlf 28 | 29 | # Fails cryptically 30 | #iverilog -o foo $OCTAVO $TESTBENCH 2>&1 >> LOG 31 | #vvp foo 32 | 33 | -------------------------------------------------------------------------------- /Parts/Counters/UpDown_Counter_Example.v: -------------------------------------------------------------------------------- 1 | 2 | `default_nettype none 3 | 4 | module UpDown_Counter_Example 5 | #( 6 | parameter WORD_WIDTH = 36, 7 | parameter INITIAL_COUNT = 55 8 | ) 9 | ( 10 | input wire clock, 11 | input wire up_down, // 1/0 up/down 12 | input wire run, // counts one step if set 13 | input wire wren, // Write overrules count 14 | input wire [WORD_WIDTH-1:0] write_data, 15 | output wire [WORD_WIDTH-1:0] count, 16 | output wire [WORD_WIDTH-1:0] next_count // sometimes handy 17 | ); 18 | 19 | UpDown_Counter 20 | #( 21 | .WORD_WIDTH (WORD_WIDTH), 22 | .INITIAL_COUNT (INITIAL_COUNT) 23 | ) 24 | Example 25 | ( 26 | .clock (clock), 27 | .up_down (up_down), 28 | .run (run), 29 | .wren (wren), 30 | .write_data (write_data), 31 | .count (count), 32 | .next_count (next_count) 33 | ); 34 | 35 | endmodule 36 | 37 | -------------------------------------------------------------------------------- /Parts/Misc/Register_Array.v: -------------------------------------------------------------------------------- 1 | 2 | // An array of registers, 3 | // each with a new data input, 4 | // each with an enable bit to update its output, 5 | // else they stay constant. 6 | 7 | // This is the way it is because you cannot pass multi-dimensional 8 | // arrays through ports in Verilog-2001. 9 | 10 | `default_nettype none 11 | 12 | module Register_Array 13 | #( 14 | parameter COUNT = 0, 15 | parameter WIDTH = 0, 16 | 17 | // Not for instantiation 18 | parameter TOTAL_WIDTH = COUNT * WIDTH 19 | ) 20 | ( 21 | input wire clock, 22 | input wire [COUNT-1:0] wren, 23 | input wire [TOTAL_WIDTH-1:0] in, 24 | output reg [TOTAL_WIDTH-1:0] out 25 | ); 26 | 27 | // -------------------------------------------------------------------------- 28 | 29 | initial begin 30 | out = {TOTAL_WIDTH{1'b0}}; 31 | end 32 | 33 | integer i; 34 | 35 | always @(posedge clock) begin 36 | for(i = 0; i < COUNT; i = i+1) begin 37 | out[(i*WIDTH) +: WIDTH] <= (wren[i] == 1'b1) ? in[(i*WIDTH) +: WIDTH] : out[(i*WIDTH) +: WIDTH]; 38 | end 39 | end 40 | 41 | endmodule 42 | 43 | -------------------------------------------------------------------------------- /Parts/ALU/Dyadic_Boolean_Operator.v: -------------------------------------------------------------------------------- 1 | 2 | // Based on control input, implements one of the 16 possible two-variable 3 | // (dyadic) Boolean operators, as o = a op b. 4 | 5 | `default_nettype none 6 | 7 | `include "Dyadic_Boolean_Operations.vh" 8 | 9 | module Dyadic_Boolean_Operator 10 | #( 11 | parameter WORD_WIDTH = 0 12 | ) 13 | ( 14 | input wire [`DYADIC_CTRL_WIDTH-1:0] op, 15 | input wire [WORD_WIDTH-1:0] a, 16 | input wire [WORD_WIDTH-1:0] b, 17 | output wire [WORD_WIDTH-1:0] o 18 | ); 19 | 20 | // One mux per bit, where the inputs select the op bits. 21 | 22 | generate 23 | genvar i; 24 | for(i = 0; i < WORD_WIDTH; i = i+1) begin: per_bit 25 | Addressed_Mux 26 | #( 27 | .WORD_WIDTH (1), 28 | .ADDR_WIDTH (`DYADIC_CTRL_ADDR_WIDTH), 29 | .INPUT_COUNT (`DYADIC_CTRL_WIDTH) 30 | ) 31 | Operator 32 | ( 33 | .addr ({a[i],b[i]}), 34 | .in (op), 35 | .out (o[i]) 36 | ); 37 | end 38 | endgenerate 39 | 40 | endmodule 41 | 42 | -------------------------------------------------------------------------------- /Parts/Address_Decode/Address_Range_Decoder_Arithmetic.v: -------------------------------------------------------------------------------- 1 | 2 | // A *universal* address decoder. Works for any address range at any starting point. 3 | 4 | // Checks if the address lies between the base and (higher, inclusive) bound of a range. 5 | 6 | // This version uses arithmetic checks and thus should scale to wide addresses 7 | // without reaching limits in the CAD tool. 8 | 9 | // Making the base and bound constant will optimize the hardware down to plain 10 | // logic. It's not as optimal as the Static version, but OK. 11 | 12 | `default_nettype none 13 | 14 | module Address_Range_Decoder_Arithmetic 15 | #( 16 | parameter ADDR_WIDTH = 0 17 | ) 18 | ( 19 | input wire [ADDR_WIDTH-1:0] base_addr, 20 | input wire [ADDR_WIDTH-1:0] bound_addr, 21 | input wire [ADDR_WIDTH-1:0] addr, 22 | output reg hit 23 | ); 24 | 25 | initial begin 26 | hit = 1'b0; 27 | end 28 | 29 | reg base_or_higher = 1'b0; 30 | reg bound_or_lower = 1'b0; 31 | 32 | always @(*) begin 33 | base_or_higher = (addr >= base_addr); 34 | bound_or_lower = (addr <= bound_addr); 35 | hit = (base_or_higher == 1'b1) && (bound_or_lower == 1'b1); 36 | end 37 | 38 | endmodule 39 | 40 | -------------------------------------------------------------------------------- /Parts/Memory/generate_init_file.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | 3 | # Generate an "empty" memory init file, suitable for $readmemh() 4 | # Default fill pattern is zero, but can be specified 5 | 6 | from sys import argv 7 | 8 | # Lifted from Modelsim's output of $writememh 9 | file_header = """// format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress""" 10 | 11 | def dump_format(width): 12 | """Numbers must be represented as zero-padded whole hex numbers""" 13 | characters = width // 4 14 | remainder = width % 4 15 | characters += min(1, remainder) 16 | format_string = "{:0" + str(characters) + "x}" 17 | return format_string 18 | 19 | def file_dump(width, depth, file_name, fill=0): 20 | """Allows dumping a slice of memory.""" 21 | with open(file_name, 'w') as f: 22 | f.write(file_header + "\n") 23 | format_string = dump_format(width) 24 | for i in xrange(depth): 25 | output = format_string.format(fill) 26 | f.write(output + "\n") 27 | 28 | if __name__ == "__main__": 29 | if len(argv) != 4: 30 | print("3 arguments: width, depth, filename\n") 31 | exit 32 | width = int(argv[1]) 33 | depth = int(argv[2]) 34 | file_name = argv[3] 35 | file_dump(width, depth, file_name) 36 | 37 | -------------------------------------------------------------------------------- /Parts/ALU/AddSub_Ripple_Carry.v: -------------------------------------------------------------------------------- 1 | 2 | // Simple adder/subtractor. 3 | // Computes A+B or A-B 4 | // Should infer to the usual LUT and carry-chain logic. 5 | 6 | `default_nettype none 7 | 8 | module AddSub_Ripple_Carry 9 | #( 10 | parameter WORD_WIDTH = 0 11 | ) 12 | ( 13 | input wire sub_add, // 1/0 -> A-B/A+B 14 | input wire carry_in, 15 | input wire signed [WORD_WIDTH-1:0] A, 16 | input wire signed [WORD_WIDTH-1:0] B, 17 | output reg signed [WORD_WIDTH-1:0] sum, 18 | output reg carry_out 19 | ); 20 | 21 | // -------------------------------------------------------------------------- 22 | 23 | localparam ZERO = {WORD_WIDTH{1'b0}}; 24 | 25 | initial begin 26 | sum = ZERO; 27 | carry_out = 1'b0; 28 | end 29 | 30 | reg [WORD_WIDTH-1:0] carry_in_ext = ZERO; 31 | 32 | always @(*) begin 33 | carry_in_ext = {{WORD_WIDTH-1{1'b0}},carry_in}; 34 | end 35 | 36 | // -------------------------------------------------------------------------- 37 | 38 | always @(*) begin 39 | {carry_out, sum} = (sub_add == 1'b1) ? A - B - carry_in_ext : A + B + carry_in_ext; 40 | end 41 | endmodule 42 | 43 | -------------------------------------------------------------------------------- /Octavo/Tests/Address_Decoders/test_bench/run_test_bench: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | INSTALL_BASE="/home/laforest/Octavo/Octavo" 4 | 5 | TOP_LEVEL_MODULE="Address_Decoders_test_bench" 6 | TESTBENCH="./${TOP_LEVEL_MODULE}.v" 7 | 8 | LPM_LIBRARY="$QUARTUS_BASE/quartus/eda/sim_lib/220model.v" 9 | ALT_LIBRARY="$QUARTUS_BASE/quartus/eda/sim_lib/altera_mf.v" 10 | 11 | SIM_DEFS="$INSTALL_BASE/Parts/SimSynth/simulation_defines.vh" 12 | 13 | SOURCES="$INSTALL_BASE/Parts/ALU/Half_Adder.v \ 14 | $INSTALL_BASE/Parts/ALU/Full_Adder.v \ 15 | $INSTALL_BASE/Parts/Misc/Inverter.v \ 16 | $INSTALL_BASE/Parts/Misc/AddSub_Structural.v \ 17 | $INSTALL_BASE/Parts/Addressing/Address_Decoder_Static.v \ 18 | $INSTALL_BASE/Parts/Addressing/Address_Decoder_Arithmetic.v \ 19 | $INSTALL_BASE/Parts/Addressing/Address_Decoder_Arithmetic_Structural.v 20 | " 21 | 22 | VLIB="work" 23 | 24 | VSIM_ACTIONS="vcd file $TOP_LEVEL_MODULE.vcd ; vcd add -r /* ; run -all ; quit" 25 | 26 | rm $TOP_LEVEL_MODULE.wlf $TOP_LEVEL_MODULE.vcd 27 | vlib $VLIB 2>&1 > LOG 28 | vlog -mfcu -incr -lint $LPM_LIBRARY $ALT_LIBRARY $SOURCES $SIM_DEFS $TESTBENCH 2>&1 >> LOG 29 | vsim -voptargs="+acc" -c -do "$VSIM_ACTIONS" $TOP_LEVEL_MODULE 2>&1 >> LOG 30 | vcd2wlf $TOP_LEVEL_MODULE.vcd $TOP_LEVEL_MODULE.wlf 2>&1 >> LOG 31 | rm vsim.wlf 32 | 33 | -------------------------------------------------------------------------------- /Octavo/Tests/controller_test_bench.v: -------------------------------------------------------------------------------- 1 | `include "params.v" 2 | 3 | module controller_test_bench(); 4 | 5 | reg clock; 6 | reg `WORD A; 7 | reg `OPCODE op; 8 | reg `ADDR D; 9 | wire `ADDR pc; 10 | 11 | initial begin 12 | clock = 0; 13 | A = 0; 14 | op = 0; // XOR 15 | D = 0; 16 | `DELAY_CLOCK_CYCLES(100) $stop; 17 | end 18 | 19 | always begin 20 | `DELAY_CLOCK_HALF_PERIOD clock <= ~clock; 21 | end 22 | 23 | always begin 24 | @(posedge clock); 25 | @(posedge clock); 26 | @(posedge clock); 27 | 28 | A = `WORD_WIDTH'd0; 29 | op = `JMP; 30 | D = `ADDR_WIDTH'd55; 31 | 32 | @(posedge clock); 33 | 34 | A = `WORD_WIDTH'd0; 35 | op = `XOR; 36 | D = `ADDR_WIDTH'd0; 37 | 38 | @(posedge clock); 39 | @(posedge clock); 40 | @(posedge clock); 41 | @(posedge clock); 42 | @(posedge clock); 43 | @(posedge clock); 44 | @(posedge clock); 45 | @(posedge clock); 46 | @(posedge clock); 47 | @(posedge clock); 48 | end 49 | 50 | controller dut ( 51 | .clock(clock), 52 | .A(A), 53 | .op(op), 54 | .D(D), 55 | .pc(pc) 56 | ); 57 | 58 | endmodule 59 | -------------------------------------------------------------------------------- /Tests/Word_OR_Reducer/test_bench/Word_OR_Reducer_test_bench.v: -------------------------------------------------------------------------------- 1 | 2 | module Word_OR_Reducer_test_bench 3 | #( 4 | parameter WORD_WIDTH = 36, 5 | parameter WORD_COUNT = 4 6 | ) 7 | ( 8 | ); 9 | 10 | // -------------------------------------------------------------------- 11 | 12 | integer cycle; 13 | reg clock; 14 | 15 | reg [(WORD_WIDTH*WORD_COUNT)-1:0] dut_in; 16 | wire [WORD_WIDTH-1:0] dut_out; 17 | 18 | initial begin 19 | cycle = 0; 20 | clock = 0; 21 | dut_in = {36'h400000000,36'h200000000,36'h100000000,36'hFFFFFFFFF}; 22 | `DELAY_CLOCK_CYCLES(32) $finish; 23 | end 24 | 25 | always @(*) begin 26 | `DELAY_CLOCK_HALF_PERIOD clock <= ~clock; 27 | end 28 | 29 | always @(posedge clock) begin 30 | cycle <= cycle + 1; 31 | end 32 | 33 | always @(posedge clock) begin 34 | dut_in = dut_in + 'd1; 35 | end 36 | 37 | // -------------------------------------------------------------------- 38 | 39 | Word_OR_Reducer 40 | #( 41 | .WORD_WIDTH (WORD_WIDTH), 42 | .WORD_COUNT (WORD_COUNT) 43 | ) 44 | DUT 45 | ( 46 | .in (dut_in), 47 | .out (dut_out) 48 | ); 49 | 50 | endmodule 51 | 52 | -------------------------------------------------------------------------------- /Octavo/Source/Sentinel_Value_Check.v: -------------------------------------------------------------------------------- 1 | 2 | // Checks if ALL the input bits match the sentinel value, 3 | // with masking to exclude bits from match. 4 | 5 | // Set a mask bit to 1 to exclude a bit from the comparison. 6 | // (by forcing both the input and sentinel bit to zero, thus matching.) 7 | // Thus, an all-one mask will cause a match to always be found. 8 | // And an all-zero mask will cause a comparison to be exact. 9 | // (which will be the default behaviour at start) 10 | 11 | // The sentinel masking logic was pulled up to the enclosing logic 12 | // to allow for retiming. 13 | 14 | `default_nettype none 15 | 16 | module Sentinel_Value_Check 17 | #( 18 | parameter WORD_WIDTH = 0 19 | ) 20 | ( 21 | input wire [WORD_WIDTH-1:0] data_in, 22 | input wire [WORD_WIDTH-1:0] sentinel_masked, 23 | input wire [WORD_WIDTH-1:0] mask, 24 | output reg match 25 | ); 26 | 27 | // -------------------------------------------------------------------------- 28 | 29 | localparam ZERO = {WORD_WIDTH{1'b0}}; 30 | 31 | initial begin 32 | match = 1'b0; 33 | end 34 | 35 | reg [WORD_WIDTH-1:0] data_in_masked = ZERO; 36 | 37 | always @(*) begin 38 | data_in_masked = data_in & ~mask; 39 | match = (data_in_masked == sentinel_masked); 40 | end 41 | 42 | endmodule 43 | 44 | -------------------------------------------------------------------------------- /Octavo/Source/Global_Defines.vh: -------------------------------------------------------------------------------- 1 | 2 | // This file holds values which remain true and constant everywhere. 3 | // Not all such values are here. Most are in module-specific include (.vh) files. 4 | 5 | // -------------------------------------------------------------------- 6 | 7 | // There are always 8 threads in Octavo. Use this number to help sync 8 | // operations along the pipeline to within one thread, such that the previous 9 | // value meets the next operation in the same thread. 10 | 11 | `define OCTAVO_THREAD_COUNT 8 12 | `define OCTAVO_THREAD_COUNT_WIDTH 3 13 | 14 | // Opcodes are always 4 bits. 15 | // The operand field widths may change though. 16 | 17 | `define OPCODE_COUNT 16 18 | `define OPCODE_WIDTH 4 19 | 20 | // The Flow Control module needs to know how much to delay some internal 21 | // signals to sync with the output of the Instruction Memory. 22 | // See Instruction_Memory.v 23 | 24 | `define INSTR_FETCH_PIPE_DEPTH 4 25 | 26 | // How many memory words are used to configure each Branch Module 27 | // See Branch_Module_Mapped.v for details 28 | 29 | `define BRANCH_CONFIG_ENTRIES 6 30 | 31 | // There are 2 Data Memories, A and B, which can each do a read and a write 32 | // each cycle. Thus, there can also be that many I/O ports active at once. 33 | // See Datapath_IO_Predication.v 34 | 35 | `define READ_PORT_COUNT 2 36 | `define WRITE_PORT_COUNT 2 37 | 38 | -------------------------------------------------------------------------------- /Octavo/Source/Instruction_Field_Extractor.v: -------------------------------------------------------------------------------- 1 | 2 | // Extracts each field out of an instruction, 3 | // with any unused bits in the MSB before the opcode. 4 | 5 | // Documents the overall intruction format. 6 | // See Address_Splitter for the split D address format. 7 | 8 | `default_nettype none 9 | 10 | module Instruction_Field_Extractor 11 | #( 12 | parameter WORD_WIDTH = 0, 13 | parameter OPCODE_WIDTH = 0, 14 | parameter D_OPERAND_WIDTH = 0, 15 | parameter A_OPERAND_WIDTH = 0, 16 | parameter B_OPERAND_WIDTH = 0 17 | ) 18 | ( 19 | input wire [WORD_WIDTH-1:0] instruction, 20 | output reg [OPCODE_WIDTH-1:0] opcode, 21 | output reg [D_OPERAND_WIDTH-1:0] D_operand, // Destination 22 | output reg [A_OPERAND_WIDTH-1:0] A_operand, // Source 23 | output reg [B_OPERAND_WIDTH-1:0] B_operand // Source 24 | ); 25 | 26 | initial begin 27 | opcode = 0; 28 | D_operand = 0; 29 | A_operand = 0; 30 | B_operand = 0; 31 | end 32 | 33 | localparam USED_BIT_WIDTH = OPCODE_WIDTH + D_OPERAND_WIDTH + A_OPERAND_WIDTH + B_OPERAND_WIDTH; 34 | 35 | always @(*) begin 36 | {opcode,D_operand,A_operand,B_operand} = instruction [USED_BIT_WIDTH-1:0]; 37 | end 38 | 39 | endmodule 40 | 41 | -------------------------------------------------------------------------------- /Octavo/Tests/Accelerators/Sliding_Window/Sliding_Window.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 1991-2013 Altera Corporation 4 | # Your use of Altera Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Altera Program License 10 | # Subscription Agreement, Altera MegaCore Function License 11 | # Agreement, or other applicable license agreement, including, 12 | # without limitation, that your use is for the sole purpose of 13 | # programming logic devices manufactured by Altera and sold by 14 | # Altera or its authorized distributors. Please refer to the 15 | # applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus II 64-Bit 20 | # Version 13.1.0 Build 162 10/23/2013 SJ Full Version 21 | # Date created = 21:10:27 May 18, 2014 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "13.1" 26 | DATE = "21:10:27 May 18, 2014" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "Sliding_Window" 31 | -------------------------------------------------------------------------------- /Octavo/Tests/Accelerators/Accumulator/Accumulator_test_harness.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 1991-2013 Altera Corporation 4 | # Your use of Altera Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Altera Program License 10 | # Subscription Agreement, Altera MegaCore Function License 11 | # Agreement, or other applicable license agreement, including, 12 | # without limitation, that your use is for the sole purpose of 13 | # programming logic devices manufactured by Altera and sold by 14 | # Altera or its authorized distributors. Please refer to the 15 | # applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus II 64-Bit 20 | # Version 13.1.0 Build 162 10/23/2013 SJ Full Version 21 | # Date created = 17:04:06 May 14, 2014 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "13.1" 26 | DATE = "17:04:06 May 14, 2014" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "Accumulator" 31 | -------------------------------------------------------------------------------- /Octavo/Tests/Accelerators/Add_Reducer/Add_Reducer_test_harness.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 1991-2013 Altera Corporation 4 | # Your use of Altera Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Altera Program License 10 | # Subscription Agreement, Altera MegaCore Function License 11 | # Agreement, or other applicable license agreement, including, 12 | # without limitation, that your use is for the sole purpose of 13 | # programming logic devices manufactured by Altera and sold by 14 | # Altera or its authorized distributors. Please refer to the 15 | # applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus II 64-Bit 20 | # Version 13.1.0 Build 162 10/23/2013 SJ Full Version 21 | # Date created = 17:04:06 May 14, 2014 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "13.1" 26 | DATE = "17:04:06 May 14, 2014" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "Add_Reducer" 31 | -------------------------------------------------------------------------------- /Octavo/Tests/Accelerators/Array_Reverse_IO/Array_Reverse_IO.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 1991-2013 Altera Corporation 4 | # Your use of Altera Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Altera Program License 10 | # Subscription Agreement, Altera MegaCore Function License 11 | # Agreement, or other applicable license agreement, including, 12 | # without limitation, that your use is for the sole purpose of 13 | # programming logic devices manufactured by Altera and sold by 14 | # Altera or its authorized distributors. Please refer to the 15 | # applicable agreement for further details. 16 | # 17 | # -------------------------------------------------------------------------- # 18 | # 19 | # Quartus II 64-Bit 20 | # Version 13.1.0 Build 162 10/23/2013 SJ Full Version 21 | # Date created = 17:04:06 May 14, 2014 22 | # 23 | # -------------------------------------------------------------------------- # 24 | 25 | QUARTUS_VERSION = "13.1" 26 | DATE = "17:04:06 May 14, 2014" 27 | 28 | # Revisions 29 | 30 | PROJECT_REVISION = "Array_Reverse_IO" 31 | -------------------------------------------------------------------------------- /Parts/Multiplexers/One_Hot_Mux.v: -------------------------------------------------------------------------------- 1 | 2 | // One-Hot Multiplexer, where a set selector bit brings out its associated 3 | // word to the output. 4 | 5 | // If more than one selector bit is set, the output is the bitwise OR of the 6 | // associated words. 7 | 8 | `default_nettype none 9 | 10 | module One_Hot_Mux 11 | #( 12 | parameter WORD_WIDTH = 0, 13 | parameter WORD_COUNT = 0, 14 | 15 | // Not for instantiation 16 | parameter TOTAL_WIDTH = WORD_COUNT * WORD_WIDTH 17 | ) 18 | ( 19 | input wire [WORD_COUNT-1:0] selectors, 20 | input wire [TOTAL_WIDTH-1:0] in, 21 | output wire [WORD_WIDTH-1:0] out 22 | ); 23 | 24 | // -------------------------------------------------------------------- 25 | 26 | wire [(WORD_COUNT*WORD_WIDTH)-1:0] selected_in; 27 | 28 | Annuller 29 | #( 30 | .WORD_WIDTH (WORD_WIDTH) 31 | ) 32 | Select_Input [WORD_COUNT-1:0] 33 | ( 34 | .annul (~selectors), 35 | .in (in), 36 | .out (selected_in) 37 | ); 38 | 39 | // -------------------------------------------------------------------- 40 | 41 | Word_OR_Reducer 42 | #( 43 | .WORD_WIDTH (WORD_WIDTH), 44 | .WORD_COUNT (WORD_COUNT) 45 | ) 46 | Merge 47 | ( 48 | .in (selected_in), 49 | .out (out) 50 | ); 51 | 52 | endmodule 53 | -------------------------------------------------------------------------------- /Octavo/Assembler/Debug.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python3 2 | 3 | from pprint import pformat 4 | from sys import exit 5 | 6 | class Debug: 7 | """Common debug code to give useful, clean object dumps. Use in conjunction with PDB.""" 8 | 9 | def __init__ (self): 10 | pass 11 | 12 | def __str__ (self): 13 | """Debug information formatter. Override in sub-classes for more complex structures.""" 14 | return self.__class__.__name__ + " ({0}): ".format(hex(id(self))) + pformat(self.__dict__, width=320, compact=True) 15 | 16 | def list_str (self, items): 17 | """Convert a list to a string. One item per line.""" 18 | output = "" 19 | for entry in items: 20 | output += str(entry) + "\n" 21 | return output 22 | 23 | def ask_for_debugger (self): 24 | input("Press Enter to run debugger, or Ctrl-C to exit.") 25 | import pdb; pdb.set_trace() 26 | 27 | def filedump (self, filename, append = False): 28 | """Dump object __str__ representation to file, with optional append.""" 29 | if append is False: 30 | mode = 'w' 31 | elif append is True: 32 | mode = 'a' 33 | else: 34 | print("debug filedump append flag must be True/False, not {0}".format(append)) 35 | self.ask_for_debugger() 36 | with open(filename, mode) as f: 37 | print(self, end="", file=f) 38 | 39 | -------------------------------------------------------------------------------- /Parts/Arbiters/Thermometer_Mask.v: -------------------------------------------------------------------------------- 1 | 2 | // Takes a bit vector and returns a mask 3 | // which masks-off all bits less significant 4 | // than the least significant set bit. 5 | 6 | // Does allow an all-zero vector as a special case, 7 | // where the mask ends up all-one. 8 | 9 | // Used to mask-off arbiter requests of higher priority 10 | // to the current grant, where the LSB has highest priority. 11 | 12 | // Core logic from Hacker's Delight 13 | 14 | `default_nettype none 15 | 16 | module Thermometer_Mask 17 | #( 18 | parameter WORD_WIDTH = 0 19 | ) 20 | ( 21 | input wire [WORD_WIDTH-1:0] bitvector, 22 | output reg [WORD_WIDTH-1:0] mask 23 | ); 24 | 25 | localparam ZERO = {WORD_WIDTH{1'b0}}; 26 | 27 | initial begin 28 | mask = ZERO; 29 | end 30 | 31 | always @(*) begin 32 | // Outputs 1 at the first set bit and all trailing (less significant) bits. 33 | // Outputs 0 at all more significant bits. 34 | // All 1's if no bit set. 35 | mask = bitvector ^ (bitvector - 1); 36 | // Invert mask to instead mask-off the set bit and the trailing bits 37 | // Don't invert mask if no bit set (don't want an all-zero mask) 38 | mask = (bitvector == ZERO) ? mask : ~mask; 39 | // Re-add set bit, so it and leading (more significant) bits pass through. 40 | mask = mask | bitvector; 41 | end 42 | 43 | endmodule 44 | 45 | -------------------------------------------------------------------------------- /Tests/skid_buffer/skid_buffer.qpf: -------------------------------------------------------------------------------- 1 | # -------------------------------------------------------------------------- # 2 | # 3 | # Copyright (C) 2017 Intel Corporation. All rights reserved. 4 | # Your use of Intel Corporation's design tools, logic functions 5 | # and other software and tools, and its AMPP partner logic 6 | # functions, and any output files from any of the foregoing 7 | # (including device programming or simulation files), and any 8 | # associated documentation or information are expressly subject 9 | # to the terms and conditions of the Intel Program License 10 | # Subscription Agreement, the Intel Quartus Prime License Agreement, 11 | # the Intel MegaCore Function License Agreement, or other 12 | # applicable license agreement, including, without limitation, 13 | # that your use is for the sole purpose of programming logic 14 | # devices manufactured by Intel and sold by Intel or its 15 | # authorized distributors. Please refer to the applicable 16 | # agreement for further details. 17 | # 18 | # -------------------------------------------------------------------------- # 19 | # 20 | # Quartus Prime 21 | # Version 17.0.2 Build 602 07/19/2017 SJ Lite Edition 22 | # Date created = 09:46:21 January 09, 2019 23 | # 24 | # -------------------------------------------------------------------------- # 25 | 26 | QUARTUS_VERSION = "17.0" 27 | DATE = "09:46:21 January 09, 2019" 28 | 29 | # Revisions 30 | 31 | PROJECT_REVISION = "skid_buffer" 32 | -------------------------------------------------------------------------------- /Octavo/Tests/AOM/test_bench/run_test_bench: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | INSTALL_BASE="/home/laforest/Octavo/Octavo" 4 | 5 | TOP_LEVEL_MODULE="Generic_test_bench" 6 | TESTBENCH="./${TOP_LEVEL_MODULE}.v" 7 | 8 | LPM_LIBRARY="$QUARTUS_BASE/quartus/eda/sim_lib/220model.v" 9 | ALT_LIBRARY="$QUARTUS_BASE/quartus/eda/sim_lib/altera_mf.v" 10 | 11 | SIM_DEFS="$INSTALL_BASE/Parts/SimSynth/simulation_defines.vh" 12 | 13 | SOURCES="$INSTALL_BASE/Parts/Counters/UpDown_Counter.v \ 14 | $INSTALL_BASE/Parts/Arbiters/Priority_Arbiter.v \ 15 | $INSTALL_BASE/Parts/Misc/Annuller.v \ 16 | $INSTALL_BASE/Parts/Misc/Word_OR_Reducer.v \ 17 | $INSTALL_BASE/Parts/Multiplexers/One_Hot_Mux.v \ 18 | $INSTALL_BASE/Parts/Memory/RAM_SDP.v \ 19 | $INSTALL_BASE/Parts/Multithreading/Delay_Line.v \ 20 | $INSTALL_BASE/Parts/Multithreading/Thread_Number.v \ 21 | $INSTALL_BASE/Parts/AOM/Address_Offset_Module_PO_Memory.v \ 22 | $INSTALL_BASE/Parts/AOM/Address_Offset_Module.v 23 | " 24 | VLIB="work" 25 | 26 | VSIM_ACTIONS="vcd file $TOP_LEVEL_MODULE.vcd ; vcd add -r /* ; run -all ; quit" 27 | 28 | rm $TOP_LEVEL_MODULE.wlf $TOP_LEVEL_MODULE.vcd 29 | vlib $VLIB 2>&1 > LOG 30 | vlog -mfcu -incr -lint $LPM_LIBRARY $ALT_LIBRARY $SOURCES $SIM_DEFS $TESTBENCH 2>&1 >> LOG 31 | vsim -voptargs="+acc" -c -do "$VSIM_ACTIONS" $TOP_LEVEL_MODULE 2>&1 >> LOG 32 | vcd2wlf $TOP_LEVEL_MODULE.vcd $TOP_LEVEL_MODULE.wlf 2>&1 >> LOG 33 | rm vsim.wlf 34 | 35 | -------------------------------------------------------------------------------- /Parts/Counters/Down_Counter_Zero_Example.v: -------------------------------------------------------------------------------- 1 | 2 | `default_nettype none 3 | 4 | module Down_Counter_Zero_Example 5 | #( 6 | parameter WORD_WIDTH = 36 7 | ) 8 | ( 9 | input wire clock, 10 | input wire run, 11 | input wire load_wren, 12 | input wire [WORD_WIDTH-1:0] load_value, 13 | output wire [WORD_WIDTH-1:0] count_out, 14 | output wire count_zero 15 | ); 16 | 17 | // -------------------------------------------------------------------------- 18 | 19 | localparam ZERO = {WORD_WIDTH{1'b0}}; 20 | 21 | reg [WORD_WIDTH-1:0] count = ZERO; 22 | 23 | // -------------------------------------------------------------------------- 24 | 25 | wire count_out_wren; 26 | 27 | Down_Counter_Zero 28 | #( 29 | .WORD_WIDTH (WORD_WIDTH) 30 | ) 31 | Example 32 | ( 33 | .run (run), 34 | .count_in (count), 35 | .load_wren (load_wren), 36 | .load_value (load_value), 37 | .count_out_wren (count_out_wren), 38 | .count_out (count_out), 39 | .count_zero (count_zero) 40 | ); 41 | 42 | // -------------------------------------------------------------------------- 43 | 44 | always @(posedge clock) begin 45 | count <= (count_out_wren == 1'b1) ? count_out : count; 46 | end 47 | 48 | endmodule 49 | 50 | -------------------------------------------------------------------------------- /Tests/Dyadic_Boolean_Operator/test_bench/Dyadic_Boolean_Operator_test_bench.v: -------------------------------------------------------------------------------- 1 | 2 | module Dyadic_Boolean_Operator_test_bench 3 | #( 4 | parameter WORD_WIDTH = 36 5 | ) 6 | ( 7 | ); 8 | localparam OP_WIDTH = 4; 9 | 10 | integer cycle; 11 | reg clock; 12 | reg [OP_WIDTH-1:0] op; 13 | reg [WORD_WIDTH-1:0] a; 14 | reg [WORD_WIDTH-1:0] b; 15 | wire [WORD_WIDTH-1:0] o; 16 | 17 | initial begin 18 | $dumpfile("Dyadic_Boolean_Operator_test_bench.vcd"); 19 | //$dumpvars(0); 20 | cycle = 0; 21 | clock = 0; 22 | op = 0; 23 | a = 36'h100F0500A; 24 | b = 36'h100F050A0; 25 | `DELAY_CLOCK_CYCLES(32) $finish; 26 | end 27 | 28 | always @(*) begin 29 | `DELAY_CLOCK_HALF_PERIOD clock <= ~clock; 30 | end 31 | 32 | always @(posedge clock) begin 33 | cycle <= cycle + 1; 34 | end 35 | 36 | always @(posedge clock) begin 37 | // Test all 16 ops. Refer to Dyadic_Boolean_Operations.vh for meaning. 38 | op = op + 4'd1; 39 | `DELAY_CLOCK_CYCLES(1); 40 | end 41 | 42 | Dyadic_Boolean_Operator 43 | #( 44 | .WORD_WIDTH (WORD_WIDTH) 45 | ) 46 | DUT 47 | ( 48 | .op (op), 49 | .a (a), 50 | .b (b), 51 | .o (o) 52 | ); 53 | 54 | endmodule 55 | 56 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/common/opcodes.asm: -------------------------------------------------------------------------------- 1 | 2 | # Define opcodes 3 | # split? shift d3 +/- dual? d2 d1 Select 4 | 5 | # This nop is not needed (could add 0 0 0), but it results in an all-zero control word, which might be handy. 6 | nop opcode split_no shift_none always_zero addsub_a_plus_b simple always_zero always_zero select_r # absolute no-op 7 | # Add must always be present. It is used by code generation for branch and pointer initialization loads. 8 | add opcode split_no shift_none b addsub_a_plus_b simple always_zero always_zero select_r # a+b 9 | sub opcode split_no shift_none b addsub_a_minus_b simple always_zero always_zero select_r # a-b 10 | psr opcode split_no shift_none a addsub_a_plus_b simple always_one always_zero select_r # Pass R to ALU outputs 11 | add*2 opcode split_no shift_left b addsub_a_minus_b simple always_zero always_zero select_r # (a+b) << 1 12 | add/2 opcode split_no shift_right_signed b addsub_a_plus_b simple always_zero always_zero select_r # (a+b) >> 1 (sign extends) 13 | add/2u opcode split_no shift_right b addsub_a_plus_b simple always_zero always_zero select_r # (a+b) >> 1 (shifts zero into MSB) 14 | 15 | -------------------------------------------------------------------------------- /Parts/Memory/RAM_SDP_Example.v: -------------------------------------------------------------------------------- 1 | 2 | `default_nettype none 3 | 4 | module RAM_SDP_Example 5 | #( 6 | parameter WORD_WIDTH = 36, 7 | parameter ADDR_WIDTH = 12, 8 | parameter DEPTH = 4096, 9 | parameter RAMSTYLE = "M10K", 10 | parameter READ_NEW_DATA = 0, 11 | parameter USE_INIT_FILE = 0, 12 | parameter INIT_FILE = "" 13 | ) 14 | ( 15 | input wire clock, 16 | input wire wren, 17 | input wire [ADDR_WIDTH-1:0] write_addr, 18 | input wire [WORD_WIDTH-1:0] write_data, 19 | input wire rden, 20 | input wire [ADDR_WIDTH-1:0] read_addr, 21 | output reg [WORD_WIDTH-1:0] read_data 22 | ); 23 | 24 | RAM_SDP 25 | #( 26 | .WORD_WIDTH (WORD_WIDTH), 27 | .ADDR_WIDTH (ADDR_WIDTH), 28 | .DEPTH (DEPTH), 29 | .RAMSTYLE (RAMSTYLE), 30 | .READ_NEW_DATA (READ_NEW_DATA), 31 | .USE_INIT_FILE (USE_INIT_FILE), 32 | .INIT_FILE (INIT_FILE) 33 | ) 34 | Example 35 | ( 36 | .clock (clock), 37 | .wren (wren), 38 | .write_addr (write_addr), 39 | .write_data (write_data), 40 | .rden (rden), 41 | .read_addr (read_addr), 42 | .read_data (read_data) 43 | ); 44 | 45 | endmodule 46 | 47 | -------------------------------------------------------------------------------- /Octavo/Tests/Triadic_ALU/test_bench/run_test_bench: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | INSTALL_BASE="/home/laforest/Octavo/Octavo" 4 | 5 | TOP_LEVEL_MODULE="Triadic_ALU_test_bench" 6 | TESTBENCH="./${TOP_LEVEL_MODULE}.v" 7 | 8 | LPM_LIBRARY="$QUARTUS_BASE/quartus/eda/sim_lib/220model.v" 9 | ALT_LIBRARY="$QUARTUS_BASE/quartus/eda/sim_lib/altera_mf.v" 10 | 11 | SIM_DEFS="$INSTALL_BASE/Parts/SimSynth/simulation_defines.vh" 12 | 13 | SOURCES="$INSTALL_BASE/Parts/Multiplexers/Addressed_Mux.v \ 14 | $INSTALL_BASE/Parts/Multiplexers/Bitwise_2to1_Mux.v \ 15 | $INSTALL_BASE/Parts/Multithreading/Delay_Line.v \ 16 | $INSTALL_BASE/Parts/ALU/Dyadic_Boolean_Operations.vh \ 17 | $INSTALL_BASE/Parts/ALU/Dyadic_Boolean_Operator.v \ 18 | $INSTALL_BASE/Parts/ALU/AddSub_Ripple_Carry_NoCarry.v \ 19 | $INSTALL_BASE/Parts/Misc/Inverter.v \ 20 | $INSTALL_BASE/Parts/ALU/R_Flags.v \ 21 | $INSTALL_BASE/Parts/ALU/Carryin_Calculator.v \ 22 | $INSTALL_BASE/Parts/ALU/Triadic_ALU_Operations.vh \ 23 | $INSTALL_BASE/Parts/ALU/Triadic_ALU.v 24 | " 25 | 26 | VLIB="work" 27 | 28 | VSIM_ACTIONS="vcd file $TOP_LEVEL_MODULE.vcd ; vcd add -r /* ; run -all ; quit" 29 | 30 | rm $TOP_LEVEL_MODULE.wlf $TOP_LEVEL_MODULE.vcd 31 | vlib $VLIB 2>&1 > LOG 32 | vlog -mfcu -incr -lint $LPM_LIBRARY $ALT_LIBRARY $SOURCES $SIM_DEFS $TESTBENCH 2>&1 >> LOG 33 | vsim -voptargs="+acc" -c -do "$VSIM_ACTIONS" $TOP_LEVEL_MODULE 2>&1 >> LOG 34 | vcd2wlf $TOP_LEVEL_MODULE.vcd $TOP_LEVEL_MODULE.wlf 2>&1 >> LOG 35 | rm vsim.wlf 36 | 37 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/array-reverse-3/array-reverse-3.asm: -------------------------------------------------------------------------------- 1 | 2 | # Reverse-3, per thread. 3 | # A -> tmp, B -> A, tmp -> B 4 | 5 | # Common library of definitions 6 | include ../common/opcodes.asm 7 | include ../common/conditions.asm 8 | 9 | # Shared variables 10 | 11 | # N-1 for N loops 12 | array_half_len shared 49 13 | 14 | output port A 0 15 | 16 | # Thread-private variables 17 | 18 | threads 0 1 2 3 4 5 6 7 19 | 20 | array private 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 21 | 22 | top_ptr_rd pointer array 1 0 23 | top_ptr_wr pointer array 1 0 24 | bot_ptr_rd pointer array -1 99 25 | bot_ptr_wr pointer array -1 99 26 | 27 | temp private 0 28 | 29 | # Code 30 | 31 | preload add 32 | 33 | start init next 34 | 35 | loop add output 0 -1 36 | init loop 37 | init top_ptr_rd 38 | init top_ptr_wr 39 | init bot_ptr_rd 40 | init bot_ptr_wr 41 | 42 | next add temp top_ptr_rd 0 43 | add top_ptr_wr bot_ptr_rd 0 44 | add bot_ptr_wr 0 temp 45 | ctz unpredicted array_half_len loop 46 | jmp unpredicted next 47 | 48 | # Set starting point (PC) for each thread 49 | program_counter start start start start start start start start 50 | 51 | -------------------------------------------------------------------------------- /Octavo/Tests/Accelerators/Array_Reverse_IO/Array_Reverse_IO_test_bench.v: -------------------------------------------------------------------------------- 1 | 2 | module Array_Reverse_IO_test_bench 3 | #( 4 | parameter WORD_WIDTH = 36, 5 | parameter LANE_COUNT = 8, 6 | parameter THREAD_COUNT = 8 7 | ) 8 | ( 9 | // This line left intentionally blank. 10 | ); 11 | integer cycle; 12 | reg clock; 13 | reg [(LANE_COUNT * WORD_WIDTH)-1:0] original; 14 | wire [(LANE_COUNT * WORD_WIDTH)-1:0] reversed; 15 | 16 | initial begin 17 | //$dumpfile("Array_Reverse_IO_test_bench.vcd"); 18 | //$dumpvars(); 19 | cycle = 0; 20 | clock = 0; 21 | original = 1; 22 | `DELAY_CLOCK_CYCLES(1000) $finish; 23 | end 24 | 25 | always @(*) begin 26 | `DELAY_CLOCK_HALF_PERIOD clock <= ~clock; 27 | end 28 | 29 | always @(posedge clock) begin 30 | cycle <= cycle + 1; 31 | end 32 | 33 | always @(posedge clock) begin 34 | // Should see the bit travel in lane-wise reverse order at output 35 | original <= original << 1; 36 | end 37 | 38 | Array_Reverse_IO 39 | #( 40 | .WORD_WIDTH (WORD_WIDTH), 41 | .LANE_COUNT (LANE_COUNT), 42 | .THREAD_COUNT (THREAD_COUNT) 43 | ) 44 | DUT 45 | ( 46 | .clock (clock), 47 | .in (original), 48 | .out (reversed) 49 | ); 50 | 51 | endmodule 52 | 53 | -------------------------------------------------------------------------------- /Tests/Word_OR_Reducer/test_harness/Word_OR_Reducer_test_harness.v: -------------------------------------------------------------------------------- 1 | 2 | module Word_OR_Reducer_test_harness 3 | #( 4 | parameter WORD_WIDTH = 36, 5 | parameter WORD_COUNT = 16 6 | ) 7 | ( 8 | input wire clock, 9 | input wire in, 10 | output wire out 11 | ); 12 | 13 | // -------------------------------------------------------------------- 14 | // -------------------------------------------------------------------- 15 | 16 | wire [WORD_WIDTH*WORD_COUNT-1:0] dut_in; 17 | wire [WORD_WIDTH-1:0] dut_out; 18 | 19 | Word_OR_Reducer 20 | #( 21 | .WORD_WIDTH (WORD_WIDTH), 22 | .WORD_COUNT (WORD_COUNT) 23 | ) 24 | DUT 25 | ( 26 | .in (dut_in), 27 | .out (dut_out) 28 | ); 29 | 30 | // -------------------------------------------------------------------- 31 | // -------------------------------------------------------------------- 32 | 33 | // Tie-off and register inputs and outputs to get a valid timing analysis. 34 | 35 | harness_input_register 36 | #( 37 | .WIDTH (WORD_WIDTH*WORD_COUNT) 38 | ) 39 | i 40 | ( 41 | .clock (clock), 42 | .in (in), 43 | .rden (1'b1), 44 | .out ({dut_in}) 45 | ); 46 | 47 | 48 | harness_output_register 49 | #( 50 | .WIDTH (WORD_WIDTH) 51 | ) 52 | o 53 | ( 54 | .clock (clock), 55 | .in ({dut_out}), 56 | .wren (1'b1), 57 | .out (out) 58 | ); 59 | 60 | endmodule 61 | 62 | -------------------------------------------------------------------------------- /Octavo/Source/Triadic_ALU_Operations.vh: -------------------------------------------------------------------------------- 1 | 2 | // See Triadic_ALU.v 3 | 4 | `ifndef TRIADIC_ALU_OPERATIONS 5 | `define TRIADIC_ALU_OPERATIONS 6 | 7 | // Number of bits in ALU control word, never changes. 8 | `define TRIADIC_ALU_CTRL_WIDTH 20 9 | 10 | // First, some primitives 11 | 12 | `include "Dyadic_Boolean_Operations.vh" 13 | 14 | `define TRIADIC_SINGLE 1'b0 15 | `define TRIADIC_DUAL 1'b1 16 | 17 | `define SELECT_R 2'd0 18 | `define SELECT_R_ZERO 2'd1 19 | `define SELECT_R_NEG 2'd2 20 | `define SELECT_S 2'd3 21 | 22 | `define SHIFT_NONE 2'd0 23 | `define SHIFT_RIGHT 2'd1 24 | `define SHIFT_RIGHT_SIGNED 2'd2 25 | `define SHIFT_LEFT 2'd3 26 | 27 | `define SPLIT_YES 1'd1 28 | `define SPLIT_NO 1'd0 29 | 30 | `define ADDSUB_A_PLUS_B 2'b00 31 | `define ADDSUB_MINUS_A_PLUS_B 2'b01 32 | `define ADDSUB_A_MINUS_B 2'b10 33 | `define ADDSUB_MINUS_A_MINUS_B 2'b11 34 | 35 | // Second, some useful computations 36 | 37 | `define ALU_NOP ({`SPLIT_NO,`SHIFT_NONE,`DYADIC_ALWAYS_ZERO,`ADDSUB_A_PLUS_B,`TRIADIC_SINGLE,`DYADIC_ALWAYS_ZERO,`DYADIC_ALWAYS_ZERO,`SELECT_R}) 38 | `define ALU_A_PLUS_B ({`SPLIT_NO,`SHIFT_NONE,`DYADIC_B,`ADDSUB_A_PLUS_B,`TRIADIC_SINGLE,`DYADIC_ALWAYS_ZERO,`DYADIC_ALWAYS_ZERO,`SELECT_R}) 39 | `define ALU_DMOV ({`SPLIT_YES,`SHIFT_NONE,`DYADIC_A,`ADDSUB_A_PLUS_B,`TRIADIC_DUAL,`DYADIC_B,`DYADIC_A,`SELECT_S}) 40 | 41 | `endif 42 | 43 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_harness/OD.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 00000 3 | 14000 4 | 15000 5 | 183c0 6 | 75000 7 | 54000 8 | 34000 9 | 00000 10 | 00000 11 | 00000 12 | 00000 13 | 00000 14 | 00000 15 | 00000 16 | 00000 17 | 00000 18 | 00000 19 | 14000 20 | 15000 21 | 183c0 22 | 75000 23 | 54000 24 | 34000 25 | 00000 26 | 00000 27 | 00000 28 | 00000 29 | 00000 30 | 00000 31 | 00000 32 | 00000 33 | 00000 34 | 00000 35 | 14000 36 | 15000 37 | 183c0 38 | 75000 39 | 54000 40 | 34000 41 | 00000 42 | 00000 43 | 00000 44 | 00000 45 | 00000 46 | 00000 47 | 00000 48 | 00000 49 | 00000 50 | 00000 51 | 14000 52 | 15000 53 | 183c0 54 | 75000 55 | 54000 56 | 34000 57 | 00000 58 | 00000 59 | 00000 60 | 00000 61 | 00000 62 | 00000 63 | 00000 64 | 00000 65 | 00000 66 | 00000 67 | 14000 68 | 15000 69 | 183c0 70 | 75000 71 | 54000 72 | 34000 73 | 00000 74 | 00000 75 | 00000 76 | 00000 77 | 00000 78 | 00000 79 | 00000 80 | 00000 81 | 00000 82 | 00000 83 | 14000 84 | 15000 85 | 183c0 86 | 75000 87 | 54000 88 | 34000 89 | 00000 90 | 00000 91 | 00000 92 | 00000 93 | 00000 94 | 00000 95 | 00000 96 | 00000 97 | 00000 98 | 00000 99 | 14000 100 | 15000 101 | 183c0 102 | 75000 103 | 54000 104 | 34000 105 | 00000 106 | 00000 107 | 00000 108 | 00000 109 | 00000 110 | 00000 111 | 00000 112 | 00000 113 | 00000 114 | 00000 115 | 14000 116 | 15000 117 | 183c0 118 | 75000 119 | 54000 120 | 34000 121 | 00000 122 | 00000 123 | 00000 124 | 00000 125 | 00000 126 | 00000 127 | 00000 128 | 00000 129 | 00000 130 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/hailstone-s/OD.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 00000 3 | 14000 4 | 34000 5 | 00000 6 | 00000 7 | 00000 8 | 00000 9 | 00000 10 | 00000 11 | 00000 12 | 00000 13 | 00000 14 | 00000 15 | 00000 16 | 00000 17 | 00000 18 | 00000 19 | 14000 20 | 34000 21 | 00000 22 | 00000 23 | 00000 24 | 00000 25 | 00000 26 | 00000 27 | 00000 28 | 00000 29 | 00000 30 | 00000 31 | 00000 32 | 00000 33 | 00000 34 | 00000 35 | 14000 36 | 34000 37 | 00000 38 | 00000 39 | 00000 40 | 00000 41 | 00000 42 | 00000 43 | 00000 44 | 00000 45 | 00000 46 | 00000 47 | 00000 48 | 00000 49 | 00000 50 | 00000 51 | 14000 52 | 34000 53 | 00000 54 | 00000 55 | 00000 56 | 00000 57 | 00000 58 | 00000 59 | 00000 60 | 00000 61 | 00000 62 | 00000 63 | 00000 64 | 00000 65 | 00000 66 | 00000 67 | 14000 68 | 34000 69 | 00000 70 | 00000 71 | 00000 72 | 00000 73 | 00000 74 | 00000 75 | 00000 76 | 00000 77 | 00000 78 | 00000 79 | 00000 80 | 00000 81 | 00000 82 | 00000 83 | 14000 84 | 34000 85 | 00000 86 | 00000 87 | 00000 88 | 00000 89 | 00000 90 | 00000 91 | 00000 92 | 00000 93 | 00000 94 | 00000 95 | 00000 96 | 00000 97 | 00000 98 | 00000 99 | 14000 100 | 34000 101 | 00000 102 | 00000 103 | 00000 104 | 00000 105 | 00000 106 | 00000 107 | 00000 108 | 00000 109 | 00000 110 | 00000 111 | 00000 112 | 00000 113 | 00000 114 | 00000 115 | 14000 116 | 34000 117 | 00000 118 | 00000 119 | 00000 120 | 00000 121 | 00000 122 | 00000 123 | 00000 124 | 00000 125 | 00000 126 | 00000 127 | 00000 128 | 00000 129 | 00000 130 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/array-reverse-3/OD.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 14000 3 | 00000 4 | 00000 5 | 00000 6 | 00000 7 | 00000 8 | 00000 9 | 00000 10 | 00000 11 | 00000 12 | 00000 13 | 00000 14 | 00000 15 | 00000 16 | 00000 17 | 00000 18 | 14000 19 | 00000 20 | 00000 21 | 00000 22 | 00000 23 | 00000 24 | 00000 25 | 00000 26 | 00000 27 | 00000 28 | 00000 29 | 00000 30 | 00000 31 | 00000 32 | 00000 33 | 00000 34 | 14000 35 | 00000 36 | 00000 37 | 00000 38 | 00000 39 | 00000 40 | 00000 41 | 00000 42 | 00000 43 | 00000 44 | 00000 45 | 00000 46 | 00000 47 | 00000 48 | 00000 49 | 00000 50 | 14000 51 | 00000 52 | 00000 53 | 00000 54 | 00000 55 | 00000 56 | 00000 57 | 00000 58 | 00000 59 | 00000 60 | 00000 61 | 00000 62 | 00000 63 | 00000 64 | 00000 65 | 00000 66 | 14000 67 | 00000 68 | 00000 69 | 00000 70 | 00000 71 | 00000 72 | 00000 73 | 00000 74 | 00000 75 | 00000 76 | 00000 77 | 00000 78 | 00000 79 | 00000 80 | 00000 81 | 00000 82 | 14000 83 | 00000 84 | 00000 85 | 00000 86 | 00000 87 | 00000 88 | 00000 89 | 00000 90 | 00000 91 | 00000 92 | 00000 93 | 00000 94 | 00000 95 | 00000 96 | 00000 97 | 00000 98 | 14000 99 | 00000 100 | 00000 101 | 00000 102 | 00000 103 | 00000 104 | 00000 105 | 00000 106 | 00000 107 | 00000 108 | 00000 109 | 00000 110 | 00000 111 | 00000 112 | 00000 113 | 00000 114 | 14000 115 | 00000 116 | 00000 117 | 00000 118 | 00000 119 | 00000 120 | 00000 121 | 00000 122 | 00000 123 | 00000 124 | 00000 125 | 00000 126 | 00000 127 | 00000 128 | 00000 129 | 00000 130 | -------------------------------------------------------------------------------- /Octavo/Assembler/benchmarks/hailstone-arrays/OD.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 00000 3 | 14000 4 | 15000 5 | 183c0 6 | 75000 7 | 54000 8 | 34000 9 | 00000 10 | 00000 11 | 00000 12 | 00000 13 | 00000 14 | 00000 15 | 00000 16 | 00000 17 | 00000 18 | 00000 19 | 14000 20 | 15000 21 | 183c0 22 | 75000 23 | 54000 24 | 34000 25 | 00000 26 | 00000 27 | 00000 28 | 00000 29 | 00000 30 | 00000 31 | 00000 32 | 00000 33 | 00000 34 | 00000 35 | 14000 36 | 15000 37 | 183c0 38 | 75000 39 | 54000 40 | 34000 41 | 00000 42 | 00000 43 | 00000 44 | 00000 45 | 00000 46 | 00000 47 | 00000 48 | 00000 49 | 00000 50 | 00000 51 | 14000 52 | 15000 53 | 183c0 54 | 75000 55 | 54000 56 | 34000 57 | 00000 58 | 00000 59 | 00000 60 | 00000 61 | 00000 62 | 00000 63 | 00000 64 | 00000 65 | 00000 66 | 00000 67 | 14000 68 | 15000 69 | 183c0 70 | 75000 71 | 54000 72 | 34000 73 | 00000 74 | 00000 75 | 00000 76 | 00000 77 | 00000 78 | 00000 79 | 00000 80 | 00000 81 | 00000 82 | 00000 83 | 14000 84 | 15000 85 | 183c0 86 | 75000 87 | 54000 88 | 34000 89 | 00000 90 | 00000 91 | 00000 92 | 00000 93 | 00000 94 | 00000 95 | 00000 96 | 00000 97 | 00000 98 | 00000 99 | 14000 100 | 15000 101 | 183c0 102 | 75000 103 | 54000 104 | 34000 105 | 00000 106 | 00000 107 | 00000 108 | 00000 109 | 00000 110 | 00000 111 | 00000 112 | 00000 113 | 00000 114 | 00000 115 | 14000 116 | 15000 117 | 183c0 118 | 75000 119 | 54000 120 | 34000 121 | 00000 122 | 00000 123 | 00000 124 | 00000 125 | 00000 126 | 00000 127 | 00000 128 | 00000 129 | 00000 130 | -------------------------------------------------------------------------------- /Parts/Misc/master_reset.v: -------------------------------------------------------------------------------- 1 | 2 | // Master reset for IP that needs a reset to enter non-X initial state. 3 | // Simply a delayed release, synchronous to the system clock, after the FPGA 4 | // comes out of configuration reset. 5 | 6 | module master_reset 7 | #( 8 | parameter DELAY_CYCLE_COUNT = 0 9 | ) 10 | ( 11 | input wire clock, 12 | output reg reset 13 | ); 14 | 15 | // -------------------------------------------------------------------------- 16 | 17 | initial begin 18 | reset = 1'b0; 19 | end 20 | 21 | // -------------------------------------------------------------------------- 22 | 23 | `include "clog2_function.vh" 24 | 25 | localparam COUNTER_WIDTH = clog2(DELAY_CYCLE_COUNT); 26 | localparam COUNTER_ZERO = {COUNTER_WIDTH{1'b0}}; 27 | localparam COUNTER_ONE = {{COUNTER_WIDTH-1{1'b0}},1'b1}; 28 | localparam COUNTER_FINAL = DELAY_CYCLE_COUNT-1; 29 | 30 | // -------------------------------------------------------------------------- 31 | 32 | // Count N-1 times, and reset goes low one cycle later. 33 | // This keeps everything pipelined, and means reset stays high 34 | // for DELAY_CYCLE_COUNT cycles exactly. 35 | 36 | reg [COUNTER_WIDTH-1:0] count = COUNTER_ZERO; 37 | reg not_done = 1'b0; 38 | 39 | always @(*) begin 40 | not_done = (count != COUNTER_FINAL[COUNTER_WIDTH-1:0]); 41 | end 42 | 43 | always @(posedge clock) begin 44 | count <= (not_done == 1'b1) ? (count + COUNTER_ONE) : count; 45 | reset <= (not_done == 1'b1); 46 | end 47 | 48 | endmodule 49 | 50 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-s/RUN/OD.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 00000 3 | 14000 4 | 34000 5 | 00000 6 | 00000 7 | 00000 8 | 00000 9 | 00000 10 | 00000 11 | 00000 12 | 00000 13 | 00000 14 | 00000 15 | 00000 16 | 00000 17 | 00000 18 | 00000 19 | 14000 20 | 34000 21 | 00000 22 | 00000 23 | 00000 24 | 00000 25 | 00000 26 | 00000 27 | 00000 28 | 00000 29 | 00000 30 | 00000 31 | 00000 32 | 00000 33 | 00000 34 | 00000 35 | 14000 36 | 34000 37 | 00000 38 | 00000 39 | 00000 40 | 00000 41 | 00000 42 | 00000 43 | 00000 44 | 00000 45 | 00000 46 | 00000 47 | 00000 48 | 00000 49 | 00000 50 | 00000 51 | 14000 52 | 34000 53 | 00000 54 | 00000 55 | 00000 56 | 00000 57 | 00000 58 | 00000 59 | 00000 60 | 00000 61 | 00000 62 | 00000 63 | 00000 64 | 00000 65 | 00000 66 | 00000 67 | 14000 68 | 34000 69 | 00000 70 | 00000 71 | 00000 72 | 00000 73 | 00000 74 | 00000 75 | 00000 76 | 00000 77 | 00000 78 | 00000 79 | 00000 80 | 00000 81 | 00000 82 | 00000 83 | 14000 84 | 34000 85 | 00000 86 | 00000 87 | 00000 88 | 00000 89 | 00000 90 | 00000 91 | 00000 92 | 00000 93 | 00000 94 | 00000 95 | 00000 96 | 00000 97 | 00000 98 | 00000 99 | 14000 100 | 34000 101 | 00000 102 | 00000 103 | 00000 104 | 00000 105 | 00000 106 | 00000 107 | 00000 108 | 00000 109 | 00000 110 | 00000 111 | 00000 112 | 00000 113 | 00000 114 | 00000 115 | 14000 116 | 34000 117 | 00000 118 | 00000 119 | 00000 120 | 00000 121 | 00000 122 | 00000 123 | 00000 124 | 00000 125 | 00000 126 | 00000 127 | 00000 128 | 00000 129 | 00000 130 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/array-reverse-3/RUN/OD.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 14000 3 | 00000 4 | 00000 5 | 00000 6 | 00000 7 | 00000 8 | 00000 9 | 00000 10 | 00000 11 | 00000 12 | 00000 13 | 00000 14 | 00000 15 | 00000 16 | 00000 17 | 00000 18 | 14000 19 | 00000 20 | 00000 21 | 00000 22 | 00000 23 | 00000 24 | 00000 25 | 00000 26 | 00000 27 | 00000 28 | 00000 29 | 00000 30 | 00000 31 | 00000 32 | 00000 33 | 00000 34 | 14000 35 | 00000 36 | 00000 37 | 00000 38 | 00000 39 | 00000 40 | 00000 41 | 00000 42 | 00000 43 | 00000 44 | 00000 45 | 00000 46 | 00000 47 | 00000 48 | 00000 49 | 00000 50 | 14000 51 | 00000 52 | 00000 53 | 00000 54 | 00000 55 | 00000 56 | 00000 57 | 00000 58 | 00000 59 | 00000 60 | 00000 61 | 00000 62 | 00000 63 | 00000 64 | 00000 65 | 00000 66 | 14000 67 | 00000 68 | 00000 69 | 00000 70 | 00000 71 | 00000 72 | 00000 73 | 00000 74 | 00000 75 | 00000 76 | 00000 77 | 00000 78 | 00000 79 | 00000 80 | 00000 81 | 00000 82 | 14000 83 | 00000 84 | 00000 85 | 00000 86 | 00000 87 | 00000 88 | 00000 89 | 00000 90 | 00000 91 | 00000 92 | 00000 93 | 00000 94 | 00000 95 | 00000 96 | 00000 97 | 00000 98 | 14000 99 | 00000 100 | 00000 101 | 00000 102 | 00000 103 | 00000 104 | 00000 105 | 00000 106 | 00000 107 | 00000 108 | 00000 109 | 00000 110 | 00000 111 | 00000 112 | 00000 113 | 00000 114 | 14000 115 | 00000 116 | 00000 117 | 00000 118 | 00000 119 | 00000 120 | 00000 121 | 00000 122 | 00000 123 | 00000 124 | 00000 125 | 00000 126 | 00000 127 | 00000 128 | 00000 129 | 00000 130 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-arrays/RUN/OD.mem: -------------------------------------------------------------------------------- 1 | // format=hex addressradix=h dataradix=h version=1.0 wordsperline=1 noaddress 2 | 00000 3 | 14000 4 | 15000 5 | 183c0 6 | 75000 7 | 54000 8 | 34000 9 | 00000 10 | 00000 11 | 00000 12 | 00000 13 | 00000 14 | 00000 15 | 00000 16 | 00000 17 | 00000 18 | 00000 19 | 14000 20 | 15000 21 | 183c0 22 | 75000 23 | 54000 24 | 34000 25 | 00000 26 | 00000 27 | 00000 28 | 00000 29 | 00000 30 | 00000 31 | 00000 32 | 00000 33 | 00000 34 | 00000 35 | 14000 36 | 15000 37 | 183c0 38 | 75000 39 | 54000 40 | 34000 41 | 00000 42 | 00000 43 | 00000 44 | 00000 45 | 00000 46 | 00000 47 | 00000 48 | 00000 49 | 00000 50 | 00000 51 | 14000 52 | 15000 53 | 183c0 54 | 75000 55 | 54000 56 | 34000 57 | 00000 58 | 00000 59 | 00000 60 | 00000 61 | 00000 62 | 00000 63 | 00000 64 | 00000 65 | 00000 66 | 00000 67 | 14000 68 | 15000 69 | 183c0 70 | 75000 71 | 54000 72 | 34000 73 | 00000 74 | 00000 75 | 00000 76 | 00000 77 | 00000 78 | 00000 79 | 00000 80 | 00000 81 | 00000 82 | 00000 83 | 14000 84 | 15000 85 | 183c0 86 | 75000 87 | 54000 88 | 34000 89 | 00000 90 | 00000 91 | 00000 92 | 00000 93 | 00000 94 | 00000 95 | 00000 96 | 00000 97 | 00000 98 | 00000 99 | 14000 100 | 15000 101 | 183c0 102 | 75000 103 | 54000 104 | 34000 105 | 00000 106 | 00000 107 | 00000 108 | 00000 109 | 00000 110 | 00000 111 | 00000 112 | 00000 113 | 00000 114 | 00000 115 | 14000 116 | 15000 117 | 183c0 118 | 75000 119 | 54000 120 | 34000 121 | 00000 122 | 00000 123 | 00000 124 | 00000 125 | 00000 126 | 00000 127 | 00000 128 | 00000 129 | 00000 130 | -------------------------------------------------------------------------------- /Parts/Counters/UpDown_Counter.v: -------------------------------------------------------------------------------- 1 | 2 | // A counter which can count up or down by 1, wraps around when passing 0 or maximum. 3 | 4 | `default_nettype none 5 | 6 | module UpDown_Counter 7 | #( 8 | parameter WORD_WIDTH = 0, 9 | parameter INITIAL_COUNT = 0 // Since WORD_WIDTH can be > 32 bits 10 | ) 11 | ( 12 | input wire clock, 13 | input wire up_down, // 1/0 up/down 14 | input wire run, // counts one step if set 15 | input wire wren, // Write overrules count 16 | input wire [WORD_WIDTH-1:0] write_data, 17 | output reg [WORD_WIDTH-1:0] count, 18 | output reg [WORD_WIDTH-1:0] next_count // sometimes handy 19 | ); 20 | 21 | // -------------------------------------------------------------------------- 22 | 23 | localparam ZERO = {WORD_WIDTH{1'b0}}; 24 | localparam ONE = {{WORD_WIDTH-1{1'b0}},1'b1}; 25 | localparam MINUS_ONE = ~ZERO; 26 | 27 | initial begin 28 | count = INITIAL_COUNT[WORD_WIDTH-1:0]; 29 | next_count = ZERO; 30 | end 31 | 32 | // -------------------------------------------------------------------------- 33 | 34 | reg [WORD_WIDTH-1:0] increment = ZERO; 35 | 36 | always @(*) begin 37 | increment = (up_down == 1'b1) ? ONE : MINUS_ONE; 38 | next_count = (wren == 1'b1) ? write_data : (count + increment); 39 | end 40 | 41 | always @(posedge clock) begin 42 | count <= ((run == 1'b1) || (wren == 1'b1)) ? next_count : count; 43 | end 44 | 45 | endmodule 46 | 47 | -------------------------------------------------------------------------------- /Parts/Multipliers/Multiplier_Generic.v: -------------------------------------------------------------------------------- 1 | 2 | // Generic description for an optionally pipelined 3 | // full-word multiplier, signed or unsigned. 4 | // Meant for simulation, but might synthesize well too. 5 | 6 | // {R_high, R_low} = A * B; 7 | 8 | `default_nettype none 9 | 10 | module Multiplier_Generic 11 | #( 12 | parameter WORD_WIDTH = 0, 13 | parameter PIPELINE_DEPTH = 0 14 | ) 15 | ( 16 | input wire clock, 17 | input wire is_signed, 18 | input wire [WORD_WIDTH-1:0] A, 19 | input wire [WORD_WIDTH-1:0] B, 20 | output wire [WORD_WIDTH-1:0] R_low, 21 | output wire [WORD_WIDTH-1:0] R_high 22 | ); 23 | 24 | // -------------------------------------------------------------------------- 25 | 26 | // Let's always do a full multiplication. 27 | // The enclosing module can pick a subset if it wants to. 28 | localparam OUTPUT_WIDTH = WORD_WIDTH * 2; 29 | localparam RESULT_ZERO = {OUTPUT_WIDTH{1'b0}}; 30 | 31 | reg [OUTPUT_WIDTH-1:0] result = RESULT_ZERO; 32 | 33 | always @(*) begin 34 | result = (is_signed == 1'b1) ? $signed(A) * $signed(B) : A * B; 35 | end 36 | 37 | // -------------------------------------------------------------------------- 38 | 39 | // Pipeline the result. These should get retimed if synthesized. 40 | 41 | Delay_Line 42 | #( 43 | .DEPTH (PIPELINE_DEPTH), 44 | .WIDTH (OUTPUT_WIDTH) 45 | ) 46 | pipeline_stages 47 | ( 48 | .clock (clock), 49 | .in (result), 50 | .out ({R_high, R_low}) 51 | ); 52 | 53 | endmodule 54 | 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | By default, and unless explicitly specified otherwise, all work in this repo falls under the BSD 2-Clause License 2 | 3 | ---- 4 | 5 | Copyright: 2012-2019, Charles Eric LaForest, eric@fpgacpu.ca 6 | License: BSD 2-Clause License http://opensource.org/licenses/BSD-2-Clause 7 | 8 | ---- 9 | 10 | Copyright (c) 2012-2019, Charles Eric LaForest, eric@fpgacpu.ca 11 | All rights reserved. 12 | 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | Redistributions of source code must retain the above copyright notice, this 17 | list of conditions and the following disclaimer. 18 | 19 | Redistributions in binary form must reproduce the above copyright notice, 20 | this list of conditions and the following disclaimer in the documentation 21 | and/or other materials provided with the distribution. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 24 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | -------------------------------------------------------------------------------- /Parts/Memory/RAM_TDP_Example.v: -------------------------------------------------------------------------------- 1 | 2 | `default_nettype none 3 | 4 | module RAM_TDP_Example 5 | #( 6 | parameter WORD_WIDTH = 36, 7 | parameter ADDR_WIDTH = 12, 8 | parameter DEPTH = 4096, 9 | parameter RAMSTYLE = "M10K", 10 | parameter READ_NEW_DATA = 0, 11 | parameter USE_INIT_FILE = 0, 12 | parameter INIT_FILE = "" 13 | ) 14 | ( 15 | input wire clock, 16 | 17 | input wire wren_A, 18 | input wire [ADDR_WIDTH-1:0] addr_A, 19 | input wire [WORD_WIDTH-1:0] write_data_A, 20 | output reg [WORD_WIDTH-1:0] read_data_A, 21 | 22 | input wire wren_B, 23 | input wire [ADDR_WIDTH-1:0] addr_B, 24 | input wire [WORD_WIDTH-1:0] write_data_B, 25 | output reg [WORD_WIDTH-1:0] read_data_B 26 | ); 27 | 28 | RAM_TDP 29 | #( 30 | .WORD_WIDTH (WORD_WIDTH), 31 | .ADDR_WIDTH (ADDR_WIDTH), 32 | .DEPTH (DEPTH), 33 | .RAMSTYLE (RAMSTYLE), 34 | .READ_NEW_DATA (READ_NEW_DATA), 35 | .USE_INIT_FILE (USE_INIT_FILE), 36 | .INIT_FILE (INIT_FILE) 37 | ) 38 | Example 39 | ( 40 | .clock (clock), 41 | 42 | .wren_A (wren_A), 43 | .addr_A (addr_A), 44 | .write_data_A (write_data_A), 45 | .read_data_A (read_data_A), 46 | 47 | .wren_B (wren_B), 48 | .addr_B (addr_B), 49 | .write_data_B (write_data_B), 50 | .read_data_B (read_data_B) 51 | ); 52 | 53 | endmodule 54 | 55 | -------------------------------------------------------------------------------- /Parts/Memory/RAM_SDP_Composite_Example.v: -------------------------------------------------------------------------------- 1 | 2 | `default_nettype none 3 | 4 | module RAM_SDP_Composite_Example 5 | #( 6 | parameter WORD_WIDTH = 36, 7 | parameter ADDR_WIDTH = 12, 8 | parameter DEPTH = 4096, 9 | parameter RAMSTYLE = "M10K", 10 | parameter READ_NEW_DATA = 0, 11 | parameter USE_INIT_FILE = 0, 12 | // Parameters for the individual sub-RAMs 13 | parameter SUB_INIT_FILE = "", 14 | parameter SUB_ADDR_WIDTH = 6, 15 | parameter SUB_DEPTH = 64 16 | ) 17 | ( 18 | input wire clock, 19 | input wire wren, 20 | input wire [ADDR_WIDTH-1:0] write_addr, 21 | input wire [WORD_WIDTH-1:0] write_data, 22 | input wire rden, 23 | input wire [ADDR_WIDTH-1:0] read_addr, 24 | output reg [WORD_WIDTH-1:0] read_data 25 | ); 26 | 27 | RAM_SDP_Composite 28 | #( 29 | .WORD_WIDTH (WORD_WIDTH), 30 | .ADDR_WIDTH (ADDR_WIDTH), 31 | .DEPTH (DEPTH), 32 | .RAMSTYLE (RAMSTYLE), 33 | .READ_NEW_DATA (READ_NEW_DATA), 34 | .USE_INIT_FILE (USE_INIT_FILE), 35 | .SUB_INIT_FILE (SUB_INIT_FILE), 36 | .SUB_ADDR_WIDTH (SUB_ADDR_WIDTH), 37 | .SUB_DEPTH (SUB_DEPTH) 38 | ) 39 | Example 40 | ( 41 | .clock (clock), 42 | .wren (wren), 43 | .write_addr (write_addr), 44 | .write_data (write_data), 45 | .rden (rden), 46 | .read_addr (read_addr), 47 | .read_data (read_data) 48 | ); 49 | 50 | endmodule 51 | 52 | -------------------------------------------------------------------------------- /Parts/Multithreading/Delay_Line.v: -------------------------------------------------------------------------------- 1 | 2 | // A configurable multi-stage pipeline, with no logic. 3 | // Allows easy adjustments via parameter calculations. 4 | // This is very useful to align various signals along a pipeline. 5 | 6 | `default_nettype none 7 | 8 | module Delay_Line 9 | #( 10 | parameter DEPTH = 0, 11 | parameter WIDTH = 0 12 | ) 13 | ( 14 | // Not used if DEPTH is zero 15 | // verilator lint_off UNUSED 16 | input wire clock, 17 | // verilator lint_on UNUSED 18 | input wire [WIDTH-1:0] in, 19 | output reg [WIDTH-1:0] out 20 | ); 21 | 22 | // -------------------------------------------------------------------------- 23 | 24 | localparam ZERO = {WIDTH{1'b0}}; 25 | 26 | initial begin 27 | out = ZERO; 28 | end 29 | 30 | // -------------------------------------------------------------------------- 31 | 32 | generate 33 | if (DEPTH == 0) begin 34 | always @(*) begin 35 | out = in; 36 | end 37 | end 38 | else begin 39 | integer i; 40 | 41 | reg [WIDTH-1:0] stage [DEPTH-1:0]; 42 | 43 | initial begin 44 | for(i = 0; i < DEPTH; i = i + 1) begin 45 | stage[i] = ZERO; 46 | end 47 | end 48 | 49 | always @(posedge clock) begin 50 | stage[0] <= in; 51 | for(i = 1; i < DEPTH; i = i + 1) begin 52 | stage[i] <= stage[i-1]; 53 | end 54 | end 55 | 56 | always @(*) begin 57 | out = stage[DEPTH-1]; 58 | end 59 | end 60 | endgenerate 61 | 62 | endmodule 63 | 64 | -------------------------------------------------------------------------------- /Parts/Misc/Word_OR_Reducer.v: -------------------------------------------------------------------------------- 1 | 2 | // Computes a word-wide OR-reduction 3 | 4 | `default_nettype none 5 | 6 | module Word_OR_Reducer 7 | #( 8 | parameter WORD_WIDTH = 0, 9 | parameter WORD_COUNT = 0 10 | ) 11 | ( 12 | input wire [(WORD_WIDTH*WORD_COUNT)-1:0] in, 13 | output reg [ WORD_WIDTH -1:0] out 14 | ); 15 | 16 | localparam ZERO = {WORD_WIDTH{1'b0}}; 17 | 18 | initial begin 19 | out = ZERO; 20 | end 21 | 22 | // -------------------------------------------------------------------- 23 | 24 | // We must contain each partial result in a separate variable. 25 | // Computing the OR-reduction in a loop on the same variable implies 26 | // a combinational loop, which is not what we want. 27 | 28 | reg [WORD_WIDTH-1:0] out_reduction [WORD_COUNT-1:0]; 29 | 30 | integer i; 31 | 32 | initial begin 33 | for(i=0; i < WORD_COUNT; i=i+1) begin 34 | out_reduction[i] = ZERO; 35 | end 36 | end 37 | 38 | // -------------------------------------------------------------------- 39 | 40 | always @(*) begin 41 | // Connect the zeroth input word to the zeroth variable. 42 | // This peels out the first loop iteration, where the read index 43 | // would be out of range otherwise. 44 | out_reduction[0] = in[0 +: WORD_WIDTH]; 45 | 46 | // OR the previous partial result with the current input word. 47 | for(i=1; i < WORD_COUNT; i=i+1) begin 48 | out_reduction[i] = out_reduction[i-1] | in[WORD_WIDTH*i +: WORD_WIDTH]; 49 | end 50 | 51 | // The last partial result is the final result. 52 | out = out_reduction[WORD_COUNT-1]; 53 | end 54 | 55 | endmodule 56 | 57 | -------------------------------------------------------------------------------- /Parts/CDC/cdc_synchronizer.v: -------------------------------------------------------------------------------- 1 | 2 | // A basic Clock Domain Crossing synchronizer 3 | 4 | // Only pass 1 synchronization bit, as a level change. 5 | // (synchronizing more than one bit across clocks is not deterministic) 6 | 7 | // If passing a pulse: must be from slow to fast clock, and 8 | // pulse period must be minimum 3x longer than fast clock period. 9 | // (three receiving fast clock edges per bit level transition) 10 | 11 | // For passing a pulse from fast to slow clock, use a pulse synchronizer. 12 | 13 | `default_nettype none 14 | 15 | module cdc_synchronizer 16 | #( 17 | // Must be 0 or greater. 18 | // See DEPTH below for meaning. 19 | parameter EXTRA_DEPTH = 0 20 | ) 21 | ( 22 | input wire sync_bit_from, 23 | input wire clock_to, 24 | output reg sync_bit_to 25 | ); 26 | 27 | // -------------------------------------------------------------------------- 28 | 29 | // Minimum valid depth is 2. 30 | // Add more if the platform requires it. 31 | // (usually near the highest operating frequencies) 32 | localparam DEPTH = 2 + EXTRA_DEPTH; 33 | localparam ZERO = {DEPTH{1'b0}}; 34 | 35 | // Tell Vivado that these reg should be placed together (UG912), 36 | // and to show up as part of MTBF reports. 37 | (* ASYNC_REG = "TRUE" *) 38 | reg [DEPTH-1:0] sync_reg = ZERO; 39 | 40 | // -------------------------------------------------------------------------- 41 | // Pass the sync bit through DEPTH registers in the receiving clock domain. 42 | 43 | integer i; 44 | 45 | always @(posedge clock_to) begin 46 | sync_reg[0] <= sync_bit_from; 47 | for(i = 1; i < DEPTH; i = i+1) begin: cdc_stages 48 | sync_reg[i] <= sync_reg[i-1]; 49 | end 50 | end 51 | 52 | always @(*) begin 53 | sync_bit_to = sync_reg[DEPTH-1]; 54 | end 55 | 56 | endmodule 57 | 58 | -------------------------------------------------------------------------------- /Octavo/Assembler/Parser.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python3 2 | 3 | from Debug import Debug 4 | 5 | class Parser (Debug): 6 | """Parses the assembly file lines and passes non-file commands to the command parser""" 7 | 8 | def __init__ (self, commands): 9 | Debug.__init__(self) 10 | self.commands = commands 11 | 12 | def strip_comments (self, line): 13 | """Return line without trailing comments. If comment starts a line, return empty line.""" 14 | stripped_line = line.split("#") 15 | stripped_line = stripped_line[0] 16 | stripped_line = stripped_line.strip() 17 | return stripped_line 18 | 19 | def parse_line (self, line): 20 | """Process each line, converting the command name into a method call to built-in assembler commands (not part of the programming per se) 21 | or pass it to command parser if unknown. First word is the command, the rest are it's arguments. (but see parse_commands re: labels)""" 22 | line = self.strip_comments(line) 23 | if len(line) == 0: 24 | return 25 | split_line = line.split() 26 | command = split_line[0] 27 | arguments = split_line[1:] 28 | parser_command = getattr(self, command, None) 29 | if parser_command is None: 30 | self.commands.parse_command(command, arguments) 31 | return 32 | parser_command(arguments) 33 | 34 | def parse_file (self, filename): 35 | with open(filename) as f: 36 | for raw_line in f.readlines(): 37 | self.parse_line(raw_line) 38 | 39 | # These are assembler commands, not related to the programming itself. 40 | 41 | def include (self, arguments): 42 | """Recurse into included files. No cycle checking!""" 43 | filename = arguments[0] 44 | self.parse_file(filename) 45 | 46 | -------------------------------------------------------------------------------- /Octavo/README.md: -------------------------------------------------------------------------------- 1 | Octavo 2 | ====== 3 | 4 | *The Octavo project has ended. See: http://fpgacpu.ca/octavo for project outcomes and detailed architectural documentation.* 5 | 6 | * Assembler: A basic Octavo assembler written in Python. Does not do resource de-allocation yet. 7 | * Diagrams: Block diagrams of functional modules. (See http://fpgacpu.ca/octavo for their explanation.) 8 | * Issues: An archive of past Github issues for this project. All closed since project end. 9 | * Source: The Octavo Verilog source code. Depends on many little modules in the Parts library (elswhere in this repo). Also contains source for some application-specific accelerators. 10 | * Tests: Some simple test benches and test harnesses for Octavo and some of the more complex parts (e.g. the ALU) 11 | 12 | The Octavo soft-CPU architecture aims to maximize the amount of processing 13 | possible on an FPGA without creating fully custom hardware. 14 | 15 | It generally reaches 80% of the maximum possible operating frequency of an 16 | FPGA device, while still computing more efficiently than any in-order scalar 17 | RISC processor. 18 | 19 | The performance comes at a price though: Octavo won't act as a drop-in 20 | replacement for Nios or other conventional soft-processors. It's not 21 | straightforward to program in assembly. You have to divide the work across 8 22 | independent hardware threads (but they do share all the memory). 23 | 24 | On the other hand, each thread sees the equivalent of an ideal, if slow 25 | processor which never stalls, has no instruction dependencies, and executes 26 | every instruction in a single cycle (branches take zero cycles). The direct 27 | memory addressing enables compact loops and parallel updating of multiple 28 | "pointers" or indices, and allows up to 2 I/O reads, an ALU operation, and 2 29 | I/O writes *per cycle*, so you can process streams of data or control external 30 | hardware efficiently. 31 | 32 | -------------------------------------------------------------------------------- /Parts/Counters/Down_Counter_Zero.v: -------------------------------------------------------------------------------- 1 | // Counts downward to zero. 2 | // Counts down one step if run is set. 3 | // Halts when it reaches zero, and raises zero signal. 4 | // Must load a new value to restart. 5 | // Load overrides run. 6 | 7 | // Uses an external count value store to support sharing the counter hardware. 8 | // (e.g.: an array of memory locations, each updated in turn) 9 | 10 | `default_nettype none 11 | 12 | module Down_Counter_Zero 13 | #( 14 | parameter WORD_WIDTH = 0 15 | ) 16 | ( 17 | input wire run, 18 | input wire [WORD_WIDTH-1:0] count_in, 19 | input wire load_wren, 20 | input wire [WORD_WIDTH-1:0] load_value, 21 | output reg count_out_wren, 22 | output reg [WORD_WIDTH-1:0] count_out, 23 | // Incorrect detection of circular logic, 24 | // possibly because the clocked storage is outside this module. 25 | // verilator lint_off UNOPT 26 | output reg count_zero 27 | // verilator lint_on UNOPT 28 | ); 29 | 30 | // -------------------------------------------------------------------------- 31 | 32 | localparam ZERO = {WORD_WIDTH{1'b0}}; 33 | localparam ONE = {{(WORD_WIDTH-1){1'b0}},1'b1}; 34 | 35 | initial begin 36 | count_out_wren = 1'b0; 37 | count_out = ZERO; 38 | count_zero = 1'b1; 39 | end 40 | 41 | // -------------------------------------------------------------------------- 42 | 43 | reg count_run = 0; 44 | 45 | always @(*) begin 46 | count_run = (run == 1'b1) & (count_zero == 1'b0); 47 | count_out_wren = (count_run == 1'b1) | (load_wren == 1'b1); 48 | count_out = (load_wren == 1'b1) ? load_value : (count_in - ONE); 49 | count_zero = (count_out == ZERO); 50 | end 51 | 52 | endmodule 53 | 54 | -------------------------------------------------------------------------------- /Parts/Multiplexers/Translated_Addressed_Mux.v: -------------------------------------------------------------------------------- 1 | 2 | // Select some inputs from a consecutive, but not power-of-2 aligned, 3 | // address range. This allows us to use the raw memory address to select some 4 | // memory-mapped item. 5 | 6 | `default_nettype none 7 | 8 | module Translated_Addressed_Mux 9 | #( 10 | parameter WORD_WIDTH = 0, 11 | parameter ADDR_WIDTH = 0, // Full address width 12 | parameter INPUT_COUNT = 0, 13 | parameter INPUT_BASE_ADDR = 0, 14 | parameter INPUT_ADDR_WIDTH = 0, // clog2(INPUT_COUNT) 15 | 16 | // Not for instantiation 17 | parameter TOTAL_WIDTH = INPUT_COUNT * WORD_WIDTH 18 | ) 19 | ( 20 | // Only LSB used, but full width here for easy system integration 21 | // verilator lint_off UNUSED 22 | input wire [ADDR_WIDTH-1:0] addr, 23 | // verilator lint_on UNUSED 24 | input wire [TOTAL_WIDTH-1:0] in, 25 | output wire [WORD_WIDTH-1:0] out 26 | ); 27 | 28 | // -------------------------------------------------------------------------- 29 | 30 | wire [INPUT_ADDR_WIDTH-1:0] addr_translated; 31 | 32 | Address_Range_Translator 33 | #( 34 | .ADDR_COUNT (INPUT_COUNT), 35 | .ADDR_BASE (INPUT_BASE_ADDR), 36 | .ADDR_WIDTH (INPUT_ADDR_WIDTH), 37 | .REGISTERED (0) 38 | ) 39 | ART 40 | ( 41 | .clock (1'b0), 42 | .raw_address (addr[INPUT_ADDR_WIDTH-1:0]), 43 | .translated_address (addr_translated) 44 | ); 45 | 46 | Addressed_Mux 47 | #( 48 | .WORD_WIDTH (WORD_WIDTH), 49 | .ADDR_WIDTH (INPUT_ADDR_WIDTH), 50 | .INPUT_COUNT (INPUT_COUNT) 51 | ) 52 | AM 53 | ( 54 | .addr (addr_translated), 55 | .in (in), 56 | .out (out) 57 | ); 58 | 59 | endmodule 60 | 61 | -------------------------------------------------------------------------------- /Octavo/Source/IO_Write_Predication.v: -------------------------------------------------------------------------------- 1 | 2 | // IO_Write_Predication. Allows us to prevent a write to an I/O port if the 3 | // port isn't ready. 4 | 5 | // Similar as IO_Read_Predication, except the IO_Active check, to generate all 6 | // the write enables, is done separately, after the ALU. 7 | 8 | `default_nettype none 9 | 10 | module IO_Write_Predication 11 | #( 12 | parameter ADDR_WIDTH = 0, 13 | parameter PORT_COUNT = 0, 14 | parameter PORT_BASE_ADDR = 0, 15 | parameter PORT_ADDR_WIDTH = 0 16 | ) 17 | ( 18 | input wire clock, 19 | input wire enable, 20 | input wire [ADDR_WIDTH-1:0] addr, 21 | input wire [PORT_COUNT-1:0] EmptyFull, 22 | output wire EmptyFull_masked, 23 | output reg addr_is_IO 24 | ); 25 | 26 | // ----------------------------------------------------------- 27 | 28 | initial begin 29 | addr_is_IO = 0; 30 | end 31 | 32 | // ----------------------------------------------------------- 33 | // Stage 1 and 2 34 | 35 | wire addr_is_IO_raw; 36 | 37 | IO_Check 38 | #( 39 | .READY_STATE (1'b0), // EMPTY 40 | .ADDR_WIDTH (ADDR_WIDTH), 41 | .PORT_COUNT (PORT_COUNT), 42 | .PORT_BASE_ADDR (PORT_BASE_ADDR), 43 | .PORT_ADDR_WIDTH (PORT_ADDR_WIDTH) 44 | ) 45 | Write_IO_Check 46 | ( 47 | .clock (clock), 48 | .enable (enable), 49 | .addr (addr), 50 | .port_EF (EmptyFull), 51 | .port_EF_masked (EmptyFull_masked), 52 | .addr_is_IO (addr_is_IO_raw) 53 | ); 54 | 55 | // -------------------------------------------------------------------- 56 | // This is to line up to Stage 2 of the IO_Check 57 | 58 | always @(posedge clock) begin 59 | addr_is_IO <= addr_is_IO_raw; 60 | end 61 | 62 | endmodule 63 | 64 | -------------------------------------------------------------------------------- /Parts/Arbiters/Priority_Selector.v: -------------------------------------------------------------------------------- 1 | 2 | // Priority Selector, where each selector bit brings out its corresponding 3 | // data word to the output, but the selector bits are first filtered through 4 | // a Priority Arbiter. Thus, the highest priority selector bit wins. 5 | // Bit 0 has highest priority, selecting the lowest (zeroth) word. 6 | 7 | // This implementation has a log depth on the datapath instead of the linear 8 | // depth of a chain of multiplexers. However, there is a linear depth 9 | // carry-chain implicit in the negation inside the Priority_Arbiter, which 10 | // should get either optimized away, or mapped to fast carry-chain hardware. 11 | 12 | // Henry Wong reports that Quartus destroys plain trees of multiplexers, 13 | // reverting them to linear chains. 14 | 15 | // You may want to substitute a structural priority arbiter if that allows 16 | // a better logic optimization. 17 | 18 | `default_nettype none 19 | 20 | module Priority_Selector 21 | #( 22 | parameter WORD_WIDTH = 0, 23 | parameter WORD_COUNT = 0 24 | ) 25 | ( 26 | input wire [WORD_COUNT-1:0] selectors, 27 | input wire [(WORD_COUNT*WORD_WIDTH)-1:0] in, 28 | output wire [WORD_WIDTH-1:0] out 29 | ); 30 | 31 | // -------------------------------------------------------------------- 32 | 33 | wire [WORD_COUNT-1:0] one_hot_selector; 34 | 35 | Priority_Arbiter 36 | #( 37 | .WORD_WIDTH (WORD_COUNT) 38 | ) 39 | Selector_Filter 40 | ( 41 | .requests (selectors) , 42 | .grant (one_hot_selector) 43 | ); 44 | 45 | // -------------------------------------------------------------------- 46 | 47 | One_Hot_Mux 48 | #( 49 | .WORD_WIDTH (WORD_WIDTH), 50 | .WORD_COUNT (WORD_COUNT) 51 | ) 52 | Output_Filter 53 | ( 54 | .selectors (one_hot_selector), 55 | .in (in), 56 | .out (out) 57 | ); 58 | 59 | endmodule 60 | -------------------------------------------------------------------------------- /Tests/Dyadic_Boolean_Operator/test_harness/Dyadic_Boolean_Operator_test_harness.v: -------------------------------------------------------------------------------- 1 | 2 | module Dyadic_Boolean_Operator_test_harness 3 | #( 4 | parameter WORD_WIDTH = 36 5 | ) 6 | ( 7 | input wire clock, 8 | input wire test_op, 9 | input wire test_a, 10 | input wire test_b, 11 | output wire test_o 12 | ); 13 | 14 | localparam OP_WIDTH = 4; 15 | 16 | // -------------------------------------------------------------------- 17 | 18 | wire [OP_WIDTH-1:0] test_op_dut; 19 | wire [WORD_WIDTH-1:0] test_a_dut; 20 | wire [WORD_WIDTH-1:0] test_b_dut; 21 | wire [WORD_WIDTH-1:0] test_o_dut; 22 | 23 | Dyadic_Boolean_Operator 24 | #( 25 | .WORD_WIDTH (WORD_WIDTH) 26 | ) 27 | DUT 28 | ( 29 | .op (test_op_dut), 30 | .a (test_a_dut), 31 | .b (test_b_dut), 32 | .o (test_o_dut) 33 | ); 34 | 35 | // -------------------------------------------------------------------- 36 | 37 | harness_input_register 38 | #( 39 | .WIDTH (OP_WIDTH) 40 | ) 41 | op 42 | ( 43 | .clock (clock), 44 | .in (test_op), 45 | .rden (1'b1), 46 | .out (test_op_dut) 47 | ); 48 | 49 | harness_input_register 50 | #( 51 | .WIDTH (WORD_WIDTH) 52 | ) 53 | a 54 | ( 55 | .clock (clock), 56 | .in (test_a), 57 | .rden (1'b1), 58 | .out (test_a_dut) 59 | ); 60 | 61 | harness_input_register 62 | #( 63 | .WIDTH (WORD_WIDTH) 64 | ) 65 | b 66 | ( 67 | .clock (clock), 68 | .in (test_b), 69 | .rden (1'b1), 70 | .out (test_b_dut) 71 | ); 72 | 73 | harness_output_register 74 | #( 75 | .WIDTH (WORD_WIDTH) 76 | ) 77 | o 78 | ( 79 | .clock (clock), 80 | .in (test_o_dut), 81 | .wren (1'b1), 82 | .out (test_o) 83 | ); 84 | 85 | endmodule 86 | 87 | -------------------------------------------------------------------------------- /Octavo/Assembler/Assembler.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python3 2 | 3 | from Parser import Parser 4 | from Commands import Commands 5 | from Data import Data 6 | from Code import Code 7 | from Resolver import Resolver 8 | from Configuration import Configuration 9 | from Generator import Generator 10 | from Operators import Operators 11 | 12 | from sys import argv 13 | 14 | if __name__ == "__main__": 15 | operators = Operators() 16 | configuration = Configuration() 17 | data = Data(configuration) 18 | code = Code(data, configuration, operators) 19 | commands = Commands(data, code) 20 | parser = Parser(commands) 21 | parser.parse_file(argv[1]) 22 | # Won't need these after Parsing and Allocation. 23 | # So let's enforce that for our own discipline. 24 | # State is carried in Code and Data. 25 | del parser 26 | del commands 27 | print("Parsing and Allocation Done") 28 | 29 | # Dump initial state of code and data 30 | # immediately after Allocation 31 | configuration.filedump("LOG.allocate") 32 | data.filedump("LOG.allocate", append = True) 33 | code.filedump("LOG.allocate", append = True) 34 | 35 | resolver = Resolver(data, code, configuration) 36 | resolver.resolve() 37 | print("Resolution Done") 38 | 39 | # Dump state of code and data after Resolution 40 | # use gvimdiff (or your tool of choice) to see the differences 41 | # There should be no remaining strings and unset variables 42 | # or instruction operands at this point. 43 | configuration.filedump("LOG.resolve") 44 | data.filedump("LOG.resolve", append = True) 45 | code.filedump("LOG.resolve", append = True) 46 | 47 | generator = Generator(data, code, configuration, operators) 48 | generator.generate() 49 | print("Generation done") 50 | 51 | configuration.filedump("LOG.generate") 52 | data.filedump("LOG.generate", append = True) 53 | code.filedump("LOG.generate", append = True) 54 | 55 | print("OK") 56 | 57 | -------------------------------------------------------------------------------- /Parts/Misc/Annuller.v: -------------------------------------------------------------------------------- 1 | 2 | // Annulls a value (gates it to zero) 3 | 4 | // We put something this simple into a module since it conveys intent, 5 | // and avoids an RTL schematic cluttered with a bunch of AND gates. 6 | 7 | // We do this using logic instead of a register synchronous clear 8 | // since it might not be as portable, nor synthesize as well. 9 | 10 | // See http://www.altera.com/literature/hb/qts/qts_qii51007.pdf (page 14-49): 11 | 12 | // // Creating many registers with different sload and sclr signals can make 13 | // // packing the registers into LABs difficult for the Quartus II Fitter 14 | // // because the sclr and sload signals are LAB-wide signals. In addition, 15 | // // using the LAB-wide sload signal prevents the Fitter from packing 16 | // // registers using the quick feedback path in the device architecture, 17 | // // which means that some registers cannot be packed with other logic. 18 | 19 | // // Synthesis tools typically restrict use of sload and sclr signals to 20 | // // cases in which there are enough registers with common signals to allow 21 | // // good LAB packing. Using the look-up table (LUT) to implement the signals 22 | // // is always more flexible if it is available. Because different device 23 | // // families offer different numbers of control signals, inference of these 24 | // // signals is also device-specific. For example, because Stratix II devices 25 | // // have more flexibility than Stratix devices with respect to secondary 26 | // // control signals, synthesis tools might infer more sload and sclr signals 27 | // // for Stratix II devices. 28 | 29 | `default_nettype none 30 | 31 | module Annuller 32 | #( 33 | parameter WORD_WIDTH = 0 34 | ) 35 | ( 36 | input wire annul, 37 | input wire [WORD_WIDTH-1:0] in, 38 | output reg [WORD_WIDTH-1:0] out 39 | ); 40 | 41 | localparam ZERO = {WORD_WIDTH{1'b0}}; 42 | 43 | initial begin 44 | out = ZERO; 45 | end 46 | 47 | always @(*) begin 48 | out = (annul == 1'b1) ? ZERO : in; 49 | end 50 | 51 | endmodule 52 | 53 | -------------------------------------------------------------------------------- /Parts/NoC/skid_buffer_datapath.v: -------------------------------------------------------------------------------- 1 | 2 | // Skid Buffer Datapath 3 | 4 | // Feed the data_out register either from the data_in, or a buffered copy of 5 | // data_in. Write to registers only if enabled by control. 6 | 7 | // Funneling into a single data_out register rather than selecting between two 8 | // equal output registers avoids a mux after registers, fed by two data 9 | // streams (thus more routing and delay). A single output register also 10 | // retimes more easily, without having to figure out ahead of time if the 11 | // logic allows it. 12 | 13 | `default_nettype none 14 | 15 | module skid_buffer_datapath 16 | #( 17 | parameter WORD_WIDTH = 0 18 | ) 19 | ( 20 | input wire clock, 21 | 22 | // Data 23 | input wire [WORD_WIDTH-1:0] data_in, 24 | output reg [WORD_WIDTH-1:0] data_out, 25 | 26 | // Control 27 | input wire data_out_wren, 28 | input wire data_buffer_wren, 29 | input wire use_buffered_data 30 | ); 31 | 32 | // -------------------------------------------------------------------------- 33 | 34 | localparam WORD_ZERO = {WORD_WIDTH{1'b0}}; 35 | 36 | initial begin 37 | data_out = WORD_ZERO; 38 | end 39 | 40 | // -------------------------------------------------------------------------- 41 | // Set-up the default values to match the "empty" state of the skid buffer, so 42 | // the first data_in to arrive ends up in the data_out by default. We don't 43 | // have to worry about state, just pass the data through unless told 44 | // otherwise. 45 | 46 | reg [WORD_WIDTH-1:0] data_buffer = WORD_ZERO; 47 | reg [WORD_WIDTH-1:0] selected_data = WORD_ZERO; 48 | 49 | always @(*) begin 50 | selected_data = (use_buffered_data == 1'b1) ? data_buffer : data_in; 51 | end 52 | 53 | always @(posedge clock) begin 54 | data_buffer <= (data_buffer_wren == 1'b1) ? data_in : data_buffer; 55 | data_out <= (data_out_wren == 1'b1) ? selected_data : data_out; 56 | end 57 | 58 | endmodule 59 | 60 | -------------------------------------------------------------------------------- /Parts/Multithreading/Thread_Number.v: -------------------------------------------------------------------------------- 1 | 2 | // Round-robin thread number counter. 3 | // Outputs both current and next thread. 4 | // Use this to multiplex a resource across threads. 5 | // Set to appropriate initial thread value depending on location in pipeline. 6 | 7 | // This is the kind of resource that gets optimized a lot and reduced to 8 | // a single instance. This causes artificial critical paths. You will want to 9 | // preserve individual instances either through netlist logical partitioning 10 | // or via source code directives at the module instance. 11 | 12 | `default_nettype none 13 | 14 | module Thread_Number 15 | #( 16 | parameter INITIAL_THREAD = 0, 17 | parameter THREAD_COUNT = 0, 18 | parameter THREAD_COUNT_WIDTH = 0 // clog2(THREAD_COUNT) 19 | ) 20 | ( 21 | input wire clock, 22 | output wire [THREAD_COUNT_WIDTH-1:0] current_thread, 23 | output wire [THREAD_COUNT_WIDTH-1:0] next_thread 24 | ); 25 | 26 | // -------------------------------------------------------------------------- 27 | 28 | localparam ZERO = {THREAD_COUNT_WIDTH{1'b0}}; 29 | localparam LAST_THREAD = THREAD_COUNT - 1; 30 | 31 | reg last_thread = 1'b0; 32 | 33 | always @(*) begin 34 | // Doing it this way to avoid an adder/subtracter comparator. 35 | last_thread = (current_thread == LAST_THREAD [THREAD_COUNT_WIDTH-1:0]); 36 | end 37 | 38 | // -------------------------------------------------------------------------- 39 | 40 | UpDown_Counter 41 | #( 42 | .WORD_WIDTH (THREAD_COUNT_WIDTH), 43 | .INITIAL_COUNT (INITIAL_THREAD) 44 | ) 45 | Thread 46 | ( 47 | .clock (clock), 48 | .up_down (1'b1), // 1/0 up/down 49 | .run (1'b1), // counts one step if set 50 | .wren (last_thread), // Write overrules count 51 | .write_data (ZERO), 52 | .count (current_thread), 53 | .next_count (next_thread) 54 | ); 55 | 56 | endmodule 57 | 58 | -------------------------------------------------------------------------------- /Octavo/Assembler/archive/memory_map.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | 3 | "Serves as repository and documentation of the memory map of Octavo. Use the names as file extensions." 4 | 5 | mem_map = { 6 | # Data memory 7 | "A": {"Origin":0, "Depth":1024, 8 | "PO_INC_base":1018, "PO_INC_count":2, 9 | "IO_base":1020, "IO_count":4}, 10 | "B": {"Origin":1024, "Depth":1024, 11 | "PO_INC_base":1018, "PO_INC_count":2, 12 | "IO_base":1020, "IO_count":4}, 13 | # Instruction memory 14 | "I": {"Origin":2048, "Depth":1024}, 15 | 16 | # High memory is write only. Place controls and write indirections there. 17 | "H": {"Origin":3072, "Depth":1024, 18 | "PO_INC_base":4093, "PO_INC_count":2}, 19 | # Default Offsets, alongside in same words at operand positions 20 | "DDO": {"Origin":3073, "Depth":1, "bit_offset":20}, 21 | "ADO": {"Origin":3073, "Depth":1, "bit_offset":10}, 22 | "BDO": {"Origin":3073, "Depth":1, "bit_offset":0}, 23 | # Programmed Offsets, alongside in same words at operand positions 24 | "DPO": {"Origin":3075, "Depth":1, "bit_offset":20}, 25 | "APO": {"Origin":3075, "Depth":1, "bit_offset":10}, 26 | "BPO": {"Origin":3075, "Depth":1, "bit_offset":0}, 27 | # Increments, alongside in same words at operand positions, but shifted above PO 28 | "DIN": {"Origin":3075, "Depth":1, "bit_offset":34}, 29 | "AIN": {"Origin":3075, "Depth":1, "bit_offset":33}, 30 | "BIN": {"Origin":3075, "Depth":1, "bit_offset":32}, 31 | 32 | # Branch Origins 33 | "BO": {"Origin":3082, "Depth":1, "bit_offset":0}, 34 | # Branch Destinations 35 | "BD": {"Origin":3082, "Depth":1, "bit_offset":10}, 36 | # Branch Conditions 37 | "BC": {"Origin":3082, "Depth":1, "bit_offset":20}, 38 | # Branch Predictions 39 | "BP": {"Origin":3082, "Depth":1, "bit_offset":23}, 40 | # Branch Prediction Enables 41 | "BPE": {"Origin":3082, "Depth":1, "bit_offset":24}, 42 | 43 | # Instruction Decode Memory 44 | "IDM": {"Origin":3100, "Depth":(8*16)}, 45 | 46 | # Memory ends at 4095 47 | } 48 | 49 | -------------------------------------------------------------------------------- /Octavo/Source/Accelerators/Array_Reverse_IO.v: -------------------------------------------------------------------------------- 1 | 2 | // Generates wiring connecting a set of I/Os in such a way as to support array 3 | // reversal. First I/O connects to last, second to penultimate, etc... in 4 | // nested rings. Special case: odd number of I/O pairs means middle set talks 5 | // to itself. 6 | 7 | // Use: write data from post-incr TOP and BOTTOM read pointers into a 2 stage 8 | // queue, then read back in reverse order using post-incr TOP and BOTTOM 9 | // post-incr write pointers: 10 | 11 | // ADD IO, TOP, 0 12 | // ADD IO, BOT, 0 13 | // ADD BOT, IO, 0 14 | // ADD TOP, IO, 0 15 | 16 | // where IO -> stage1 -> stage2 -> IO 17 | // BOT TOP 18 | 19 | // Note the instruction order matters to allow for values to propagate through 20 | // the queue. 21 | 22 | `default_nettype none 23 | 24 | module Array_Reverse_IO 25 | #( 26 | parameter WORD_WIDTH = 36, 27 | parameter LANE_COUNT = 8, 28 | parameter THREAD_COUNT = 8 29 | ) 30 | ( 31 | input wire clock, 32 | input wire [(WORD_WIDTH * LANE_COUNT)-1:0] in, 33 | output reg [(WORD_WIDTH * LANE_COUNT)-1:0] out 34 | ); 35 | 36 | // 8, not 16 stages, since write happen 8 cycles after read. 37 | localparam QUEUE_DEPTH = THREAD_COUNT; 38 | 39 | reg [(WORD_WIDTH * LANE_COUNT)-1:0] queue [QUEUE_DEPTH-1:0]; 40 | 41 | integer i, j, k; 42 | 43 | always @(posedge clock) begin 44 | for (i = 0; i < LANE_COUNT; i = i + 1) begin 45 | queue[0][(i * WORD_WIDTH) +: WORD_WIDTH] <= in[(i * WORD_WIDTH) +: WORD_WIDTH]; 46 | end 47 | end 48 | 49 | always @(posedge clock) begin 50 | for (k = 0; k < QUEUE_DEPTH-1; k = k + 1) begin 51 | queue[k+1] <= queue[k]; 52 | end 53 | end 54 | 55 | always @(*) begin 56 | for (j = LANE_COUNT-1; j >= 0; j = j - 1) begin 57 | out[(j * WORD_WIDTH) +: WORD_WIDTH] <= queue[QUEUE_DEPTH-1][(((LANE_COUNT-1) - j) * WORD_WIDTH) +: WORD_WIDTH]; 58 | end 59 | end 60 | 61 | endmodule 62 | 63 | -------------------------------------------------------------------------------- /Octavo/Tests/Accelerators/Add_Reducer/Add_Reducer_test_bench.v: -------------------------------------------------------------------------------- 1 | 2 | module Add_Reducer_test_bench 3 | #( 4 | parameter WORD_WIDTH = 36, 5 | parameter ADDENDS = 8 // ECL XXX hardcoded, don't touch 6 | ) 7 | ( 8 | output wire [WORD_WIDTH-1:0] reduction 9 | ); 10 | integer cycle; 11 | reg clock; 12 | reg [(ADDENDS * WORD_WIDTH)-1:0] addends; 13 | integer i; 14 | 15 | initial begin 16 | $dumpfile("Add_Reducer_test_bench.vcd"); 17 | $dumpvars; 18 | cycle = 0; 19 | clock = 0; 20 | for (i = 0; i < ADDENDS; i = i + 1) begin 21 | addends[(i * WORD_WIDTH) +: WORD_WIDTH] = 0; 22 | end 23 | `DELAY_CLOCK_CYCLES(200) $finish; 24 | end 25 | 26 | always begin 27 | `DELAY_CLOCK_HALF_PERIOD clock <= ~clock; 28 | end 29 | 30 | always @(posedge clock) begin 31 | cycle <= cycle + 1; 32 | end 33 | 34 | always @(posedge clock) begin 35 | 36 | // reduction: 1 37 | `DELAY_CLOCK_CYCLES(10) 38 | for (i = 0; i < ADDENDS; i = i + 1) begin 39 | addends[(i * WORD_WIDTH) +: WORD_WIDTH] <= 0; 40 | end 41 | 42 | // reduction: 8 43 | `DELAY_CLOCK_CYCLES(10) 44 | for (i = 0; i < ADDENDS; i = i + 1) begin 45 | addends[(i * WORD_WIDTH) +: WORD_WIDTH] <= 1; 46 | end 47 | 48 | // reduction: 28 49 | `DELAY_CLOCK_CYCLES(10) 50 | for (i = 0; i < ADDENDS; i = i + 1) begin 51 | addends[(i * WORD_WIDTH) +: WORD_WIDTH] <= i; 52 | end 53 | 54 | // reduction: 36 55 | `DELAY_CLOCK_CYCLES(10) 56 | for (i = 0; i < ADDENDS; i = i + 1) begin 57 | addends[(i * WORD_WIDTH) +: WORD_WIDTH] <= i+1; 58 | end 59 | 60 | end 61 | 62 | Add_Reducer 63 | #( 64 | .WORD_WIDTH (WORD_WIDTH) 65 | // .ADDENDS (ADDENDS) // ECL XXX hardcoded, don't touch 66 | ) 67 | DUT 68 | ( 69 | .clock (clock), 70 | .addends (addends), 71 | .reduction (reduction) 72 | ); 73 | 74 | endmodule 75 | 76 | -------------------------------------------------------------------------------- /Octavo/Diagrams/triadic.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5c 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 6 8550 3915 9000 4410 11 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 12 | 8730 4050 8730 4410 8820 4320 8820 4140 8730 4050 13 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 14 | 1 1 1.00 30.00 60.00 15 | 8550 4140 8730 4140 16 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 17 | 1 1 1.00 30.00 60.00 18 | 8550 4320 8730 4320 19 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 20 | 1 1 1.00 30.00 60.00 21 | 8820 4230 9000 4230 22 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 23 | 1 1 1.00 30.00 60.00 24 | 8775 3915 8775 4095 25 | -6 26 | 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 27 | 7650 3420 8370 3420 8370 4140 7650 4140 7650 3420 28 | 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 29 | 7650 4320 8370 4320 8370 5040 7650 5040 7650 4320 30 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 31 | 1 1 1.00 30.00 60.00 32 | 7470 4860 7650 4860 33 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 34 | 1 1 1.00 30.00 60.00 35 | 7470 3600 7650 3600 36 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 37 | 1 1 1.00 30.00 60.00 38 | 7470 3960 7650 3960 39 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 40 | 1 1 1.00 30.00 60.00 41 | 7470 4500 7650 4500 42 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 43 | 8370 3780 8550 3780 8550 4140 44 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 45 | 8370 4680 8550 4680 8550 4320 46 | 2 2 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 5 47 | 7245 3105 9180 3105 9180 5130 7245 5130 7245 3105 48 | 4 0 0 50 -1 0 12 0.0000 4 135 105 7335 4005 y\001 49 | 4 0 0 50 -1 0 12 0.0000 4 90 105 7335 3645 x\001 50 | 4 0 0 50 -1 0 12 0.0000 4 90 90 8730 3870 z\001 51 | 4 0 0 50 -1 0 12 0.0000 4 90 105 9000 4275 o\001 52 | 4 0 0 50 -1 0 12 0.0000 4 90 105 7335 4545 x\001 53 | 4 0 0 50 -1 0 12 0.0000 4 135 105 7335 4905 y\001 54 | 4 0 0 50 -1 0 12 0.0000 4 135 510 7740 4635 UDO2\001 55 | 4 0 0 50 -1 0 12 0.0000 4 135 510 7740 3735 UDO1\001 56 | 4 0 0 50 -1 0 12 0.0000 4 180 570 8505 3330 f(x,y,z)\001 57 | 4 0 0 50 -1 0 12 0.0000 4 180 480 7785 3960 g(x,y)\001 58 | 4 0 0 50 -1 0 12 0.0000 4 180 480 7785 4860 h(x,y)\001 59 | 4 0 0 50 -1 0 12 0.0000 4 135 390 7335 3330 UTO\001 60 | -------------------------------------------------------------------------------- /Octavo/Source/IO_Active.v: -------------------------------------------------------------------------------- 1 | 2 | // Generates the "active" signal for each I/O port, based on the address of 3 | // the selected I/O port, if enabled also. 4 | 5 | // This is the read or write enable (rden or wren) 6 | 7 | `default_nettype none 8 | 9 | module IO_Active 10 | #( 11 | parameter ADDR_WIDTH = 0, 12 | parameter PORT_COUNT = 0, 13 | parameter PORT_BASE_ADDR = 0, 14 | parameter PORT_ADDR_WIDTH = 0 15 | ) 16 | ( 17 | input wire enable, 18 | // Interface is ADDR_WIDTH to avoid having the 19 | // enclosing module have to care about the I/O 20 | // address range. 21 | // verilator lint_off UNUSED 22 | input wire [ADDR_WIDTH-1:0] addr, 23 | // verilator lint_on UNUSED 24 | output wire [PORT_COUNT-1:0] active 25 | ); 26 | 27 | // -------------------------------------------------------------------- 28 | 29 | wire [PORT_ADDR_WIDTH-1:0] addr_translated; 30 | 31 | Address_Range_Translator 32 | #( 33 | .ADDR_COUNT (PORT_COUNT), 34 | .ADDR_BASE (PORT_BASE_ADDR), 35 | .ADDR_WIDTH (PORT_ADDR_WIDTH), 36 | .REGISTERED (0) 37 | ) 38 | IO_Port 39 | ( 40 | .clock (1'b0), 41 | .raw_address (addr[PORT_ADDR_WIDTH-1:0]), 42 | .translated_address (addr_translated) 43 | ); 44 | 45 | // -------------------------------------------------------------------- 46 | 47 | wire [PORT_COUNT-1:0] active_raw; 48 | 49 | Binary_to_N_Decoder 50 | #( 51 | .BINARY_WIDTH (PORT_ADDR_WIDTH), 52 | .OUTPUT_WIDTH (PORT_COUNT) 53 | ) 54 | Port_Active 55 | ( 56 | .in (addr_translated), 57 | .out (active_raw) 58 | ); 59 | 60 | // -------------------------------------------------------------------- 61 | 62 | Annuller 63 | #( 64 | .WORD_WIDTH (PORT_COUNT) 65 | ) 66 | active_enable 67 | ( 68 | .annul (enable == 1'b0), 69 | .in (active_raw), 70 | .out (active) 71 | ); 72 | 73 | 74 | endmodule 75 | 76 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-s/LOG/LOG.compile: -------------------------------------------------------------------------------- 1 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o test_bench.o ../test_bench.cpp 2 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o verilated.o /usr/local/share/verilator/include/verilated.cpp 3 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o verilated_vcd_c.o /usr/local/share/verilator/include/verilated_vcd_c.cpp 4 | /usr/bin/perl /usr/local/share/verilator/bin/verilator_includer -DVL_INCLUDE_OPT=include VDUT.cpp VDUT_Branch_Module__pi65.cpp VDUT_Dyadic_Boolean_Operator__W24.cpp > VDUT__ALLcls.cpp 5 | /usr/bin/perl /usr/local/share/verilator/bin/verilator_includer -DVL_INCLUDE_OPT=include VDUT__Trace.cpp VDUT__Syms.cpp VDUT__Trace__Slow.cpp > VDUT__ALLsup.cpp 6 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o VDUT__ALLcls.o VDUT__ALLcls.cpp 7 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o VDUT__ALLsup.o VDUT__ALLsup.cpp 8 | Archiving VDUT__ALL.a ... 9 | ar r VDUT__ALL.a VDUT__ALLcls.o VDUT__ALLsup.o 10 | ar: creating VDUT__ALL.a 11 | ranlib VDUT__ALL.a 12 | g++ test_bench.o verilated.o verilated_vcd_c.o VDUT__ALL.a -o VDUT -lm -lstdc++ 13 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-arrays/LOG/LOG.compile: -------------------------------------------------------------------------------- 1 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o test_bench.o ../test_bench.cpp 2 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o verilated.o /usr/local/share/verilator/include/verilated.cpp 3 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o verilated_vcd_c.o /usr/local/share/verilator/include/verilated_vcd_c.cpp 4 | /usr/bin/perl /usr/local/share/verilator/bin/verilator_includer -DVL_INCLUDE_OPT=include VDUT.cpp VDUT_Branch_Module__pi59.cpp VDUT_Dyadic_Boolean_Operator__W24.cpp > VDUT__ALLcls.cpp 5 | /usr/bin/perl /usr/local/share/verilator/bin/verilator_includer -DVL_INCLUDE_OPT=include VDUT__Trace.cpp VDUT__Syms.cpp VDUT__Trace__Slow.cpp > VDUT__ALLsup.cpp 6 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o VDUT__ALLcls.o VDUT__ALLcls.cpp 7 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o VDUT__ALLsup.o VDUT__ALLsup.cpp 8 | Archiving VDUT__ALL.a ... 9 | ar r VDUT__ALL.a VDUT__ALLcls.o VDUT__ALLsup.o 10 | ar: creating VDUT__ALL.a 11 | ranlib VDUT__ALL.a 12 | g++ test_bench.o verilated.o verilated_vcd_c.o VDUT__ALL.a -o VDUT -lm -lstdc++ 13 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/array-reverse-3/LOG/LOG.compile: -------------------------------------------------------------------------------- 1 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o test_bench.o ../test_bench.cpp 2 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o verilated.o /usr/local/share/verilator/include/verilated.cpp 3 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o verilated_vcd_c.o /usr/local/share/verilator/include/verilated_vcd_c.cpp 4 | /usr/bin/perl /usr/local/share/verilator/bin/verilator_includer -DVL_INCLUDE_OPT=include VDUT.cpp VDUT_Branch_Module__pi59.cpp VDUT_Dyadic_Boolean_Operator__W24.cpp > VDUT__ALLcls.cpp 5 | /usr/bin/perl /usr/local/share/verilator/bin/verilator_includer -DVL_INCLUDE_OPT=include VDUT__Trace.cpp VDUT__Syms.cpp VDUT__Trace__Slow.cpp > VDUT__ALLsup.cpp 6 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o VDUT__ALLcls.o VDUT__ALLcls.cpp 7 | g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVL_PRINTF=printf -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TRACE=1 -Wno-sign-compare -Wno-uninitialized -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Wno-shadow -c -o VDUT__ALLsup.o VDUT__ALLsup.cpp 8 | Archiving VDUT__ALL.a ... 9 | ar r VDUT__ALL.a VDUT__ALLcls.o VDUT__ALLsup.o 10 | ar: creating VDUT__ALL.a 11 | ranlib VDUT__ALL.a 12 | g++ test_bench.o verilated.o verilated_vcd_c.o VDUT__ALL.a -o VDUT -lm -lstdc++ 2>&1 | c++filt 13 | -------------------------------------------------------------------------------- /Parts/NoC/Master_AXI_Sequencer_Read.v: -------------------------------------------------------------------------------- 1 | 2 | // Master AXI Read Sequencer 3 | 4 | // The sequencer enables the read address and read data AXI transactions in 5 | // turn, as the AXI and system interfaces complete their parts. 6 | 7 | // A transaction is started by raising and holding the enable signal until the 8 | // corresponding done signal is also raised, then both drop. (AXI ready/valid 9 | // handshake) 10 | 11 | module Master_AXI_Sequencer_Read 12 | // No parameters 13 | ( 14 | input wire clock, 15 | 16 | // AXI Address Read 17 | output reg ar_control_enable, 18 | input wire ar_control_done, 19 | 20 | // AXI Data Read 21 | output reg r_control_enable, 22 | input wire r_control_done 23 | ); 24 | 25 | // -------------------------------------------------------------------------- 26 | // States for AXI reads 27 | 28 | localparam STATE_BITS = 1; 29 | 30 | localparam [STATE_BITS-1:0] DO_ADDR = 'd0; // Doing the address transaction 31 | localparam [STATE_BITS-1:0] DO_DATA = 'd1; // Doing the data transaction 32 | 33 | reg [STATE_BITS-1:0] state = DO_ADDR; 34 | reg [STATE_BITS-1:0] state_next = DO_ADDR; 35 | 36 | // -------------------------------------------------------------------------- 37 | // Enable the transactions based on the states 38 | 39 | always @(*) begin 40 | ar_control_enable = (state == DO_ADDR); 41 | r_control_enable = (state == DO_DATA); 42 | end 43 | 44 | // -------------------------------------------------------------------------- 45 | // Describe the conditions which affect transactions (after being enabled) 46 | 47 | reg ar_done = 1'b0; 48 | reg r_done = 1'b0; 49 | 50 | always @(*) begin 51 | ar_done = (state == DO_ADDR) && (ar_control_done == 1'b1); 52 | r_done = (state == DO_DATA) && (r_control_done == 1'b1); 53 | end 54 | 55 | // -------------------------------------------------------------------------- 56 | // Do the state transitions 57 | 58 | always @(*) begin 59 | state_next = (ar_done == 1'b1) ? DO_DATA : state; 60 | state_next = (r_done == 1'b1) ? DO_ADDR : state_next; 61 | end 62 | 63 | always @(posedge clock) begin 64 | state <= state_next; 65 | end 66 | 67 | endmodule 68 | 69 | -------------------------------------------------------------------------------- /Octavo/Tests/Address_Decoders/test_bench/Address_Decoders_test_bench.v: -------------------------------------------------------------------------------- 1 | 2 | module Address_Decoders_test_bench 3 | #( 4 | parameter WORD_WIDTH = 36 5 | ) 6 | ( 7 | ); 8 | 9 | // -------------------------------------------------------------------- 10 | 11 | integer cycle; 12 | reg clock; 13 | 14 | reg [WORD_WIDTH-1:0] base_addr; 15 | reg [WORD_WIDTH-1:0] bound_addr; 16 | reg [WORD_WIDTH-1:0] addr; 17 | 18 | reg hit_static; 19 | reg hit_arithm; 20 | reg hit_struct; 21 | 22 | initial begin 23 | $dumpfile("Address_Decoders_test_bench.vcd"); 24 | //$dumpvars(0); 25 | cycle = 0; 26 | clock = 0; 27 | base_addr = 'd557; 28 | bound_addr = 'd666; 29 | addr = 'd0; 30 | `DELAY_CLOCK_CYCLES(1024) $finish; 31 | end 32 | 33 | always @(*) begin 34 | `DELAY_CLOCK_HALF_PERIOD clock <= ~clock; 35 | end 36 | 37 | always @(posedge clock) begin 38 | cycle <= cycle + 1; 39 | end 40 | 41 | always @(posedge clock) begin 42 | `DELAY_CLOCK_CYCLES(1); 43 | addr = addr + 'd1; 44 | end 45 | 46 | // -------------------------------------------------------------------- 47 | 48 | Address_Decoder_Static 49 | #( 50 | .ADDR_WIDTH (WORD_WIDTH), 51 | .ADDR_BASE (base_addr), 52 | .ADDR_BOUND (bound_addr) 53 | ) 54 | Static 55 | ( 56 | .addr (addr_in), 57 | .hit (hit_static) 58 | ); 59 | 60 | Address_Decoder_Arithmetic 61 | #( 62 | .ADDR_WIDTH (WORD_WIDTH) 63 | ) 64 | Arithm 65 | ( 66 | .base_addr (base_addr), 67 | .bound_addr (bound_addr), 68 | .addr (addr_in), 69 | .hit (hit_arithm) 70 | ); 71 | 72 | Address_Decoder_Arithmetic_Structural 73 | #( 74 | .ADDR_WIDTH (WORD_WIDTH) 75 | ) 76 | Struct 77 | ( 78 | .base_addr (base_addr), 79 | .bound_addr (bound_addr), 80 | .addr (addr_in), 81 | .hit (hit_struct) 82 | ); 83 | 84 | endmodule 85 | 86 | -------------------------------------------------------------------------------- /Parts/TestHarness/harness_example.v: -------------------------------------------------------------------------------- 1 | 2 | `default_nettype none 3 | 4 | module harness_example 5 | #( 6 | parameter WORD_WIDTH = 36, 7 | parameter ADDR_WIDTH = 24 8 | ) 9 | ( 10 | input wire clock, 11 | input wire test_in, 12 | output wire test_out, 13 | 14 | // These are only here so the "input" signal are used 15 | // in this example. Normally not here, and sent to 16 | // the DUT. 17 | output reg [WORD_WIDTH-1:0] word_out, 18 | output reg [ADDR_WIDTH-1:0] addr_out 19 | ); 20 | 21 | // -------------------------------------------------------------------- 22 | 23 | localparam INPUT_WIDTH = WORD_WIDTH + ADDR_WIDTH; 24 | localparam OUTPUT_WIDTH = WORD_WIDTH + ADDR_WIDTH; 25 | 26 | wire [INPUT_WIDTH-1:0] test_input; 27 | reg [OUTPUT_WIDTH-1:0] test_output; 28 | 29 | // -------------------------------------------------------------------- 30 | 31 | localparam WORD_ZERO = {WORD_WIDTH{1'b0}}; 32 | localparam ADDR_ZERO = {ADDR_WIDTH{1'b0}}; 33 | 34 | reg [WORD_WIDTH-1:0] some_word_input = WORD_ZERO; 35 | reg [ADDR_WIDTH-1:0] some_addr_input = ADDR_ZERO; 36 | 37 | reg [WORD_WIDTH-1:0] some_word_output = WORD_ZERO; 38 | reg [ADDR_WIDTH-1:0] some_addr_output = ADDR_ZERO; 39 | 40 | always @(*) begin 41 | {some_word_input, some_addr_input} = test_input; 42 | test_output = {some_word_output, some_addr_output}; 43 | end 44 | 45 | // Only for this example, so signals are used. 46 | always @(*) begin 47 | word_out = some_word_input; 48 | addr_out = some_addr_input; 49 | end 50 | 51 | // -------------------------------------------------------------------- 52 | // Test Harness Registers 53 | 54 | harness_input_register 55 | #( 56 | .WIDTH (INPUT_WIDTH) 57 | ) 58 | harness_in 59 | ( 60 | .clock (clock), 61 | .in (test_in), 62 | .rden (1'b1), 63 | .out (test_input) 64 | ); 65 | 66 | harness_output_register 67 | #( 68 | .WIDTH (OUTPUT_WIDTH) 69 | ) 70 | harness_out 71 | ( 72 | .clock (clock), 73 | .in (test_output), 74 | .wren (1'b1), 75 | .out (test_out) 76 | ); 77 | 78 | endmodule 79 | 80 | -------------------------------------------------------------------------------- /Octavo/Tests/Address_Decoders/test_harness/Address_Decoders_test_harness.v: -------------------------------------------------------------------------------- 1 | 2 | module Address_Decoders_test_harness 3 | #( 4 | parameter WORD_WIDTH = 36 5 | ) 6 | ( 7 | input wire clock, 8 | input wire in, 9 | output wire out 10 | ); 11 | 12 | // -------------------------------------------------------------------- 13 | // -------------------------------------------------------------------- 14 | 15 | // We can only do one decoder at a time since we can't partition them, and 16 | // that makes measuring logic usage difficult. 17 | 18 | localparam [WORD_WIDTH-1:0] BASE = 'd567; 19 | localparam [WORD_WIDTH-1:0] BOUND = 'd666; 20 | 21 | wire [WORD_WIDTH-1:0] addr_in; 22 | 23 | wire hit; 24 | 25 | Address_Decoder_Static 26 | #( 27 | .ADDR_WIDTH (WORD_WIDTH), 28 | .ADDR_BASE (BASE), 29 | .ADDR_BOUND (BOUND) 30 | ) 31 | Static 32 | ( 33 | .addr (addr_in), 34 | .hit (hit) 35 | ); 36 | 37 | // Address_Decoder_Arithmetic 38 | // #( 39 | // .ADDR_WIDTH (WORD_WIDTH) 40 | // ) 41 | // Arith 42 | // ( 43 | // .base_addr (BASE), 44 | // .bound_addr (BOUND), 45 | // .addr (addr_in), 46 | // .hit (hit) 47 | // ); 48 | 49 | // Address_Decoder_Arithmetic_Structural 50 | // #( 51 | // .ADDR_WIDTH (WORD_WIDTH) 52 | // ) 53 | // Struct 54 | // ( 55 | // .base_addr (BASE), 56 | // .bound_addr (BOUND), 57 | // .addr (addr_in), 58 | // .hit (hit) 59 | // ); 60 | 61 | // -------------------------------------------------------------------- 62 | // -------------------------------------------------------------------- 63 | 64 | // Tie-off and register inputs and outputs to get a valid timing analysis. 65 | 66 | harness_input_register 67 | #( 68 | .WIDTH (WORD_WIDTH) 69 | ) 70 | i 71 | ( 72 | .clock (clock), 73 | .in (in), 74 | .rden (1'b1), 75 | .out ({addr_in}) 76 | ); 77 | 78 | 79 | harness_output_register 80 | #( 81 | .WIDTH (1) 82 | ) 83 | o 84 | ( 85 | .clock (clock), 86 | .in ({hit}), 87 | .wren (1'b1), 88 | .out (out) 89 | ); 90 | 91 | endmodule 92 | 93 | -------------------------------------------------------------------------------- /Parts/Address_Decode/Address_Splitter.v: -------------------------------------------------------------------------------- 1 | 2 | // Address Splitter 3 | 4 | // Splits the D address operand into DA and DB, depending on split control 5 | // bit. 6 | 7 | // If unsplit, then they are both D, addressing the entire write address 8 | // space. Later address decode logic will typically only write-enable the A or 9 | // B memory exclusively, else we would duplicate the written data into both. 10 | 11 | // If split, then DA/DB each address a range at the beginning of the A and 12 | // B memories as mapped in the write address space. That range will be half of 13 | // the address width of the full D address, extended to the full width of 14 | // D with the upper bits set to the upper bits of the base address of A and B. 15 | 16 | // The base address of A is assumed to be zero. That of B is higher, and 17 | // a parameter. 18 | 19 | // *** THE NUMBER OF D ADDRESS BITS MUST BE EVEN *** 20 | 21 | `default_nettype none 22 | 23 | module Address_Splitter 24 | #( 25 | parameter ADDR_WIDTH = 0, 26 | parameter DB_BASE_ADDR = 0 27 | ) 28 | ( 29 | input wire clock, 30 | input wire split, 31 | input wire [ADDR_WIDTH-1:0] D, 32 | output reg [ADDR_WIDTH-1:0] DA, 33 | output reg [ADDR_WIDTH-1:0] DB 34 | ); 35 | 36 | // -------------------------------------------------------------------- 37 | 38 | initial begin 39 | DA = 0; 40 | DB = 0; 41 | end 42 | 43 | // -------------------------------------------------------------------- 44 | 45 | localparam ADDR_WIDTH_SPLIT = ADDR_WIDTH / 2; 46 | localparam DA_UPPER_BITS = {ADDR_WIDTH_SPLIT{1'b0}}; 47 | localparam DB_UPPER_BITS = DB_BASE_ADDR [ADDR_WIDTH-1:ADDR_WIDTH_SPLIT]; 48 | 49 | // -------------------------------------------------------------------- 50 | 51 | reg [ADDR_WIDTH_SPLIT-1:0] DA_LOWER_BITS = 0; 52 | reg [ADDR_WIDTH_SPLIT-1:0] DB_LOWER_BITS = 0; 53 | 54 | always @(*) begin 55 | {DA_LOWER_BITS,DB_LOWER_BITS} = D; 56 | end 57 | 58 | // -------------------------------------------------------------------- 59 | 60 | always @(posedge clock) begin 61 | DA <= (split == 1'b1) ? {DA_UPPER_BITS,DA_LOWER_BITS} : D; 62 | DB <= (split == 1'b1) ? {DB_UPPER_BITS,DB_LOWER_BITS} : D; 63 | end 64 | 65 | endmodule 66 | 67 | -------------------------------------------------------------------------------- /Octavo/Source/Memory_IO_Predication.v: -------------------------------------------------------------------------------- 1 | 2 | // I/O Predication for one Memory in Octavo Datapath 3 | 4 | `default_nettype none 5 | 6 | module Memory_IO_Predication 7 | #( 8 | parameter ADDR_WIDTH = 0, 9 | parameter PORT_COUNT = 0, 10 | parameter PORT_BASE_ADDR = 0, 11 | parameter PORT_ADDR_WIDTH = 0 12 | ) 13 | ( 14 | input wire clock, 15 | 16 | input wire read_enable, 17 | input wire [ADDR_WIDTH-1:0] read_addr, 18 | input wire write_enable, 19 | input wire [ADDR_WIDTH-1:0] write_addr, 20 | 21 | input wire [PORT_COUNT-1:0] read_EF, 22 | input wire [PORT_COUNT-1:0] write_EF, 23 | output wire read_EF_masked, 24 | output wire write_EF_masked, 25 | 26 | output wire [PORT_COUNT-1:0] io_rden, 27 | output wire read_addr_is_IO, 28 | output wire write_addr_is_IO 29 | ); 30 | 31 | // -------------------------------------------------------------------- 32 | 33 | IO_Read_Predication 34 | #( 35 | .ADDR_WIDTH (ADDR_WIDTH), 36 | .PORT_COUNT (PORT_COUNT), 37 | .PORT_BASE_ADDR (PORT_BASE_ADDR), 38 | .PORT_ADDR_WIDTH (PORT_ADDR_WIDTH) 39 | ) 40 | IORP 41 | ( 42 | .clock (clock), 43 | .enable (read_enable), 44 | .addr (read_addr), 45 | .EmptyFull (read_EF), 46 | .EmptyFull_masked (read_EF_masked), 47 | .io_rden (io_rden), 48 | .addr_is_IO (read_addr_is_IO) 49 | ); 50 | 51 | // -------------------------------------------------------------------- 52 | 53 | IO_Write_Predication 54 | #( 55 | .ADDR_WIDTH (ADDR_WIDTH), 56 | .PORT_COUNT (PORT_COUNT), 57 | .PORT_BASE_ADDR (PORT_BASE_ADDR), 58 | .PORT_ADDR_WIDTH (PORT_ADDR_WIDTH) 59 | ) 60 | IOWP 61 | ( 62 | .clock (clock), 63 | .enable (write_enable), 64 | .addr (write_addr), 65 | .EmptyFull (write_EF), 66 | .EmptyFull_masked (write_EF_masked), 67 | .addr_is_IO (write_addr_is_IO) 68 | ); 69 | 70 | endmodule 71 | 72 | -------------------------------------------------------------------------------- /Octavo/Tests/Accelerators/Sliding_Window/Sliding_Window_test_bench.v: -------------------------------------------------------------------------------- 1 | 2 | module Sliding_Window_test_bench 3 | #( 4 | parameter WORD_WIDTH = 36, 5 | parameter LANES = 8 // ECL XXX hardcoded, don't touch 6 | ) 7 | ( 8 | output wire [(WORD_WIDTH * LANES)-1:0] read_data 9 | ); 10 | integer cycle; 11 | reg clock; 12 | reg in_write; 13 | reg out_read; 14 | reg [(WORD_WIDTH * LANES)-1:0] write_data; 15 | integer i; 16 | 17 | initial begin 18 | $dumpfile("Sliding_Window_test_bench.vcd"); 19 | $dumpvars; 20 | cycle = 0; 21 | clock = 0; 22 | in_write = 0; 23 | out_read = 0; 24 | for (i = 0; i < LANES; i = i + 1) begin 25 | write_data[(i * WORD_WIDTH) +: WORD_WIDTH] = 0; 26 | end 27 | `DELAY_CLOCK_CYCLES(2000) $finish; 28 | end 29 | 30 | always begin 31 | `DELAY_CLOCK_HALF_PERIOD clock <= ~clock; 32 | end 33 | 34 | always @(posedge clock) begin 35 | cycle <= cycle + 1; 36 | end 37 | 38 | always @(posedge clock) begin 39 | 40 | // Load some data 41 | `DELAY_CLOCK_CYCLES(10) 42 | in_write = `HIGH; 43 | out_read = `LOW; 44 | for (i = 0; i < LANES; i = i + 1) begin 45 | write_data[(i * WORD_WIDTH) +: WORD_WIDTH] <= i*2; 46 | end 47 | `DELAY_CLOCK_CYCLES(1) 48 | in_write = `LOW; 49 | out_read = `LOW; 50 | 51 | // Now let's read them out 52 | `DELAY_CLOCK_CYCLES(10) 53 | in_write = `LOW; 54 | out_read = `HIGH; 55 | 56 | // Load some data just as the previous one exhausts. 57 | `DELAY_CLOCK_CYCLES(7) 58 | in_write = `HIGH; 59 | out_read = `HIGH; 60 | for (i = 0; i < LANES; i = i + 1) begin 61 | write_data[(i * WORD_WIDTH) +: WORD_WIDTH] <= i*3; 62 | end 63 | `DELAY_CLOCK_CYCLES(1) 64 | in_write = `LOW; 65 | out_read = `HIGH; 66 | 67 | // Now let's read them all out 68 | `DELAY_CLOCK_CYCLES(20) 69 | in_write = `LOW; 70 | out_read = `HIGH; 71 | 72 | end 73 | 74 | Sliding_Window 75 | #( 76 | .WORD_WIDTH (WORD_WIDTH), 77 | .LANES (LANES) 78 | ) 79 | DUT 80 | ( 81 | .clock (clock), 82 | .in_write (in_write), 83 | .in (write_data), 84 | .out_read (out_read), 85 | .out (read_data) 86 | ); 87 | 88 | endmodule 89 | 90 | -------------------------------------------------------------------------------- /Parts/Arbiters/Round_Robin_Arbiter.v: -------------------------------------------------------------------------------- 1 | 2 | // Returns a single bit set from all set request bits, in a round-robin order 3 | // going from LSB to MSB and back around. Requests can be added or dropped 4 | // on-the-fly, but synchronously. 5 | 6 | `default_nettype none 7 | 8 | module Round_Robin_Arbiter 9 | #( 10 | parameter WORD_WIDTH = 0 11 | ) 12 | ( 13 | input wire clock, 14 | input wire [WORD_WIDTH-1:0] requests, 15 | output reg [WORD_WIDTH-1:0] grant 16 | ); 17 | 18 | localparam ZERO = {WORD_WIDTH{1'b0}}; 19 | 20 | initial begin 21 | grant = ZERO; 22 | end 23 | 24 | // -------------------------------------------------------------------- 25 | 26 | // Grant a request in priority order (LSB has higest priority) 27 | 28 | wire [WORD_WIDTH-1:0] grant_raw; 29 | 30 | Priority_Arbiter 31 | #( 32 | .WORD_WIDTH (WORD_WIDTH) 33 | ) 34 | Raw 35 | ( 36 | .requests (requests), 37 | .grant (grant_raw) 38 | ); 39 | 40 | // -------------------------------------------------------------------- 41 | 42 | // Mask-off all requests of higher priority 43 | // than the request granted in the previous cycle. 44 | 45 | wire [WORD_WIDTH-1:0] mask; 46 | 47 | Thermometer_Mask 48 | #( 49 | .WORD_WIDTH (WORD_WIDTH) 50 | ) 51 | Grant_Mask 52 | ( 53 | .bitvector (grant), 54 | .mask (mask) 55 | ); 56 | 57 | reg [WORD_WIDTH-1:0] requests_masked; 58 | 59 | always @(*) begin 60 | requests_masked = requests & mask; 61 | end 62 | 63 | // -------------------------------------------------------------------- 64 | 65 | // Grant a request in priority order, but from the masked requests 66 | // (equal or lower priority to the request granted last cycle) 67 | 68 | wire [WORD_WIDTH-1:0] grant_masked; 69 | 70 | Priority_Arbiter 71 | #( 72 | .WORD_WIDTH (WORD_WIDTH) 73 | ) 74 | Masked 75 | ( 76 | .requests (requests_masked), 77 | .grant (grant_masked) 78 | ); 79 | 80 | // -------------------------------------------------------------------- 81 | 82 | // If no granted requests remain after masking, then grant from the 83 | // unmasked requests, which starts over granting from the highest (LSB) 84 | // priority. This also resets the mask. And the process begins again. 85 | 86 | always @(posedge clock) begin 87 | grant <= (grant_masked == ZERO) ? grant_raw : grant_masked; 88 | end 89 | 90 | endmodule 91 | 92 | -------------------------------------------------------------------------------- /Parts/NoC/skid_buffer.v: -------------------------------------------------------------------------------- 1 | 2 | // Skid Buffer: decouples two sides of a ready/valid handshake to allow 3 | // back-to-back transfers without a combinational path between sender and 4 | // receiver (or master and slave). 5 | 6 | // A skid-buffer is a degenerate FIFO with only two entries. It is useful 7 | // when you need to pipeline the path between a sender and a receiver for 8 | // concurrency and/or timing, but not to smooth-out data rate mismatches. It 9 | // also only requires two data registers, which at this scale is smaller than 10 | // LUTRAMs or Block RAMs (depending on implementation), and has more freedom 11 | // of placement and routing. 12 | 13 | // This skid buffer assumes AXI behaviour for valid/ready handshakes. 14 | 15 | `default_nettype none 16 | 17 | module skid_buffer 18 | #( 19 | parameter WORD_WIDTH = 0 20 | ) 21 | ( 22 | input wire clock, 23 | 24 | // Slave interface 25 | input wire s_valid, 26 | output wire s_ready, 27 | input wire [WORD_WIDTH-1:0] s_data, 28 | 29 | // Master interface 30 | output wire m_valid, 31 | input wire m_ready, 32 | output wire [WORD_WIDTH-1:0] m_data 33 | ); 34 | 35 | // -------------------------------------------------------------------------- 36 | // The FSM handles the master and slave port handshakes, and provides the 37 | // datapath control signals. 38 | 39 | wire data_out_wren; 40 | wire data_buffer_wren; 41 | wire use_buffered_data; 42 | 43 | skid_buffer_fsm 44 | // No parameters 45 | controlpath 46 | ( 47 | .clock (clock), 48 | 49 | .s_valid (s_valid), 50 | .s_ready (s_ready), 51 | 52 | .m_valid (m_valid), 53 | .m_ready (m_ready), 54 | 55 | .data_out_wren (data_out_wren), 56 | .data_buffer_wren (data_buffer_wren), 57 | .use_buffered_data (use_buffered_data) 58 | 59 | ); 60 | 61 | // -------------------------------------------------------------------------- 62 | // The datapath stores and steers the data. 63 | 64 | skid_buffer_datapath 65 | #( 66 | .WORD_WIDTH (WORD_WIDTH) 67 | ) 68 | datapath 69 | ( 70 | .clock (clock), 71 | 72 | .data_in (s_data), 73 | .data_out (m_data), 74 | 75 | .data_out_wren (data_out_wren), 76 | .data_buffer_wren (data_buffer_wren), 77 | .use_buffered_data (use_buffered_data) 78 | ); 79 | 80 | endmodule 81 | 82 | -------------------------------------------------------------------------------- /Octavo/Tests/Accelerators/Accumulator/Accumulator_test_bench.v: -------------------------------------------------------------------------------- 1 | 2 | module Accumulator_test_bench 3 | #( 4 | parameter WORD_WIDTH = 36, 5 | parameter THREAD_COUNT = 8 6 | ) 7 | ( 8 | output wire [WORD_WIDTH-1:0] total 9 | ); 10 | integer cycle; 11 | reg clock; 12 | reg [WORD_WIDTH-1:0] addend; 13 | reg read_total; 14 | reg write_addend; 15 | 16 | initial begin 17 | $dumpfile("Accumulator_test_bench.vcd"); 18 | $dumpvars(0); 19 | cycle = 0; 20 | clock = 0; 21 | addend = 0; 22 | read_total = 0; 23 | write_addend = 0; 24 | `DELAY_CLOCK_CYCLES(200) $finish; 25 | end 26 | 27 | always @(*) begin 28 | `DELAY_CLOCK_HALF_PERIOD clock <= ~clock; 29 | end 30 | 31 | always @(posedge clock) begin 32 | cycle <= cycle + 1; 33 | end 34 | 35 | always @(posedge clock) begin 36 | 37 | // 0 + 1 = 1, read out 38 | read_total = `HIGH; 39 | write_addend = `HIGH; 40 | addend = 1; 41 | `DELAY_CLOCK_CYCLES(1) 42 | read_total = `LOW; 43 | write_addend = `LOW; 44 | `DELAY_CLOCK_CYCLES((THREAD_COUNT-1)) 45 | 46 | // 0 + 1 + 2 = 3 47 | read_total = `LOW; 48 | write_addend = `HIGH; 49 | addend = 2; 50 | `DELAY_CLOCK_CYCLES(1) 51 | write_addend <= `LOW; 52 | `DELAY_CLOCK_CYCLES((THREAD_COUNT-1)) 53 | 54 | // 0 + 1 + 2 + 3 = 6 55 | read_total = `LOW; 56 | write_addend = `HIGH; 57 | addend = 3; 58 | `DELAY_CLOCK_CYCLES(1) 59 | write_addend <= `LOW; 60 | `DELAY_CLOCK_CYCLES((THREAD_COUNT-1)) 61 | 62 | // 0 + 1 + 2 + 3 + 4 = 10 63 | read_total = `LOW; 64 | write_addend = `HIGH; 65 | addend = 4; 66 | `DELAY_CLOCK_CYCLES(1) 67 | write_addend = `LOW; 68 | `DELAY_CLOCK_CYCLES((THREAD_COUNT-1)) 69 | 70 | // avoids syntax error 71 | read_total = `HIGH; 72 | 73 | end 74 | 75 | Accumulator 76 | #( 77 | .WORD_WIDTH (WORD_WIDTH), 78 | .THREAD_COUNT (THREAD_COUNT) 79 | ) 80 | DUT 81 | ( 82 | .clock (clock), 83 | .write_addend (write_addend), 84 | .addend (addend), 85 | .read_total (read_total), 86 | .total (total) 87 | ); 88 | 89 | endmodule 90 | 91 | -------------------------------------------------------------------------------- /Octavo/Tests/Octavo/test_bench/hailstone-s/test_bench.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Test bench driver. 3 | // Based off Dan Gisselquist's work: http://zipcpu.com/blog/2017/06/21/looking-at-verilator.html 4 | 5 | // General code 6 | #include 7 | #include 8 | 9 | // Specific to the DUT and Verilator 10 | #include "VDUT.h" 11 | #include 12 | #include 13 | 14 | int 15 | main 16 | ( 17 | int argc, 18 | char ** argv 19 | ) 20 | { 21 | int cycles_executed = 0; 22 | int cycles_to_run = 5000; 23 | 24 | // Current simulation time (64-bit unsigned) 25 | vluint64_t main_time = 0; 26 | 27 | // Pass arguments so Verilated code can see them, e.g. $value$plusargs 28 | Verilated::commandArgs(argc, argv); 29 | 30 | // Set debug level, 0 is off, 9 is highest presently used 31 | Verilated::debug(9); 32 | 33 | // Create an instance of our Device Under Test 34 | VDUT *DUT = new VDUT; 35 | 36 | // Setup VCD dump 37 | Verilated::traceEverOn(true); 38 | VerilatedVcdC* vcd = new VerilatedVcdC; 39 | // Trace 99 levels of hierarchy 40 | DUT->trace(vcd, 99); 41 | vcd->open("dump.vcd"); 42 | 43 | // Make sure all state is initialized 44 | DUT->clock = 0; 45 | DUT->eval(); 46 | 47 | // Tick the clock until we are done 48 | while(true) { 49 | DUT->clock = 0; 50 | DUT->eval(); 51 | vcd->dump(main_time); 52 | main_time++; 53 | 54 | DUT->clock = 1; 55 | DUT->eval(); 56 | vcd->dump(main_time); 57 | main_time++; 58 | 59 | cycles_executed++; 60 | 61 | // // Test I/O write handshake, just on the zeroth port on Memory A 62 | // if ((cycles_executed > 100) && (cycles_executed < 200)) 63 | // { 64 | // DUT->io_write_EF_A = 1; 65 | // } 66 | // else 67 | // { 68 | // DUT->io_write_EF_A = 0; 69 | // } 70 | 71 | // When writing to port A, print the output (cut to 32 bits). 72 | 73 | if (DUT->io_wren_A != 0) { 74 | printf("%u: (%#x) %u\n", cycles_executed, DUT->io_wren_A, (DUT->io_write_data_A[1] >> 4) ); 75 | } 76 | 77 | if ( (cycles_executed == cycles_to_run) || (Verilated::gotFinish() == true) ) 78 | { 79 | printf("Simulation terminated normally at cycle %u\n", cycles_executed); 80 | DUT->final(); 81 | vcd->close(); 82 | delete vcd; 83 | vcd = NULL; 84 | delete DUT; 85 | DUT = NULL; 86 | exit(EXIT_SUCCESS); 87 | } 88 | } 89 | 90 | printf("Simulation terminated abnormally. Executable likely corrupted.\n"); 91 | exit(EXIT_FAILURE); 92 | } 93 | 94 | -------------------------------------------------------------------------------- /Parts/ALU/AddSub_Ripple_Carry_NoCarry.v: -------------------------------------------------------------------------------- 1 | 2 | // Adder/subtractor without carry-in/out. 3 | // This allows us to compute +/-A + +/-B without extra logic. 4 | // Should infer to the usual LUT and carry-chain logic. 5 | 6 | // Also generates addition-specific predicates for later comparisons 7 | 8 | `default_nettype none 9 | 10 | module AddSub_Ripple_Carry_NoCarry 11 | #( 12 | parameter WORD_WIDTH = 0 13 | ) 14 | ( 15 | input wire signed [WORD_WIDTH-1:0] A, 16 | input wire A_negative, 17 | input wire signed [WORD_WIDTH-1:0] B, 18 | input wire B_negative, 19 | output reg signed [WORD_WIDTH-1:0] sum, 20 | output reg carry_out, 21 | output reg overflow 22 | ); 23 | 24 | localparam ZERO = {WORD_WIDTH{1'b0}}; 25 | 26 | // -------------------------------------------------------------------- 27 | 28 | wire [WORD_WIDTH-1:0] A_signed; 29 | wire [WORD_WIDTH-1:0] B_signed; 30 | 31 | Inverter 32 | #( 33 | .WORD_WIDTH (WORD_WIDTH) 34 | ) 35 | A_inv 36 | ( 37 | .invert (A_negative), 38 | .in (A), 39 | .out (A_signed) 40 | ); 41 | 42 | Inverter 43 | #( 44 | .WORD_WIDTH (WORD_WIDTH) 45 | ) 46 | B_inv 47 | ( 48 | .invert (B_negative), 49 | .in (B), 50 | .out (B_signed) 51 | ); 52 | 53 | // -------------------------------------------------------------------- 54 | 55 | reg [WORD_WIDTH-1:0] A_negative_ext = ZERO; 56 | reg [WORD_WIDTH-1:0] B_negative_ext = ZERO; 57 | 58 | always @(*) begin 59 | A_negative_ext = {{WORD_WIDTH-1{1'b0}},A_negative}; 60 | B_negative_ext = {{WORD_WIDTH-1{1'b0}},B_negative}; 61 | end 62 | 63 | // -X = (~X)+1 64 | 65 | always @(*) begin 66 | {carry_out,sum} = A_signed + B_signed + A_negative_ext + B_negative_ext; 67 | end 68 | 69 | // -------------------------------------------------------------------- 70 | // Find carry-in into MSB 71 | 72 | wire carry_in; 73 | 74 | Carryin_Calculator 75 | #( 76 | .WORD_WIDTH (1) 77 | ) 78 | MSB_Cin 79 | ( 80 | .A (A_signed[WORD_WIDTH-1]), 81 | .B (B_signed[WORD_WIDTH-1]), 82 | .S (sum [WORD_WIDTH-1]), 83 | .Cin (carry_in) 84 | ); 85 | 86 | // -------------------------------------------------------------------- 87 | 88 | always @(*) begin 89 | overflow = carry_in ^ carry_out; // signed overflow 90 | end 91 | 92 | endmodule 93 | 94 | -------------------------------------------------------------------------------- /Parts/Address_Decode/Address_Range_Decoder_Static.v: -------------------------------------------------------------------------------- 1 | 2 | // A *universal* address decoder. Works for any address range at any starting point. 3 | 4 | // Checks if the address lies between the base and (higher, inclusive) bound of a range. 5 | 6 | // Checks if the input address matches each possible address in the range, 7 | // then outputs the bitwise OR of all these checks. Some boolean algebra 8 | // shows that it will always optimize down to a minimal form: any bits which 9 | // iterate over their entire binary range become boolean "don't care", leaving 10 | // the other bits to do the match. Thus, for aligned power of 2 address 11 | // ranges, we get the minimal NOT-AND-gate decoder. 12 | 13 | // This approach has one caveat: you may have to test, at synthesis time, up 14 | // to all 2^N possible addresses, and store the matches into a vector 2^N bits 15 | // long. This could take a long time and AFAIK, Verilog implementations have 16 | // a maximum vector width of a few million, so this decoder will break for 17 | // address ranges more than 20-23 bits wide. 18 | 19 | // Call it a synthesizer stress-test. ;) 20 | 21 | // Even if your CAD tool can handle huge vectors, because we use an int as 22 | // counter, this decoder cannot be guaranteed to work for address ranges 23 | // exceeding 32 bits. 24 | 25 | // However, this implementation yields the smallest, fastest logic. 26 | 27 | `default_nettype none 28 | 29 | module Address_Range_Decoder_Static 30 | #( 31 | parameter ADDR_WIDTH = 0, 32 | parameter ADDR_BASE = 0, 33 | parameter ADDR_BOUND = 0 34 | ) 35 | ( 36 | input wire enable, 37 | input wire [ADDR_WIDTH-1:0] addr, 38 | output reg hit 39 | ); 40 | 41 | localparam ADDR_COUNT = ADDR_BOUND - ADDR_BASE + 1; 42 | localparam COUNT_ZERO = {ADDR_COUNT{1'b0}}; 43 | 44 | initial begin 45 | hit = 1'b0; 46 | end 47 | 48 | // -------------------------------------------------------------------- 49 | 50 | integer i; 51 | reg [ADDR_COUNT-1:0] per_addr_match = COUNT_ZERO; 52 | 53 | // Check each address in base/bound range for match 54 | always @(*) begin 55 | for(i = ADDR_BASE; i <= ADDR_BOUND; i = i + 1) begin : addr_decode 56 | per_addr_match[i-ADDR_BASE] = (addr == i[ADDR_WIDTH-1:0]); 57 | end 58 | end 59 | 60 | // -------------------------------------------------------------------- 61 | 62 | reg hit_raw = 0; 63 | 64 | // Do any of them match, and are we enabled? 65 | always @(*) begin : is_hit 66 | hit_raw = | per_addr_match; 67 | hit = hit_raw & enable; 68 | end 69 | 70 | endmodule 71 | 72 | -------------------------------------------------------------------------------- /Octavo/Tests/alu_test_bench.v: -------------------------------------------------------------------------------- 1 | `include "params.v" 2 | 3 | module alu_test_bench(); 4 | 5 | reg clock; 6 | reg half_clock; 7 | reg `OPCODE op; 8 | reg `A_WORD A; 9 | reg `B_WORD B; 10 | wire `ALU_WORD R; 11 | wire `OPCODE op_out; 12 | 13 | initial begin 14 | clock = 0; 15 | half_clock = 0; 16 | op = `XOR; 17 | A = 0; 18 | B = 0; 19 | `DELAY_CLOCK_CYCLES(100) $stop; 20 | end 21 | 22 | always begin 23 | `DELAY_CLOCK_HALF_PERIOD clock <= ~clock; 24 | end 25 | 26 | always begin 27 | @(posedge clock) 28 | half_clock <= ~half_clock; 29 | end 30 | 31 | always begin 32 | op <= `XOR; 33 | A <= `A_WORD_WIDTH'hAAAAAAAAA; 34 | B <= `B_WORD_WIDTH'h555555555; 35 | @(posedge clock); 36 | 37 | op <= `AND; 38 | A <= `A_WORD_WIDTH'hAAAAAAAAA; 39 | B <= `B_WORD_WIDTH'h555555555; 40 | @(posedge clock); 41 | 42 | op <= `OR; 43 | A <= `A_WORD_WIDTH'hAAAAAAAAA; 44 | B <= `B_WORD_WIDTH'h555555555; 45 | @(posedge clock); 46 | 47 | op <= `SRL; 48 | A <= `A_WORD_WIDTH'h808080808; 49 | B <= `B_WORD_WIDTH'hFFFFFFFFF; 50 | @(posedge clock); 51 | 52 | op <= `SRA; 53 | A <= `A_WORD_WIDTH'h808080808; 54 | B <= `B_WORD_WIDTH'hFFFFFFFFF; 55 | @(posedge clock); 56 | 57 | op <= `ADD; 58 | A <= `A_WORD_WIDTH'hFFFFFFFFF; 59 | B <= `B_WORD_WIDTH'h000000001; 60 | @(posedge clock); 61 | 62 | op <= `SUB; 63 | A <= `A_WORD_WIDTH'h000000002; 64 | B <= `B_WORD_WIDTH'h000000003; 65 | @(posedge clock); 66 | 67 | op <= `SUB; 68 | A <= `A_WORD_WIDTH'h000000001; 69 | B <= `B_WORD_WIDTH'h000000003; 70 | @(posedge clock); 71 | 72 | op <= `YES; 73 | A <= `A_WORD_WIDTH'h808080808; 74 | B <= `B_WORD_WIDTH'h101010101; 75 | @(posedge clock); 76 | 77 | 78 | op <= `MLO; 79 | A <= `A_WORD_WIDTH'h0000FFFFF; 80 | B <= `B_WORD_WIDTH'h0000FFFFF; 81 | @(posedge clock); 82 | 83 | op <= `MHI; 84 | A <= `A_WORD_WIDTH'h0000FFFFF; 85 | B <= `B_WORD_WIDTH'h0000FFFFF; 86 | @(posedge clock); 87 | end 88 | 89 | alu dut( 90 | .clock(clock), 91 | .half_clock(half_clock), 92 | .op_in(op), 93 | .A(A), 94 | .B(B), 95 | .R(R), 96 | .op_out(op_out) 97 | ); 98 | 99 | endmodule 100 | -------------------------------------------------------------------------------- /Parts/NoC/Master_AXI_Sequencer_Write.v: -------------------------------------------------------------------------------- 1 | 2 | // Master AXI Write Sequencer 3 | 4 | // The sequencer enables the write address, write data, and write response 5 | // AXI transactions in turn, as the AXI and system interfaces complete their 6 | // parts. 7 | 8 | // A transaction is started by raising and holding the enable signal until the 9 | // corresponding done signal is also raised, then both drop. (AXI ready/valid 10 | // handshake) 11 | 12 | module Master_AXI_Sequencer_Write 13 | // No parameters 14 | ( 15 | input wire clock, 16 | 17 | // AXI Address Write 18 | output reg aw_control_enable, 19 | input wire aw_control_done, 20 | 21 | // AXI Data Write 22 | output reg w_control_enable, 23 | input wire w_control_done, 24 | 25 | // AXI Write Response 26 | output reg b_control_enable, 27 | input wire b_control_done 28 | ); 29 | 30 | // -------------------------------------------------------------------------- 31 | // States for AXI writes 32 | 33 | localparam STATE_BITS = 2; 34 | 35 | localparam [STATE_BITS-1:0] DO_ADDR = 'd0; // Doing the address transaction 36 | localparam [STATE_BITS-1:0] DO_DATA = 'd1; // Doing the data transaction 37 | localparam [STATE_BITS-1:0] DO_RESP = 'd2; // Doing the response transaction 38 | 39 | reg [STATE_BITS-1:0] state = DO_ADDR; 40 | reg [STATE_BITS-1:0] state_next = DO_ADDR; 41 | 42 | // -------------------------------------------------------------------------- 43 | // Enable the transactions based on the states 44 | 45 | always @(*) begin 46 | aw_control_enable = (state == DO_ADDR); 47 | w_control_enable = (state == DO_DATA); 48 | b_control_enable = (state == DO_RESP); 49 | end 50 | 51 | // -------------------------------------------------------------------------- 52 | // Describe the conditions which affect transactions (after being enabled) 53 | 54 | reg aw_done = 1'b0; 55 | reg w_done = 1'b0; 56 | reg b_done = 1'b0; 57 | 58 | always @(*) begin 59 | aw_done = (state == DO_ADDR) && (aw_control_done == 1'b1); 60 | w_done = (state == DO_DATA) && (w_control_done == 1'b1); 61 | b_done = (state == DO_RESP) && (b_control_done == 1'b1); 62 | end 63 | 64 | // -------------------------------------------------------------------------- 65 | // Do the state transitions 66 | 67 | always @(*) begin 68 | state_next = (aw_done == 1'b1) ? DO_DATA : state; 69 | state_next = (w_done == 1'b1) ? DO_RESP : state_next; 70 | state_next = (b_done == 1'b1) ? DO_ADDR : state_next; 71 | end 72 | 73 | always @(posedge clock) begin 74 | state <= state_next; 75 | end 76 | 77 | endmodule 78 | 79 | -------------------------------------------------------------------------------- /Octavo/Diagrams/Address_Splitter.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5c 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 6 9045 7560 9405 8100 11 | 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 12 | 9090 7605 9360 7605 9360 8055 9090 8055 9090 7605 13 | 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 14 | 9180 8055 9225 7965 9270 8055 15 | -6 16 | 6 9045 8280 9405 8820 17 | 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 18 | 9090 8325 9360 8325 9360 8775 9090 8775 9090 8325 19 | 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 20 | 9180 8775 9225 8685 9270 8775 21 | -6 22 | 6 8730 7470 8910 8145 23 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 24 | 8730 7508 8730 8138 8910 8003 8910 7643 8730 7508 25 | 4 0 0 50 -1 0 8 0.0000 4 90 75 8775 8010 1\001 26 | 4 0 0 50 -1 0 8 0.0000 4 90 75 8775 7740 0\001 27 | -6 28 | 6 8730 8190 8910 8865 29 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 30 | 8730 8228 8730 8858 8910 8723 8910 8363 8730 8228 31 | 4 0 0 50 -1 0 8 0.0000 4 90 75 8775 8730 1\001 32 | 4 0 0 50 -1 0 8 0.0000 4 90 75 8775 8460 0\001 33 | -6 34 | 6 7515 7875 8505 8055 35 | 4 0 0 50 -1 0 12 0.0000 4 165 900 7515 8010 {000000,D\001 36 | 4 0 0 50 -1 0 6 0.0000 4 75 75 8370 8055 A\001 37 | 4 0 0 50 -1 0 12 0.0000 4 165 90 8415 8010 }\001 38 | -6 39 | 6 7515 8595 8505 8775 40 | 4 0 0 50 -1 0 12 0.0000 4 165 900 7515 8730 {001000,D\001 41 | 4 0 0 50 -1 0 6 0.0000 4 75 75 8370 8775 B\001 42 | 4 0 0 50 -1 0 12 0.0000 4 165 90 8415 8730 }\001 43 | -6 44 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 45 | 1 1 1.00 30.00 60.00 46 | 9090 7830 8910 7830 47 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 48 | 1 1 1.00 30.00 60.00 49 | 9090 8550 8910 8550 50 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 51 | 1 1 1.00 30.00 60.00 52 | 9540 7830 9360 7830 53 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 54 | 1 1 1.00 30.00 60.00 55 | 9540 8550 9360 8550 56 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 57 | 9360 7245 9360 8955 58 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 59 | 1 1 1.00 30.00 60.00 60 | 8730 8415 8550 8415 61 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 62 | 1 1 1.00 30.00 60.00 63 | 8730 8685 8550 8685 64 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 65 | 1 1 1.00 30.00 60.00 66 | 8730 7695 8550 7695 67 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 68 | 1 1 1.00 30.00 60.00 69 | 8730 7965 8550 7965 70 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 71 | 1 1 1.00 30.00 60.00 72 | 8820 8325 8820 8055 73 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 74 | 1 1 1.00 30.00 60.00 75 | 8820 7605 8820 7425 76 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 77 | 8820 7425 8550 7425 78 | 4 0 0 50 -1 0 12 0.0000 4 135 270 9540 7875 DA\001 79 | 4 0 0 50 -1 0 12 0.0000 4 135 270 9540 8595 DB\001 80 | 4 0 0 50 -1 0 12 0.0000 4 135 105 9225 7515 0\001 81 | 4 0 0 50 -1 0 12 0.0000 4 180 360 8100 7470 split\001 82 | 4 0 0 50 -1 0 12 0.0000 4 135 135 8235 7740 D\001 83 | 4 0 0 50 -1 0 12 0.0000 4 135 135 8235 8460 D\001 84 | -------------------------------------------------------------------------------- /Octavo/Diagrams/IO_Ready.fig: -------------------------------------------------------------------------------- 1 | #FIG 3.2 Produced by xfig version 3.2.5c 2 | Landscape 3 | Center 4 | Metric 5 | A4 6 | 100.00 7 | Single 8 | -2 9 | 1200 2 10 | 6 2160 9090 2745 9405 11 | 5 1 0 1 0 -1 0 0 -1 0.000 0 0 0 0 2475.000 9270.000 2475 9135 2610 9270 2475 9405 12 | 2 1 0 1 0 -1 0 0 -1 4.000 0 0 0 0 0 2 13 | 2160 9360 2295 9360 14 | 2 1 0 1 0 -1 0 0 -1 4.000 0 0 0 0 0 2 15 | 2160 9180 2295 9180 16 | 2 1 0 1 0 -1 0 0 -1 0.000 0 1 0 0 0 2 17 | 2295 9135 2295 9405 18 | 2 1 0 1 0 -1 0 0 -1 0.000 0 1 0 0 0 2 19 | 2475 9135 2295 9135 20 | 2 1 0 1 0 -1 0 0 -1 4.000 0 0 0 0 0 2 21 | 2475 9405 2295 9405 22 | 2 1 0 1 0 -1 0 0 -1 4.000 0 0 0 0 0 2 23 | 2745 9270 2610 9270 24 | -6 25 | 6 2160 9540 2745 9855 26 | 6 2160 9540 2745 9855 27 | 5 1 0 1 0 -1 0 0 -1 0.000 0 0 0 0 2475.000 9720.000 2475 9585 2610 9720 2475 9855 28 | 2 1 0 1 0 -1 0 0 -1 4.000 0 0 0 0 0 2 29 | 2160 9810 2295 9810 30 | 2 1 0 1 0 -1 0 0 -1 4.000 0 0 0 0 0 2 31 | 2160 9630 2295 9630 32 | 2 1 0 1 0 -1 0 0 -1 0.000 0 1 0 0 0 2 33 | 2295 9585 2295 9855 34 | 2 1 0 1 0 -1 0 0 -1 0.000 0 1 0 0 0 2 35 | 2475 9585 2295 9585 36 | 2 1 0 1 0 -1 0 0 -1 4.000 0 0 0 0 0 2 37 | 2475 9855 2295 9855 38 | 2 1 0 1 0 -1 0 0 -1 4.000 0 0 0 0 0 2 39 | 2745 9720 2610 9720 40 | -6 41 | 1 3 0 1 0 7 0 0 20 0.000 1 0.0000 2259 9808 28 28 2259 9808 2287 9808 42 | 1 3 0 1 0 7 0 0 20 0.000 1 0.0000 2259 9627 28 28 2259 9627 2287 9627 43 | -6 44 | 6 2745 9315 3330 9630 45 | 5 1 0 1 0 -1 0 0 -1 0.000 0 0 0 0 3060.000 9495.000 3060 9360 3195 9495 3060 9630 46 | 2 1 0 1 0 -1 0 0 -1 4.000 0 0 0 0 0 2 47 | 2745 9585 2880 9585 48 | 2 1 0 1 0 -1 0 0 -1 4.000 0 0 0 0 0 2 49 | 2745 9405 2880 9405 50 | 2 1 0 1 0 -1 0 0 -1 0.000 0 1 0 0 0 2 51 | 2880 9360 2880 9630 52 | 2 1 0 1 0 -1 0 0 -1 0.000 0 1 0 0 0 2 53 | 3060 9360 2880 9360 54 | 2 1 0 1 0 -1 0 0 -1 4.000 0 0 0 0 0 2 55 | 3060 9630 2880 9630 56 | 2 1 0 1 0 -1 0 0 -1 4.000 0 0 0 0 0 2 57 | 3330 9495 3195 9495 58 | -6 59 | 6 3330 9225 3690 9765 60 | 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 61 | 3375 9270 3645 9270 3645 9720 3375 9720 3375 9270 62 | 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 63 | 3465 9720 3510 9630 3555 9720 64 | -6 65 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 66 | 2745 9270 2745 9405 67 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 68 | 2745 9720 2745 9585 69 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 70 | 1 1 1.00 30.00 60.00 71 | 3375 9495 3195 9495 72 | 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 1 2 73 | 1 1 1.00 30.00 60.00 74 | 3825 9495 3645 9495 75 | 2 1 1 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 2 76 | 3645 9045 3645 9855 77 | 4 0 0 50 -1 0 12 0.0000 4 135 330 3825 9540 IOR\001 78 | 4 0 0 50 -1 0 12 0.0000 4 135 105 3510 9180 0\001 79 | 4 0 0 50 -1 0 12 0.0000 4 165 795 1260 9225 (A) E/Frm\001 80 | 4 0 0 50 -1 0 12 0.0000 4 165 795 1260 9405 (B) E/Frm\001 81 | 4 0 0 50 -1 0 12 0.0000 4 165 870 1170 9675 (A) E/Fwm\001 82 | 4 0 0 50 -1 0 12 0.0000 4 165 870 1170 9855 (B) E/Fwm\001 83 | --------------------------------------------------------------------------------