├── .gitignore ├── stopwatch-dual ├── .gitignore ├── iCEBreaker_Workshop_Manual_Teardown_2019.pdf ├── Makefile ├── icebreaker.pcf ├── README.md ├── stopwatch.v └── solution │ └── stopwatch.v ├── stopwatch ├── guide │ ├── themes │ │ ├── cover.png │ │ ├── ._cover.png │ │ ├── infoq-screen-theme.yml │ │ ├── infoq-prepress-theme.yml │ │ ├── half-theme.yml │ │ ├── pae-theme.yml │ │ ├── fullsize-theme.yml │ │ └── 6x9-theme.yml │ ├── images │ │ ├── underline.png │ │ ├── 7segment-segments.png │ │ ├── pmod-7segment-schematic.png │ │ └── icebreaker-v10b-with-7seg.jpg │ ├── README.md │ ├── sections │ │ ├── macros.adoc │ │ └── objectives.adoc │ └── icebreaker-fpga-stopwatch-workshop.adoc ├── icebreaker-fpga-stopwatch-workshop.pdf ├── README.md ├── Makefile ├── icebreaker.pcf ├── stopwatch.v └── solution │ └── stopwatch.v └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ._* 2 | *.yslog 3 | *.bin 4 | *.json 5 | *.asc 6 | *.nplog 7 | *.rpt 8 | -------------------------------------------------------------------------------- /stopwatch-dual/.gitignore: -------------------------------------------------------------------------------- 1 | /*.asc 2 | /*.bin 3 | /*.json 4 | /*.rpt 5 | /*.nplog 6 | /*.yslog 7 | -------------------------------------------------------------------------------- /stopwatch/guide/themes/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icebreaker-fpga/icebreaker-workshop/HEAD/stopwatch/guide/themes/cover.png -------------------------------------------------------------------------------- /stopwatch/guide/images/underline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icebreaker-fpga/icebreaker-workshop/HEAD/stopwatch/guide/images/underline.png -------------------------------------------------------------------------------- /stopwatch/guide/themes/._cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icebreaker-fpga/icebreaker-workshop/HEAD/stopwatch/guide/themes/._cover.png -------------------------------------------------------------------------------- /stopwatch/guide/images/7segment-segments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icebreaker-fpga/icebreaker-workshop/HEAD/stopwatch/guide/images/7segment-segments.png -------------------------------------------------------------------------------- /stopwatch/icebreaker-fpga-stopwatch-workshop.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icebreaker-fpga/icebreaker-workshop/HEAD/stopwatch/icebreaker-fpga-stopwatch-workshop.pdf -------------------------------------------------------------------------------- /stopwatch/guide/images/pmod-7segment-schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icebreaker-fpga/icebreaker-workshop/HEAD/stopwatch/guide/images/pmod-7segment-schematic.png -------------------------------------------------------------------------------- /stopwatch/guide/images/icebreaker-v10b-with-7seg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icebreaker-fpga/icebreaker-workshop/HEAD/stopwatch/guide/images/icebreaker-v10b-with-7seg.jpg -------------------------------------------------------------------------------- /stopwatch/README.md: -------------------------------------------------------------------------------- 1 | Welcome to the iCEBreaker FPGA stopwatch workshop! 2 | 3 | This directory contains a pdf file with the guide. Open it up, follow the instructions and have fun! 4 | -------------------------------------------------------------------------------- /stopwatch-dual/iCEBreaker_Workshop_Manual_Teardown_2019.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/icebreaker-fpga/icebreaker-workshop/HEAD/stopwatch-dual/iCEBreaker_Workshop_Manual_Teardown_2019.pdf -------------------------------------------------------------------------------- /stopwatch/guide/README.md: -------------------------------------------------------------------------------- 1 | If you want to synthesize the workshop guide out of the asciidoc files you will need asciidoctor-pdf. 2 | 3 | To install asciidoctor-pdf run `gem install asciidoctor-pdf`. 4 | 5 | To build the workshop guide run `asciidoctor-pdf *.adoc` 6 | 7 | -------------------------------------------------------------------------------- /stopwatch/guide/sections/macros.adoc: -------------------------------------------------------------------------------- 1 | :q: ? \ 2 | + \ 3 | image:underline.png[] \ 4 | + \ 5 | 6 | :qq: ? \ 7 | + \ 8 | image:underline.png[] \ 9 | image:underline.png[] \ 10 | + \ 11 | 12 | :qqqq: ? \ 13 | + \ 14 | image:underline.png[] \ 15 | image:underline.png[] \ 16 | image:underline.png[] \ 17 | image:underline.png[] \ 18 | + \ 19 | 20 | :bl: pass:[ +] 21 | 22 | -------------------------------------------------------------------------------- /stopwatch/guide/sections/objectives.adoc: -------------------------------------------------------------------------------- 1 | .Course Objectives 2 | This lab manual is a workbook that accompanies the iCEBreaker FPGA stopwatch workshop. 3 | 4 | Our objective is for attendees to get as much hands-on time with hardware as possible during our classes. Lectures serve as introductions to topics, but the walk-throughs and challenges in this manual will lead you to deeper understanding and higher retention of important information. We recommend recording as much as possible in this manual, as it may become a resource for your future hardware hacking adventures. 5 | 6 | This training is based on the SecuringHardware.com model developed by Joe FitzPatrick. If you enjoy this workshop make sure to check out the list of workshops SecuringHardware.com offer. This workshop was developed by 1BitSquared for the iCEBreaker FPGA development board. We also develop other workshops. You can find the WTFpga and iCEBreaker workshops on GitHub at https://github.com/icebreaker-fpga. 7 | -------------------------------------------------------------------------------- /stopwatch/Makefile: -------------------------------------------------------------------------------- 1 | PROJ = stopwatch 2 | 3 | all: $(PROJ).rpt $(PROJ).bin 4 | 5 | $(PROJ).json: $(PROJ).v 6 | yosys -ql $(PROJ).yslog -p 'synth_ice40 -top top -json $@' $< 7 | 8 | $(PROJ).asc: $(PROJ).json icebreaker.pcf 9 | nextpnr-ice40 -ql $(PROJ).nplog --up5k --package sg48 --freq 12 --asc $@ --pcf icebreaker.pcf --json $< 10 | 11 | $(PROJ).bin: $(PROJ).asc 12 | icepack $< $@ 13 | 14 | $(PROJ).rpt: $(PROJ).asc 15 | icetime -d up5k -c 12 -mtr $@ $< 16 | 17 | $(PROJ)_tb: $(PROJ)_tb.v $(PROJ).v 18 | iverilog -o $@ $^ 19 | 20 | $(PROJ)_tb.vcd: $(PROJ)_tb 21 | vvp -N $< +vcd=$@ 22 | 23 | $(PROJ)_syn.v: $(PROJ).json 24 | yosys -p 'read_json $^; write_verilog $@' 25 | 26 | $(PROJ)_syntb: $(PROJ)_tb.v $(PROJ)_syn.v 27 | iverilog -o $@ $^ `yosys-config --datdir/ice40/cells_sim.v` 28 | 29 | $(PROJ)_syntb.vcd: $(PROJ)_syntb 30 | vvp -N $< +vcd=$@ 31 | 32 | prog: $(PROJ).bin 33 | iceprog $< 34 | 35 | sudo-prog: $(PROJ).bin 36 | @echo 'Executing prog as root!!!' 37 | sudo iceprog $< 38 | 39 | clean: 40 | rm -f $(PROJ).yslog $(PROJ).nplog $(PROJ).json $(PROJ).asc $(PROJ).rpt $(PROJ).bin 41 | rm -f $(PROJ)_tb $(PROJ)_tb.vcd $(PROJ)_syn.v $(PROJ)_syntb $(PROJ)_syntb.vcd 42 | 43 | .SECONDARY: 44 | .PHONY: all prog clean 45 | -------------------------------------------------------------------------------- /stopwatch-dual/Makefile: -------------------------------------------------------------------------------- 1 | PROJ = stopwatch 2 | 3 | all: $(PROJ).rpt $(PROJ).bin 4 | 5 | $(PROJ).json: $(PROJ).v 6 | yosys -ql $(PROJ).yslog -p 'synth_ice40 -top top -json $@' $< 7 | 8 | $(PROJ).asc: $(PROJ).json icebreaker.pcf 9 | nextpnr-ice40 -ql $(PROJ).nplog --up5k --package sg48 --freq 12 --asc $@ --pcf icebreaker.pcf --json $< 10 | 11 | $(PROJ).bin: $(PROJ).asc 12 | icepack $< $@ 13 | 14 | $(PROJ).rpt: $(PROJ).asc 15 | icetime -d up5k -c 12 -mtr $@ $< 16 | 17 | $(PROJ)_tb: $(PROJ)_tb.v $(PROJ).v 18 | iverilog -o $@ $^ 19 | 20 | $(PROJ)_tb.vcd: $(PROJ)_tb 21 | vvp -N $< +vcd=$@ 22 | 23 | $(PROJ)_syn.v: $(PROJ).json 24 | yosys -p 'read_json $^; write_verilog $@' 25 | 26 | $(PROJ)_syntb: $(PROJ)_tb.v $(PROJ)_syn.v 27 | iverilog -o $@ $^ `yosys-config --datdir/ice40/cells_sim.v` 28 | 29 | $(PROJ)_syntb.vcd: $(PROJ)_syntb 30 | vvp -N $< +vcd=$@ 31 | 32 | prog: $(PROJ).bin 33 | iceprog $< 34 | 35 | sudo-prog: $(PROJ).bin 36 | @echo 'Executing prog as root!!!' 37 | sudo iceprog $< 38 | 39 | clean: 40 | rm -f $(PROJ).yslog $(PROJ).nplog $(PROJ).json $(PROJ).asc $(PROJ).rpt $(PROJ).bin 41 | rm -f $(PROJ)_tb $(PROJ)_tb.vcd $(PROJ)_syn.v $(PROJ)_syntb $(PROJ)_syntb.vcd 42 | 43 | .SECONDARY: 44 | .PHONY: all prog clean 45 | -------------------------------------------------------------------------------- /stopwatch/icebreaker.pcf: -------------------------------------------------------------------------------- 1 | # 12 MHz clock 2 | set_io -nowarn CLK 35 3 | 4 | # RS232 5 | set_io -nowarn RX 6 6 | set_io -nowarn TX 9 7 | 8 | # LEDs and Button 9 | set_io -nowarn BTN_N 10 10 | set_io -nowarn LEDR_N 11 11 | set_io -nowarn LEDG_N 37 12 | 13 | # RGB LED Driver 14 | set_io -nowarn LED_RED_N 39 15 | set_io -nowarn LED_GRN_N 40 16 | set_io -nowarn LED_BLU_N 41 17 | 18 | # SPI Flash 19 | set_io -nowarn FLASH_SCK 15 20 | set_io -nowarn FLASH_SSB 16 21 | set_io -nowarn FLASH_IO0 14 22 | set_io -nowarn FLASH_IO1 17 23 | set_io -nowarn FLASH_IO2 12 24 | set_io -nowarn FLASH_IO3 13 25 | 26 | # PMOD 1A 27 | set_io -nowarn P1A1 4 28 | set_io -nowarn P1A2 2 29 | set_io -nowarn P1A3 47 30 | set_io -nowarn P1A4 45 31 | set_io -nowarn P1A7 3 32 | set_io -nowarn P1A8 48 33 | set_io -nowarn P1A9 46 34 | set_io -nowarn P1A10 44 35 | 36 | # PMOD 1B 37 | set_io -nowarn P1B1 43 38 | set_io -nowarn P1B2 38 39 | set_io -nowarn P1B3 34 40 | set_io -nowarn P1B4 31 41 | set_io -nowarn P1B7 42 42 | set_io -nowarn P1B8 36 43 | set_io -nowarn P1B9 32 44 | set_io -nowarn P1B10 28 45 | 46 | # LEDs and Buttons (PMOD 2) 47 | set_io -nowarn LED1 26 48 | set_io -nowarn LED2 27 49 | set_io -nowarn LED3 25 50 | set_io -nowarn LED4 23 51 | set_io -nowarn LED5 21 52 | set_io -nowarn BTN1 20 53 | set_io -nowarn BTN2 19 54 | set_io -nowarn BTN3 18 55 | -------------------------------------------------------------------------------- /stopwatch-dual/icebreaker.pcf: -------------------------------------------------------------------------------- 1 | # 12 MHz clock 2 | set_io -nowarn CLK 35 3 | 4 | # RS232 5 | set_io -nowarn RX 6 6 | set_io -nowarn TX 9 7 | 8 | # LEDs and Button 9 | set_io -nowarn BTN_N 10 10 | set_io -nowarn LEDR_N 11 11 | set_io -nowarn LEDG_N 37 12 | 13 | # RGB LED Driver 14 | set_io -nowarn LED_RED_N 39 15 | set_io -nowarn LED_GRN_N 40 16 | set_io -nowarn LED_BLU_N 41 17 | 18 | # SPI Flash 19 | set_io -nowarn FLASH_SCK 15 20 | set_io -nowarn FLASH_SSB 16 21 | set_io -nowarn FLASH_IO0 14 22 | set_io -nowarn FLASH_IO1 17 23 | set_io -nowarn FLASH_IO2 12 24 | set_io -nowarn FLASH_IO3 13 25 | 26 | # PMOD 1A 27 | set_io -nowarn P1A1 4 28 | set_io -nowarn P1A2 2 29 | set_io -nowarn P1A3 47 30 | set_io -nowarn P1A4 45 31 | set_io -nowarn P1A7 3 32 | set_io -nowarn P1A8 48 33 | set_io -nowarn P1A9 46 34 | set_io -nowarn P1A10 44 35 | 36 | # PMOD 1B 37 | set_io -nowarn P1B1 43 38 | set_io -nowarn P1B2 38 39 | set_io -nowarn P1B3 34 40 | set_io -nowarn P1B4 31 41 | set_io -nowarn P1B7 42 42 | set_io -nowarn P1B8 36 43 | set_io -nowarn P1B9 32 44 | set_io -nowarn P1B10 28 45 | 46 | # LEDs and Buttons (PMOD 2) 47 | set_io -nowarn LED1 26 48 | set_io -nowarn LED2 27 49 | set_io -nowarn LED3 25 50 | set_io -nowarn LED4 23 51 | set_io -nowarn LED5 21 52 | set_io -nowarn BTN1 20 53 | set_io -nowarn BTN2 19 54 | set_io -nowarn BTN3 18 55 | -------------------------------------------------------------------------------- /stopwatch-dual/README.md: -------------------------------------------------------------------------------- 1 | WTFpga NG -- Stopwatch Edition 2 | ============================== 3 | 4 | Run `make prog` and play with the design. What do the buttons do? 5 | 6 | Compare your observations with the `assign LEDx = ...` lines in `stopwatch.v`. 7 | 8 | Simple continous assignments 9 | ---------------------------- 10 | 11 | Change the assignments for `LED1..LED5` so that 12 | 13 | `LED1` is on when buttons 1 and 2 are pressed. 14 | 15 | `LED2` is on when buttons 1 and 3 are pressed. 16 | 17 | `LED3` is on when buttons 2 and 3 are pressed. 18 | 19 | `LED4` is on when the "user button" (`BTN_N`) is pressed. (Note that this button is inverted, i.e. the value of `BTN_N` is zero when the button is pressed.) 20 | 21 | `LED5` is on when any of the four buttons is pressed. 22 | 23 | Add missing 7-segment digits 24 | ---------------------------- 25 | 26 | The module `seven_seg_hex` is converting a 4-bit binary number into a 7-bit seven segment control vector. The entries for "3" and "8" are missing add them. 27 | 28 | Switch to decimal counting 29 | -------------------------- 30 | 31 | The module `bcd16_increment` reads a 16-bit BCD number (a decimal digit in each nibble) and increments it by one. Replace the line `assign display_value_inc = display_value + 1;` with an instance of `bcd16_increment` so that the stop watch counts in decimal instead of hexadecimal. 32 | 33 | (See the instances of `seven_seg_ctrl` for how to instantiate a module.) 34 | 35 | Add RESET button 36 | ---------------- 37 | 38 | Add an if-statement to the `always @(posedge CLK)` block in the `top` module that will reset `display_value` to zero when the "user button" (`BTN_N`) is pressed. 39 | 40 | Add START/STOP buttons 41 | --------------------- 42 | 43 | Add a (1 bit) `running` register (initialized to zero), and change the code that increments `display_value` to only apply the increment when running is `1`. 44 | 45 | Add if-statements to the `always @(posedge CLK)` block in the `top` module that will set `running` to `1` when `BTN3` is pressed, and reset `running` to `0` when `BTN1` is pressed. Now these two buttons function as START and STOP buttons for the stop watch. 46 | 47 | Also change the RESET functionality so that `running` is reset to `0` when the "user button" (`BTN_N`) is pressed. 48 | 49 | Add lap time measurement 50 | ------------------------ 51 | 52 | Finally let's also add lap time measurement: pressing the center button on the 53 | board should display the current time for two seconds while we keep counting in 54 | the background. 55 | 56 | For this, we need to add a 16 bit register `lap_value` and an 8 bit register 57 | `lap_timeout`. 58 | 59 | `lap_timeout` should be decremented in every `clkdiv_pulse` cycle until 60 | it reaches zero. The seven segment display should show the value of `lap_value` 61 | instead of `display_value` when `lap_timeout` has a nonzero value. 62 | 63 | Pressing the center button (`BTN2`) should set `lap_timeout` to 200 and copy the 64 | value from `display_value` to `lap_value`. 65 | 66 | Note: The syntax `a ? b : c` can be used to select value `b` when `a` is nonzero, 67 | and value `c` otherwise. 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## iCEBreaker FPGA Workshop 2 | 3 | Welcome to the iCEBreaker FPGA workshop repository. 4 | 5 | This workshop is self directed and can be done on your own time. 6 | 7 | 8 | ## iCEBreaker workshop sessions 9 | 10 | * [Crowd Supply Teardown conference](https://www.crowdsupply.com/teardown/portland-2019) in Portland Oregon 21st-23rd June 2019. 11 | * [Chaos Communication Congress 36C3](https://events.ccc.de/congress/2019/wiki/index.php/Session:ICEBreaker_FPGA_Workshop) 12 | in Leipzig Germany 27th-30th December 2019. 13 | 14 | The most up to date version of the workshop can be found on in the stopwatch subdirectory of [this repository](https://github.com/icebreaker-fpga/icebreaker-workshop/tree/master/stopwatch). 15 | 16 | ## Supplies needed 17 | 18 | * Computer 19 | * Micro USB cable (make sure it is a data cable not just a charge cable) 20 | * [iCEBreaker](https://1bitsquared.com/products/icebreaker) 21 | * [iCEBreaker 7Segment display](https://1bitsquared.com/products/pmod-7-segment-display) 22 | * You might need one or two displays depending on the workshop you choose. 23 | 24 | **Note:** In most cases we provide the iCEBreaker hardware for the duration of the 25 | workshop. You will have to return it after the workshop is over. Make sure to 26 | read the specific workshop instructions. We usually also have extra hardware 27 | you can purchase so you can keep hacking on it and take home. Also refer to the 28 | workshop instructions of how to get the hardware or ping [@esden on 29 | twitter](https://twitter.com/esden). 30 | 31 | ## Toolchain installation 32 | 33 | Follow the instructions on the [fomu-toolchain 34 | README](https://github.com/im-tomu/fomu-toolchain) to install the FPGA 35 | toolchain on your computer. 36 | 37 | ## I am ready let's GO! 38 | 39 | Now that you have all the supplies and the toolchain installed go ahead and 40 | clone this repository: 41 | 42 | ``` 43 | git clone https://github.com/icebreaker-fpga/icebreaker-workshop.git 44 | cd icebreaker-workshop/stopwatch 45 | ``` 46 | 47 | In the stopwatch directory you will find the workshop guide PDF. Follow the 48 | instructions inside the PDF. If you happen to do the workshop as part of an 49 | organized class the helpers are here to help you out when you have questions or 50 | you get stuck somewhere. Do not hesitate to ask for help, this is why we are 51 | here. 52 | 53 | If you are doing the workshop on your own time and you want to share your 54 | experiances or want to ask a question, [join our Discord 55 | server](https://1bitsquared.com/pages/chat)! 56 | 57 | ## Troubleshooting 58 | 59 | **I am running iceprog and the programmer is not being detected** 60 | 61 | **Linux** 62 | 63 | * Check if the device is being detected by the kernel with 'lsusb' it will 64 | either show up as a Future Electronics device or the name of the programmer 65 | vendor. 66 | * If the device is being detected by the kernel you might not have permissions 67 | to access the device. If you run `sudo iceprog ...` and the device is 68 | decected you can give yourself permissions by creating a udev file at: 69 | `/etc/udev/rules.d/53-icebreaker-ftdi.rules` and adding the following line in 70 | that file: 71 | ``` 72 | ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="0660", GROUP="plugdev", TAG+="uaccess" 73 | ``` 74 | After adding that file you need to at least replug the programmer or even 75 | reload the udev rules. 76 | 77 | **Windows** 78 | 79 | You will need the [zadig drivers](https://zadig.akeo.ie), choose icebreaker interface 0 and then choose winusb. If the icebreaker interface does not show up, check that "List all devices" is ticked under "Options". 80 | -------------------------------------------------------------------------------- /stopwatch/stopwatch.v: -------------------------------------------------------------------------------- 1 | // Cause yosys to throw an error when we implicitly declare nets 2 | `default_nettype none 3 | 4 | // Project entry point 5 | module top ( 6 | input CLK, 7 | input BTN_N, BTN1, BTN2, BTN3, 8 | output LED1, LED2, LED3, LED4, LED5, 9 | output P1A1, P1A2, P1A3, P1A4, P1A7, P1A8, P1A9, P1A10, 10 | ); 11 | // 7 segment control line bus 12 | wire [7:0] seven_segment; 13 | 14 | // Assign 7 segment control line bus to Pmod pins 15 | assign { P1A10, P1A9, P1A8, P1A7, P1A4, P1A3, P1A2, P1A1 } = seven_segment; 16 | 17 | // Display value register and increment bus 18 | reg [7:0] display_value = 0; 19 | wire [7:0] display_value_inc; 20 | 21 | // Clock divider and pulse registers 22 | reg [20:0] clkdiv = 0; 23 | reg clkdiv_pulse = 0; 24 | 25 | // Combinatorial logic 26 | assign LED1 = !BTN_N; // Not operator example 27 | assign LED2 = BTN1 || BTN2; // Or operator example 28 | assign LED3 = BTN2 ^ BTN3; // Xor operator example 29 | assign LED4 = BTN3 && !BTN_N; // And operator example 30 | assign LED5 = (BTN1 + BTN2 + BTN3 + 2'b00) >> 1; // Addition and shift example 31 | 32 | // Synchronous logic 33 | always @(posedge CLK) begin 34 | // Clock divider pulse generator 35 | if (clkdiv == 1200000) begin 36 | clkdiv <= 0; 37 | clkdiv_pulse <= 1; 38 | end else begin 39 | clkdiv <= clkdiv + 1; 40 | clkdiv_pulse <= 0; 41 | end 42 | 43 | // Timer counter 44 | if (clkdiv_pulse) begin 45 | display_value <= display_value_inc; 46 | end 47 | 48 | end 49 | 50 | assign display_value_inc = display_value + 8'b1; 51 | 52 | // 7 segment display control Pmod 1A 53 | seven_seg_ctrl seven_segment_ctrl ( 54 | .CLK(CLK), 55 | .din(display_value[7:0]), 56 | .dout(seven_segment) 57 | ); 58 | 59 | endmodule 60 | 61 | // BCD (Binary Coded Decimal) counter 62 | module bcd8_increment ( 63 | input [7:0] din, 64 | output reg [7:0] dout 65 | ); 66 | always @* begin 67 | case (1'b1) 68 | din[7:0] == 8'h 99: 69 | dout = 0; 70 | din[3:0] == 4'h 9: 71 | dout = {din[7:4] + 4'd 1, 4'h 0}; 72 | default: 73 | dout = {din[7:4], din[3:0] + 4'd 1}; 74 | endcase 75 | end 76 | endmodule 77 | 78 | // Seven segment controller 79 | // Switches quickly between the two parts of the display 80 | // to create the illusion of both halves being illuminated 81 | // at the same time. 82 | module seven_seg_ctrl ( 83 | input CLK, 84 | input [7:0] din, 85 | output reg [7:0] dout 86 | ); 87 | wire [6:0] lsb_digit; 88 | wire [6:0] msb_digit; 89 | 90 | seven_seg_hex msb_nibble ( 91 | .din(din[7:4]), 92 | .dout(msb_digit) 93 | ); 94 | 95 | seven_seg_hex lsb_nibble ( 96 | .din(din[3:0]), 97 | .dout(lsb_digit) 98 | ); 99 | 100 | reg [9:0] clkdiv = 0; 101 | reg clkdiv_pulse = 0; 102 | reg msb_not_lsb = 0; 103 | 104 | always @(posedge CLK) begin 105 | clkdiv <= clkdiv + 1; 106 | clkdiv_pulse <= &clkdiv; 107 | msb_not_lsb <= msb_not_lsb ^ clkdiv_pulse; 108 | 109 | if (clkdiv_pulse) begin 110 | if (msb_not_lsb) begin 111 | dout[6:0] <= ~msb_digit; 112 | dout[7] <= 0; 113 | end else begin 114 | dout[6:0] <= ~lsb_digit; 115 | dout[7] <= 1; 116 | end 117 | end 118 | end 119 | endmodule 120 | 121 | // Convert 4bit numbers to 7 segments 122 | module seven_seg_hex ( 123 | input [3:0] din, 124 | output reg [6:0] dout 125 | ); 126 | always @* 127 | case (din) 128 | 4'h0: dout = 7'b 0111111; 129 | 4'h1: dout = 7'b 0000110; 130 | 4'h2: dout = 7'b 1011011; 131 | // 4'h3: dout = FIXME; 132 | 4'h4: dout = 7'b 1100110; 133 | 4'h5: dout = 7'b 1101101; 134 | 4'h6: dout = 7'b 1111101; 135 | 4'h7: dout = 7'b 0000111; 136 | // 4'h8: dout = FIXME; 137 | 4'h9: dout = 7'b 1101111; 138 | 4'hA: dout = 7'b 1110111; 139 | 4'hB: dout = 7'b 1111100; 140 | 4'hC: dout = 7'b 0111001; 141 | 4'hD: dout = 7'b 1011110; 142 | 4'hE: dout = 7'b 1111001; 143 | 4'hF: dout = 7'b 1110001; 144 | default: dout = 7'b 1000000; 145 | endcase 146 | endmodule 147 | -------------------------------------------------------------------------------- /stopwatch/solution/stopwatch.v: -------------------------------------------------------------------------------- 1 | // Cause yosys to throw an error when we implicitly declare nets 2 | `default_nettype none 3 | 4 | // Project entry point 5 | module top ( 6 | input CLK, 7 | input BTN_N, BTN1, BTN2, BTN3, 8 | output LED1, LED2, LED3, LED4, LED5, 9 | output P1A1, P1A2, P1A3, P1A4, P1A7, P1A8, P1A9, P1A10, 10 | ); 11 | // 7 segment control line bus 12 | wire [7:0] seven_segment; 13 | 14 | // Assign 7 segment control line bus to Pmod pins 15 | assign { P1A10, P1A9, P1A8, P1A7, P1A4, P1A3, P1A2, P1A1 } = seven_segment; 16 | 17 | // Display value register and increment bus 18 | reg [7:0] display_value = 0; 19 | wire [7:0] display_value_inc; 20 | 21 | // Lap registers 22 | reg [7:0] lap_value = 0; 23 | reg [4:0] lap_timeout = 0; 24 | 25 | // Clock divider and pulse registers 26 | reg [20:0] clkdiv = 0; 27 | reg clkdiv_pulse = 0; 28 | reg running = 0; 29 | 30 | // Combinatorial logic 31 | assign LED1 = BTN1 && BTN2; 32 | assign LED2 = BTN1 && BTN3; 33 | assign LED3 = BTN2 && BTN3; 34 | assign LED4 = !BTN_N; 35 | assign LED5 = !BTN_N || BTN1 || BTN2 || BTN3; 36 | 37 | // Synchronous logic 38 | always @(posedge CLK) begin 39 | // Clock divider pulse generator 40 | if (clkdiv == 1200000) begin 41 | clkdiv <= 0; 42 | clkdiv_pulse <= 1; 43 | end else begin 44 | clkdiv <= clkdiv + 1; 45 | clkdiv_pulse <= 0; 46 | end 47 | 48 | // Lap timeout counter 49 | if (clkdiv_pulse && lap_timeout) begin 50 | lap_timeout <= lap_timeout - 1; 51 | end 52 | 53 | // Timer counter 54 | if (clkdiv_pulse && running) begin 55 | display_value <= display_value_inc; 56 | end 57 | 58 | // Button controls 59 | if (!BTN_N) begin 60 | display_value <= 0; 61 | running <= 0; 62 | lap_timeout <= 0; 63 | end 64 | 65 | if (BTN3) begin 66 | running <= 1; 67 | end 68 | 69 | if (BTN1) begin 70 | running <= 0; 71 | end 72 | 73 | if (BTN2) begin 74 | lap_value <= display_value; 75 | lap_timeout <= 20; 76 | end 77 | end 78 | 79 | // BCD counter 80 | bcd8_increment bot_inc ( 81 | .din(display_value), 82 | .dout(display_value_inc) 83 | ); 84 | 85 | // 7 segment display control 86 | seven_seg_ctrl seven_segment_ctrl ( 87 | .CLK(CLK), 88 | .din(lap_timeout ? lap_value[7:0] : display_value[7:0]), 89 | .dout(seven_segment) 90 | ); 91 | 92 | endmodule 93 | 94 | // BCD (Binary Coded Decimal) counter 95 | module bcd8_increment ( 96 | input [7:0] din, 97 | output reg [7:0] dout 98 | ); 99 | always @* begin 100 | case (1'b1) 101 | din[7:0] == 8'h 99: 102 | dout = 0; 103 | din[3:0] == 4'h 9: 104 | dout = {din[7:4] + 4'd 1, 4'h 0}; 105 | default: 106 | dout = {din[7:4], din[3:0] + 4'd 1}; 107 | endcase 108 | end 109 | endmodule 110 | 111 | // Seven segment controller 112 | // Switches quickly between the two parts of the display 113 | // to create the illusion of both halfs being illuminated 114 | // at the same time. 115 | module seven_seg_ctrl ( 116 | input CLK, 117 | input [7:0] din, 118 | output reg [7:0] dout 119 | ); 120 | wire [6:0] lsb_digit; 121 | wire [6:0] msb_digit; 122 | 123 | seven_seg_hex msb_nibble ( 124 | .din(din[7:4]), 125 | .dout(msb_digit) 126 | ); 127 | 128 | seven_seg_hex lsb_nibble ( 129 | .din(din[3:0]), 130 | .dout(lsb_digit) 131 | ); 132 | 133 | reg [9:0] clkdiv = 0; 134 | reg clkdiv_pulse = 0; 135 | reg msb_not_lsb = 0; 136 | 137 | always @(posedge CLK) begin 138 | clkdiv <= clkdiv + 1; 139 | clkdiv_pulse <= &clkdiv; 140 | msb_not_lsb <= msb_not_lsb ^ clkdiv_pulse; 141 | 142 | if (clkdiv_pulse) begin 143 | if (msb_not_lsb) begin 144 | dout[6:0] <= ~msb_digit; 145 | dout[7] <= 0; 146 | end else begin 147 | dout[6:0] <= ~lsb_digit; 148 | dout[7] <= 1; 149 | end 150 | end 151 | end 152 | endmodule 153 | 154 | // Convert 4bit numbers to 7 segments 155 | module seven_seg_hex ( 156 | input [3:0] din, 157 | output reg [6:0] dout 158 | ); 159 | always @* 160 | case (din) 161 | 4'h0: dout = 7'b 0111111; 162 | 4'h1: dout = 7'b 0000110; 163 | 4'h2: dout = 7'b 1011011; 164 | 4'h3: dout = 7'b 1001111; 165 | 4'h4: dout = 7'b 1100110; 166 | 4'h5: dout = 7'b 1101101; 167 | 4'h6: dout = 7'b 1111101; 168 | 4'h7: dout = 7'b 0000111; 169 | 4'h8: dout = 7'b 1111111; 170 | 4'h9: dout = 7'b 1101111; 171 | 4'hA: dout = 7'b 1110111; 172 | 4'hB: dout = 7'b 1111100; 173 | 4'hC: dout = 7'b 0111001; 174 | 4'hD: dout = 7'b 1011110; 175 | 4'hE: dout = 7'b 1111001; 176 | 4'hF: dout = 7'b 1110001; 177 | default: dout = 7'b 1000000; 178 | endcase 179 | endmodule 180 | -------------------------------------------------------------------------------- /stopwatch-dual/stopwatch.v: -------------------------------------------------------------------------------- 1 | // Cause yosys to throw an error when we implicitly declare nets 2 | `default_nettype none 3 | 4 | // Project entry point 5 | module top ( 6 | input CLK, 7 | input BTN_N, BTN1, BTN2, BTN3, 8 | output LED1, LED2, LED3, LED4, LED5, 9 | output P1A1, P1A2, P1A3, P1A4, P1A7, P1A8, P1A9, P1A10, 10 | output P1B1, P1B2, P1B3, P1B4, P1B7, P1B8, P1B9, P1B10 11 | ); 12 | // 7 segment control line busses 13 | wire [7:0] seven_segment_top; 14 | wire [7:0] seven_segment_bot; 15 | 16 | // Assign 7 segment control line bus to Pmod pins 17 | assign { P1A10, P1A9, P1A8, P1A7, P1A4, P1A3, P1A2, P1A1 } = seven_segment_top; 18 | assign { P1B10, P1B9, P1B8, P1B7, P1B4, P1B3, P1B2, P1B1 } = seven_segment_bot; 19 | 20 | // Display value register and increment bus 21 | reg [15:0] display_value = 0; 22 | wire [15:0] display_value_inc; 23 | 24 | // Clock divider and pulse registers 25 | reg [20:0] clkdiv = 0; 26 | reg clkdiv_pulse = 0; 27 | 28 | // Combinatorial logic 29 | assign LED1 = !BTN_N; // Not operator example 30 | assign LED2 = BTN1 || BTN2; // Or operator example 31 | assign LED3 = BTN2 ^ BTN3; // Xor operator example 32 | assign LED4 = BTN3 && !BTN_N; // And operator example 33 | assign LED5 = (BTN1 + BTN2 + BTN3 + 2'b00) >> 1; // Addition and shift example 34 | 35 | // Synchronous logic 36 | always @(posedge CLK) begin 37 | // Clock divider pulse generator 38 | if (clkdiv == 120000) begin 39 | clkdiv <= 0; 40 | clkdiv_pulse <= 1; 41 | end else begin 42 | clkdiv <= clkdiv + 1; 43 | clkdiv_pulse <= 0; 44 | end 45 | 46 | // Timer counter 47 | if (clkdiv_pulse) begin 48 | display_value <= display_value_inc; 49 | end 50 | end 51 | 52 | assign display_value_inc = display_value + 16'b1; 53 | 54 | // 7 segment display control top Pmod 1A 55 | seven_seg_ctrl seven_segment_ctrl_top ( 56 | .CLK(CLK), 57 | .din(display_value[15:8]), 58 | .dout(seven_segment_top) 59 | ); 60 | 61 | // 7 segment display control bottom Pmod 1B 62 | seven_seg_ctrl seven_segment_ctrl_bot ( 63 | .CLK(CLK), 64 | .din(display_value[7:0]), 65 | .dout(seven_segment_bot) 66 | ); 67 | 68 | endmodule 69 | 70 | // BCD (Binary Coded Decimal) counter 71 | module bcd16_increment ( 72 | input [15:0] din, 73 | output reg [15:0] dout 74 | ); 75 | always @* begin 76 | case (1'b1) 77 | din[15:0] == 16'h 9999: 78 | dout = 0; 79 | din[11:0] == 12'h 999: 80 | dout = {din[15:12] + 4'd 1, 12'h 000}; 81 | din[7:0] == 8'h 99: 82 | dout = {din[15:12], din[11:8] + 4'd 1, 8'h 00}; 83 | din[3:0] == 4'h 9: 84 | dout = {din[15:8], din[7:4] + 4'd 1, 4'h 0}; 85 | default: 86 | dout = {din[15:4], din[3:0] + 4'd 1}; 87 | endcase 88 | end 89 | endmodule 90 | 91 | // Seven segment controller 92 | // Switches quickly between the two parts of the display 93 | // to create the illusion of both halfs being illuminated 94 | // at the same time. 95 | module seven_seg_ctrl ( 96 | input CLK, 97 | input [7:0] din, 98 | output reg [7:0] dout 99 | ); 100 | wire [6:0] lsb_digit; 101 | wire [6:0] msb_digit; 102 | 103 | seven_seg_hex msb_nibble ( 104 | .din(din[7:4]), 105 | .dout(msb_digit) 106 | ); 107 | 108 | seven_seg_hex lsb_nibble ( 109 | .din(din[3:0]), 110 | .dout(lsb_digit) 111 | ); 112 | 113 | reg [9:0] clkdiv = 0; 114 | reg clkdiv_pulse = 0; 115 | reg msb_not_lsb = 0; 116 | 117 | always @(posedge CLK) begin 118 | clkdiv <= clkdiv + 1; 119 | clkdiv_pulse <= &clkdiv; 120 | msb_not_lsb <= msb_not_lsb ^ clkdiv_pulse; 121 | 122 | if (clkdiv_pulse) begin 123 | if (msb_not_lsb) begin 124 | dout[6:0] <= ~msb_digit; 125 | dout[7] <= 0; 126 | end else begin 127 | dout[6:0] <= ~lsb_digit; 128 | dout[7] <= 1; 129 | end 130 | end 131 | end 132 | endmodule 133 | 134 | // Convert 4bit numbers to 7 segments 135 | module seven_seg_hex ( 136 | input [3:0] din, 137 | output reg [6:0] dout 138 | ); 139 | always @* 140 | case (din) 141 | 4'h0: dout = 7'b 0111111; 142 | 4'h1: dout = 7'b 0000110; 143 | 4'h2: dout = 7'b 1011011; 144 | // 4'h3: dout = FIXME; 145 | 4'h4: dout = 7'b 1100110; 146 | 4'h5: dout = 7'b 1101101; 147 | 4'h6: dout = 7'b 1111101; 148 | 4'h7: dout = 7'b 0000111; 149 | // 4'h8: dout = FIXME; 150 | 4'h9: dout = 7'b 1101111; 151 | 4'hA: dout = 7'b 1110111; 152 | 4'hB: dout = 7'b 1111100; 153 | 4'hC: dout = 7'b 0111001; 154 | 4'hD: dout = 7'b 1011110; 155 | 4'hE: dout = 7'b 1111001; 156 | 4'hF: dout = 7'b 1110001; 157 | default: dout = 7'b 1000000; 158 | endcase 159 | endmodule 160 | -------------------------------------------------------------------------------- /stopwatch-dual/solution/stopwatch.v: -------------------------------------------------------------------------------- 1 | // Cause yosys to throw an error when we implicitly declare nets 2 | `default_nettype none 3 | 4 | // Project entry point 5 | module top ( 6 | input CLK, 7 | input BTN_N, BTN1, BTN2, BTN3, 8 | output LED1, LED2, LED3, LED4, LED5, 9 | output P1A1, P1A2, P1A3, P1A4, P1A7, P1A8, P1A9, P1A10, 10 | output P1B1, P1B2, P1B3, P1B4, P1B7, P1B8, P1B9, P1B10 11 | ); 12 | // 7 segment control line busses 13 | wire [7:0] seven_segment_top; 14 | wire [7:0] seven_segment_bot; 15 | 16 | // Assign 7 segment control line bus to Pmod pins 17 | assign { P1A10, P1A9, P1A8, P1A7, P1A4, P1A3, P1A2, P1A1 } = seven_segment_top; 18 | assign { P1B10, P1B9, P1B8, P1B7, P1B4, P1B3, P1B2, P1B1 } = seven_segment_bot; 19 | 20 | // Display value register and increment bus 21 | reg [15:0] display_value = 0; 22 | wire [15:0] display_value_inc; 23 | 24 | // Lap registers 25 | reg [15:0] lap_value = 0; 26 | reg [7:0] lap_timeout = 0; 27 | 28 | // Clock divider and pulse registers 29 | reg [20:0] clkdiv = 0; 30 | reg clkdiv_pulse = 0; 31 | reg running = 0; 32 | 33 | // Combinatorial logic 34 | assign LED1 = BTN1 && BTN2; 35 | assign LED2 = BTN1 && BTN3; 36 | assign LED3 = BTN2 && BTN3; 37 | assign LED4 = !BTN_N; 38 | assign LED5 = !BTN_N || BTN1 || BTN2 || BTN3; 39 | 40 | // Synchronous logic 41 | always @(posedge CLK) begin 42 | // Clock divider pulse generator 43 | if (clkdiv == 120000) begin 44 | clkdiv <= 0; 45 | clkdiv_pulse <= 1; 46 | end else begin 47 | clkdiv <= clkdiv + 1; 48 | clkdiv_pulse <= 0; 49 | end 50 | 51 | // Lap timeout counter 52 | if (clkdiv_pulse && lap_timeout) begin 53 | lap_timeout <= lap_timeout - 1; 54 | end 55 | 56 | // Timer counter 57 | if (clkdiv_pulse && running) begin 58 | display_value <= display_value_inc; 59 | end 60 | 61 | // Button controls 62 | if (!BTN_N) begin 63 | display_value <= 0; 64 | running <= 0; 65 | end 66 | 67 | if (BTN3) begin 68 | running <= 1; 69 | end 70 | 71 | if (BTN1) begin 72 | running <= 0; 73 | end 74 | 75 | if (BTN2) begin 76 | lap_value <= display_value; 77 | lap_timeout <= 200; 78 | end 79 | end 80 | 81 | // BCD counter 82 | bcd16_increment bot_inc ( 83 | .din(display_value), 84 | .dout(display_value_inc) 85 | ); 86 | 87 | // 7 segment display control top Pmod 1A 88 | seven_seg_ctrl seven_segment_ctrl_top ( 89 | .CLK(CLK), 90 | .din(lap_timeout ? lap_value[15:8] : display_value[15:8]), 91 | .dout(seven_segment_top) 92 | ); 93 | 94 | // 7 segment display control bottom Pmod 1B 95 | seven_seg_ctrl seven_segment_ctrl_bot ( 96 | .CLK(CLK), 97 | .din(lap_timeout ? lap_value[7:0] : display_value[7:0]), 98 | .dout(seven_segment_bot) 99 | ); 100 | 101 | endmodule 102 | 103 | // BCD (Binary Coded Decimal) counter 104 | module bcd16_increment ( 105 | input [15:0] din, 106 | output reg [15:0] dout 107 | ); 108 | always @* begin 109 | case (1'b1) 110 | din[15:0] == 16'h 9999: 111 | dout = 0; 112 | din[11:0] == 12'h 999: 113 | dout = {din[15:12] + 4'd 1, 12'h 000}; 114 | din[7:0] == 8'h 99: 115 | dout = {din[15:12], din[11:8] + 4'd 1, 8'h 00}; 116 | din[3:0] == 4'h 9: 117 | dout = {din[15:8], din[7:4] + 4'd 1, 4'h 0}; 118 | default: 119 | dout = {din[15:4], din[3:0] + 4'd 1}; 120 | endcase 121 | end 122 | endmodule 123 | 124 | // Seven segment controller 125 | // Switches quickly between the two parts of the display 126 | // to create the illusion of both halfs being illuminated 127 | // at the same time. 128 | module seven_seg_ctrl ( 129 | input CLK, 130 | input [7:0] din, 131 | output reg [7:0] dout 132 | ); 133 | wire [6:0] lsb_digit; 134 | wire [6:0] msb_digit; 135 | 136 | seven_seg_hex msb_nibble ( 137 | .din(din[7:4]), 138 | .dout(msb_digit) 139 | ); 140 | 141 | seven_seg_hex lsb_nibble ( 142 | .din(din[3:0]), 143 | .dout(lsb_digit) 144 | ); 145 | 146 | reg [9:0] clkdiv = 0; 147 | reg clkdiv_pulse = 0; 148 | reg msb_not_lsb = 0; 149 | 150 | always @(posedge CLK) begin 151 | clkdiv <= clkdiv + 1; 152 | clkdiv_pulse <= &clkdiv; 153 | msb_not_lsb <= msb_not_lsb ^ clkdiv_pulse; 154 | 155 | if (clkdiv_pulse) begin 156 | if (msb_not_lsb) begin 157 | dout[6:0] <= ~msb_digit; 158 | dout[7] <= 0; 159 | end else begin 160 | dout[6:0] <= ~lsb_digit; 161 | dout[7] <= 1; 162 | end 163 | end 164 | end 165 | endmodule 166 | 167 | // Convert 4bit numbers to 7 segments 168 | module seven_seg_hex ( 169 | input [3:0] din, 170 | output reg [6:0] dout 171 | ); 172 | always @* 173 | case (din) 174 | 4'h0: dout = 7'b 0111111; 175 | 4'h1: dout = 7'b 0000110; 176 | 4'h2: dout = 7'b 1011011; 177 | 4'h3: dout = 7'b 1001111; 178 | 4'h4: dout = 7'b 1100110; 179 | 4'h5: dout = 7'b 1101101; 180 | 4'h6: dout = 7'b 1111101; 181 | 4'h7: dout = 7'b 0000111; 182 | 4'h8: dout = 7'b 1111111; 183 | 4'h9: dout = 7'b 1101111; 184 | 4'hA: dout = 7'b 1110111; 185 | 4'hB: dout = 7'b 1111100; 186 | 4'hC: dout = 7'b 0111001; 187 | 4'hD: dout = 7'b 1011110; 188 | 4'hE: dout = 7'b 1111001; 189 | 4'hF: dout = 7'b 1110001; 190 | default: dout = 7'b 1000000; 191 | endcase 192 | endmodule 193 | -------------------------------------------------------------------------------- /stopwatch/guide/themes/infoq-screen-theme.yml: -------------------------------------------------------------------------------- 1 | font: 2 | catalog: 3 | Akkurat: 4 | normal: Akkurat-Light.ttf 5 | bold: Akkurat-Bold.ttf 6 | italic: Akkurat-Normal-Italic.ttf 7 | bold_italic: Akkurat-Bold-Italic.ttf 8 | # Noto Serif supports Latin, Latin-1 Supplement, Latin Extended-A, Greek, Cyrillic, Vietnamese & an assortment of symbols 9 | Noto Serif: 10 | normal: notoserif-regular-subset.ttf 11 | bold: notoserif-bold-subset.ttf 12 | italic: notoserif-italic-subset.ttf 13 | bold_italic: notoserif-bold_italic-subset.ttf 14 | # M+ 1mn supports ASCII and the circled numbers used for conums 15 | M+ 1mn: 16 | normal: mplus1mn-regular-ascii-conums.ttf 17 | bold: mplus1mn-bold-ascii.ttf 18 | italic: mplus1mn-italic-ascii.ttf 19 | bold_italic: mplus1mn-bold_italic-ascii.ttf 20 | # M+ 1p supports Latin, Latin-1 Supplement, Latin Extended, Greek, Cyrillic, Vietnamese, Japanese & an assortment of symbols 21 | # It also provides arrows for ->, <-, => and <= replacements in case these glyphs are missing from font 22 | M+ 1p Fallback: 23 | normal: mplus1p-regular-fallback.ttf 24 | bold: mplus1p-regular-fallback.ttf 25 | italic: mplus1p-regular-fallback.ttf 26 | bold_italic: mplus1p-regular-fallback.ttf 27 | fallbacks: 28 | - M+ 1p Fallback 29 | page: 30 | background_color: ffffff 31 | layout: portrait 32 | margin: [0.5in, 0.67in, 0.67in, 0.67in] 33 | size: LETTER 34 | base: 35 | align: justify 36 | # color as hex string (leading # is optional) 37 | font_color: 333333 38 | # color as RGB array 39 | #font_color: [51, 51, 51] 40 | # color as CMYK array (approximated) 41 | #font_color: [0, 0, 0, 0.92] 42 | #font_color: [0, 0, 0, 92%] 43 | font_family: Noto Serif 44 | # choose one of these font_size/line_height_length combinations 45 | #font_size: 14 46 | #line_height_length: 20 47 | #font_size: 11.25 48 | #line_height_length: 18 49 | #font_size: 11.2 50 | #line_height_length: 16 51 | font_size: 10.5 52 | #line_height_length: 15 53 | # correct line height for Noto Serif metrics 54 | line_height_length: 12 55 | #font_size: 11.25 56 | #line_height_length: 18 57 | line_height: $base_line_height_length / $base_font_size 58 | font_size_large: round($base_font_size * 1.25) 59 | font_size_small: round($base_font_size * 0.85) 60 | font_size_min: 7 61 | font_style: normal 62 | border_color: eeeeee 63 | border_radius: 4 64 | border_width: 0.5 65 | # FIXME vertical_rhythm is weird; we should think in terms of ems 66 | #vertical_rhythm: $base_line_height_length * 2 / 3 67 | # correct line height for Noto Serif metrics (comes with built-in line height) 68 | vertical_rhythm: $base_line_height_length 69 | horizontal_rhythm: $base_line_height_length 70 | # QUESTION should vertical_spacing be block_spacing instead? 71 | vertical_spacing: $vertical_rhythm 72 | link: 73 | font_color: 428bca 74 | # literal is currently used for inline monospaced in prose and table cells 75 | literal: 76 | font_color: b12146 77 | font_family: M+ 1mn 78 | heading: 79 | #font_color: 181818 80 | font_color: $base_font_color 81 | font_family: $base_font_family 82 | font_style: bold 83 | # h1 is used for part titles 84 | h1_font_size: floor($base_font_size * 2.6) 85 | # h2 is used for chapter titles 86 | h2_font_size: floor($base_font_size * 2.15) 87 | h3_font_size: round($base_font_size * 1.7) 88 | h4_font_size: $base_font_size_large 89 | h5_font_size: $base_font_size 90 | h6_font_size: $base_font_size_small 91 | #line_height: 1.4 92 | # correct line height for Noto Serif metrics (comes with built-in line height) 93 | line_height: 1.2 94 | margin_top: $vertical_rhythm * 0.2 95 | margin_bottom: $vertical_rhythm * 0.8 96 | title_page: 97 | align: center 98 | # hide text by default 99 | font_color: ffffff 100 | font_family: Akkurat 101 | font_style: bold 102 | title: 103 | top: 10% 104 | font_size: $heading_h1_font_size * 2 105 | font_color: 181818 106 | text_transform: uppercase 107 | line_height: 1.25 108 | authors: 109 | margin_top: 445.0 110 | font_size: $heading_h1_font_size 111 | font_color: 181818 112 | revision: 113 | margin_top: 0 114 | block: 115 | margin_top: 0 116 | margin_bottom: $vertical_rhythm 117 | caption: 118 | align: left 119 | font_style: italic 120 | # FIXME perhaps set line_height instead of / in addition to margins? 121 | margin_inside: $vertical_rhythm / 3 122 | #margin_inside: $vertical_rhythm / 4 123 | margin_outside: 0 124 | lead: 125 | font_size: $base_font_size_large 126 | line_height: 1.4 127 | abstract: 128 | font_color: 5c6266 129 | font_size: $lead_font_size 130 | line_height: $lead_line_height 131 | font_style: italic 132 | admonition: 133 | column_rule_color: $base_border_color 134 | column_rule_width: $base_border_width 135 | padding: [0, $horizontal_rhythm, 0, $horizontal_rhythm] 136 | blockquote: 137 | font_color: $base_font_color 138 | font_size: $base_font_size_large 139 | border_color: $base_border_color 140 | border_width: 5 141 | padding: [$vertical_rhythm / 2, $horizontal_rhythm, $vertical_rhythm / -2, $horizontal_rhythm + $blockquote_border_width / 2] 142 | cite_font_size: $base_font_size_small 143 | cite_font_color: 999999 144 | # code is used for source blocks (perhaps change to source or listing?) 145 | code: 146 | font_color: $base_font_color 147 | font_family: $literal_font_family 148 | font_size: ceil($base_font_size) 149 | padding: $code_font_size 150 | line_height: 1.25 151 | background_color: f5f5f5 152 | border_color: cccccc 153 | border_radius: $base_border_radius 154 | border_width: 0.75 155 | conum: 156 | font_family: M+ 1mn 157 | font_color: $literal_font_color 158 | font_size: $base_font_size 159 | line_height: 4 / 3 160 | example: 161 | border_color: $base_border_color 162 | border_radius: $base_border_radius 163 | border_width: 0.75 164 | background_color: transparent 165 | # FIXME reenable margin bottom once margin collapsing is implemented 166 | padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm] 167 | image: 168 | align: left 169 | prose: 170 | margin_top: 0 171 | margin_bottom: $vertical_rhythm 172 | sidebar: 173 | border_color: $page_background_color 174 | border_radius: $base_border_radius 175 | border_width: $base_border_width 176 | background_color: eeeeee 177 | # FIXME reenable margin bottom once margin collapsing is implemented 178 | padding: [$vertical_rhythm, $vertical_rhythm * 1.25, 0, $vertical_rhythm * 1.25] 179 | title: 180 | align: center 181 | font_color: $heading_font_color 182 | font_family: $heading_font_family 183 | font_size: $heading_h4_font_size 184 | font_style: $heading_font_style 185 | thematic_break: 186 | border_color: $base_border_color 187 | border_style: solid 188 | border_width: $base_border_width 189 | margin_top: $vertical_rhythm * 0.5 190 | margin_bottom: $vertical_rhythm * 1.5 191 | description_list: 192 | term_font_style: italic 193 | term_spacing: $vertical_rhythm / 4 194 | description_indent: $horizontal_rhythm * 1.25 195 | outline_list: 196 | indent: $horizontal_rhythm * 1.5 197 | # NOTE item_spacing applies to list items that do not have complex content 198 | item_spacing: $vertical_rhythm / 2 199 | #marker_font_color: 404040 200 | table: 201 | background_color: $page_background_color 202 | #head_background_color: 203 | #head_font_color: $base_font_color 204 | head_font_style: bold 205 | even_row_background_color: f9f9f9 206 | #odd_row_background_color: 207 | foot_background_color: f0f0f0 208 | border_color: dddddd 209 | border_width: $base_border_width 210 | # HACK accounting for line-height 211 | cell_padding: [3, 3, 6, 3] 212 | toc: 213 | dot_leader_font_color: a9a9a9 214 | #dot_leader_content: '. ' 215 | indent: $horizontal_rhythm 216 | line_height: 1.4 217 | header: 218 | font_color: A6A6A6 219 | height: 0.5in 220 | line_height: 1 221 | columns: =100% 222 | recto: 223 | center: 224 | content: '{chapter-title}' 225 | verso: 226 | center: 227 | content: '{document-title}' 228 | footer: 229 | font_color: [61, 51, 45, 5] 230 | font_size: $base_font_size_small 231 | font_style: bold 232 | height: 0.5in 233 | line_height: 1 234 | columns: <50% >50% 235 | recto: 236 | right: 237 | content: '{page-number}' 238 | verso: 239 | left: 240 | content: '{page-number}' 241 | -------------------------------------------------------------------------------- /stopwatch/guide/themes/infoq-prepress-theme.yml: -------------------------------------------------------------------------------- 1 | font: 2 | catalog: 3 | Akkurat: 4 | normal: notoserif-regular-subset.ttf 5 | bold: notoserif-bold-subset.ttf 6 | italic: notoserif-italic-subset.ttf 7 | bold_italic: notoserif-bold_italic-subset.ttf 8 | # Noto Serif supports Latin, Latin-1 Supplement, Latin Extended-A, Greek, Cyrillic, Vietnamese & an assortment of symbols 9 | Noto Serif: 10 | normal: notoserif-regular-subset.ttf 11 | bold: notoserif-bold-subset.ttf 12 | italic: notoserif-italic-subset.ttf 13 | bold_italic: notoserif-bold_italic-subset.ttf 14 | # M+ 1mn supports ASCII and the circled numbers used for conums 15 | M+ 1mn: 16 | normal: mplus1mn-regular-ascii-conums.ttf 17 | bold: mplus1mn-bold-ascii.ttf 18 | italic: mplus1mn-italic-ascii.ttf 19 | bold_italic: mplus1mn-bold_italic-ascii.ttf 20 | # M+ 1p supports Latin, Latin-1 Supplement, Latin Extended, Greek, Cyrillic, Vietnamese, Japanese & an assortment of symbols 21 | # It also provides arrows for ->, <-, => and <= replacements in case these glyphs are missing from font 22 | M+ 1p Fallback: 23 | normal: mplus1p-regular-fallback.ttf 24 | bold: mplus1p-regular-fallback.ttf 25 | italic: mplus1p-regular-fallback.ttf 26 | bold_italic: mplus1p-regular-fallback.ttf 27 | fallbacks: 28 | - M+ 1p Fallback 29 | page: 30 | background_color: ffffff 31 | layout: portrait 32 | # NOTE margin_inner and margin_outer replace side margins when media=prepress 33 | margin: [0.6in, 0.75in, 0.5in, 0.75in] 34 | margin_inner: 1in 35 | margin_outer: 0.5in 36 | size: [6in, 9in] 37 | base: 38 | align: justify 39 | # color as hex string (leading # is optional) 40 | font_color: 333333 41 | # color as RGB array 42 | #font_color: [51, 51, 51] 43 | # color as CMYK array (approximated) 44 | #font_color: [0, 0, 0, 0.92] 45 | #font_color: [0, 0, 0, 92%] 46 | font_family: Noto Serif 47 | # choose one of these font_size/line_height_length combinations 48 | #font_size: 14 49 | #line_height_length: 20 50 | #font_size: 11.25 51 | #line_height_length: 18 52 | #font_size: 11.2 53 | #line_height_length: 16 54 | font_size: 9 55 | #line_height_length: 15 56 | # correct line height for Noto Serif metrics 57 | line_height_length: 10.25 58 | #font_size: 11.25 59 | #line_height_length: 18 60 | line_height: $base_line_height_length / $base_font_size 61 | font_size_large: round($base_font_size * 1.25) 62 | font_size_small: round($base_font_size * 0.85) 63 | font_size_min: 4 64 | font_style: normal 65 | border_color: eeeeee 66 | border_radius: 4 67 | border_width: 0.35 68 | # FIXME vertical_rhythm is weird; we should think in terms of ems 69 | #vertical_rhythm: $base_line_height_length * 2 / 3 70 | # correct line height for Noto Serif metrics (comes with built-in line height) 71 | vertical_rhythm: $base_line_height_length 72 | horizontal_rhythm: $base_line_height_length 73 | # QUESTION should vertical_spacing be block_spacing instead? 74 | vertical_spacing: $vertical_rhythm 75 | link: 76 | font_color: 333333 #428bca 77 | # literal is currently used for inline monospaced in prose and table cells 78 | literal: 79 | font_color: 333333 #b12146 80 | font_family: M+ 1mn 81 | heading: 82 | #font_color: 181818 83 | font_color: $base_font_color 84 | font_family: $base_font_family 85 | font_style: bold 86 | # h1 is used for part titles 87 | h1_font_size: floor($base_font_size * 2.6) 88 | # h2 is used for chapter titles 89 | h2_font_size: floor($base_font_size * 2.15) 90 | h3_font_size: round($base_font_size * 1.7) 91 | h4_font_size: $base_font_size_large 92 | h5_font_size: $base_font_size 93 | h6_font_size: $base_font_size_small 94 | #line_height: 1.4 95 | # correct line height for Noto Serif metrics (comes with built-in line height) 96 | line_height: 1.2 97 | margin_top: $vertical_rhythm * 0.2 98 | margin_bottom: $vertical_rhythm * 0.8 99 | title_page: 100 | align: center 101 | # hide text by default 102 | font_color: ffffff 103 | font_family: Akkurat 104 | font_style: bold 105 | title: 106 | top: 4% 107 | font_size: $heading_h1_font_size * 1.75 108 | font_color: 181818 109 | text_transform: uppercase 110 | line_height: 1.25 111 | authors: 112 | margin_top: 390.0 113 | font_size: $heading_h1_font_size 114 | font_color: 181818 115 | revision: 116 | margin_top: 0 117 | block: 118 | margin_top: 0 119 | margin_bottom: $vertical_rhythm 120 | caption: 121 | align: left 122 | font_style: italic 123 | # FIXME perhaps set line_height instead of / in addition to margins? 124 | margin_inside: $vertical_rhythm / 3 125 | #margin_inside: $vertical_rhythm / 4 126 | margin_outside: 0 127 | lead: 128 | font_size: $base_font_size_large 129 | line_height: 1.4 130 | abstract: 131 | font_color: 333333 #5c6266 132 | font_size: $lead_font_size 133 | line_height: $lead_line_height 134 | font_style: italic 135 | admonition: 136 | column_rule_color: $base_border_color 137 | column_rule_width: $base_border_width 138 | padding: [0, $horizontal_rhythm, 0, $horizontal_rhythm] 139 | blockquote: 140 | font_color: $base_font_color 141 | font_size: $base_font_size_large 142 | border_color: $base_border_color 143 | border_width: 3.5 144 | padding: [$vertical_rhythm / 2, $horizontal_rhythm, $vertical_rhythm / -2, $horizontal_rhythm + $blockquote_border_width / 2] 145 | cite_font_size: $base_font_size_small 146 | cite_font_color: 333333 #999999 147 | # code is used for source blocks (perhaps change to source or listing?) 148 | code: 149 | font_color: $base_font_color 150 | font_family: $literal_font_family 151 | font_size: 8 152 | padding: $code_font_size 153 | line_height: 1.25 154 | background_color: ffffff 155 | border_color: cccccc 156 | border_radius: $base_border_radius 157 | border_width: 0 158 | conum: 159 | font_family: M+ 1mn 160 | font_color: $literal_font_color 161 | font_size: $base_font_size 162 | line_height: 4 / 3 163 | example: 164 | border_color: $base_border_color 165 | border_radius: $base_border_radius 166 | border_width: 0.5 167 | background_color: transparent 168 | # FIXME reenable margin bottom once margin collapsing is implemented 169 | padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm] 170 | image: 171 | align: left 172 | prose: 173 | margin_top: 0 174 | margin_bottom: $vertical_rhythm 175 | sidebar: 176 | border_color: B8B8B8 #$page_background_color 177 | border_radius: $base_border_radius 178 | border_width: $base_border_width 179 | background_color: eeeeee 180 | # FIXME reenable margin bottom once margin collapsing is implemented 181 | padding: [$vertical_rhythm, $vertical_rhythm * 1.25, 0, $vertical_rhythm * 1.25] 182 | title: 183 | align: center 184 | font_color: $heading_font_color 185 | font_family: $heading_font_family 186 | font_size: $heading_h4_font_size 187 | font_style: $heading_font_style 188 | thematic_break: 189 | border_color: $base_border_color 190 | border_style: solid 191 | border_width: $base_border_width 192 | margin_top: $vertical_rhythm * 0.5 193 | margin_bottom: $vertical_rhythm * 1.5 194 | description_list: 195 | term_font_style: italic 196 | term_spacing: $vertical_rhythm / 4 197 | description_indent: $horizontal_rhythm * 1.25 198 | outline_list: 199 | indent: $horizontal_rhythm * 1.5 200 | # NOTE item_spacing applies to list items that do not have complex content 201 | item_spacing: $vertical_rhythm / 2 202 | #marker_font_color: 404040 203 | table: 204 | background_color: $page_background_color 205 | #head_background_color: 206 | #head_font_color: $base_font_color 207 | head_font_style: bold 208 | even_row_background_color: f9f9f9 209 | #odd_row_background_color: 210 | foot_background_color: f0f0f0 211 | border_color: dddddd 212 | border_width: $base_border_width 213 | # HACK accounting for line-height 214 | cell_padding: [2, 2, 4, 2] 215 | toc: 216 | dot_leader_font_color: a9a9a9 217 | #dot_leader_content: '. ' 218 | indent: $horizontal_rhythm 219 | line_height: 1.4 220 | header: 221 | font_color: 999999 #A6A6A6 222 | height: 0.5in 223 | line_height: 1 224 | columns: =100% 225 | recto: 226 | center: 227 | content: '{chapter-title}' 228 | verso: 229 | center: 230 | content: '{document-title}' 231 | footer: 232 | font_color: [61, 51, 45, 5] 233 | font_size: $base_font_size_small 234 | font_style: bold 235 | height: 0.5in 236 | line_height: 1 237 | columns: <50% >50% 238 | recto: 239 | right: 240 | content: '{page-number}' 241 | verso: 242 | left: 243 | content: '{page-number}' 244 | -------------------------------------------------------------------------------- /stopwatch/guide/themes/half-theme.yml: -------------------------------------------------------------------------------- 1 | font: 2 | catalog: 3 | # Noto Serif supports Latin, Latin-1 Supplement, Latin Extended-A, Greek, Cyrillic, Vietnamese & an assortment of symbols 4 | Noto Serif: 5 | normal: notoserif-regular-subset.ttf 6 | bold: notoserif-bold-subset.ttf 7 | italic: notoserif-italic-subset.ttf 8 | bold_italic: notoserif-bold_italic-subset.ttf 9 | # M+ 1mn supports ASCII and the circled numbers used for conums 10 | M+ 1mn: 11 | normal: mplus1mn-regular-ascii-conums.ttf 12 | bold: mplus1mn-bold-ascii.ttf 13 | italic: mplus1mn-italic-ascii.ttf 14 | bold_italic: mplus1mn-bold_italic-ascii.ttf 15 | # M+ 1p supports Latin, Latin-1 Supplement, Latin Extended, Greek, Cyrillic, Vietnamese, Japanese & an assortment of symbols 16 | # It also provides arrows for ->, <-, => and <= replacements in case these glyphs are missing from font 17 | M+ 1p Fallback: 18 | normal: mplus1p-regular-fallback.ttf 19 | bold: mplus1p-regular-fallback.ttf 20 | italic: mplus1p-regular-fallback.ttf 21 | bold_italic: mplus1p-regular-fallback.ttf 22 | fallbacks: 23 | - M+ 1p Fallback 24 | page: 25 | background_color: ffffff 26 | layout: portrait 27 | margin: [0.5in, 0.5in, 0.5in, 0.5in] 28 | # margin_inner and margin_outer keys are used for recto/verso print margins when media=prepress 29 | size: [5.5in, 8.5in] 30 | base: 31 | align: justify 32 | # color as hex string (leading # is optional) 33 | font_color: 333333 34 | # color as RGB array 35 | #font_color: [51, 51, 51] 36 | # color as CMYK array (approximated) 37 | #font_color: [0, 0, 0, 0.92] 38 | #font_color: [0, 0, 0, 92%] 39 | font_family: Noto Serif 40 | # choose one of these font_size/line_height_length combinations 41 | #font_size: 14 42 | #line_height_length: 20 43 | #font_size: 11.25 44 | #line_height_length: 18 45 | #font_size: 11.2 46 | #line_height_length: 16 47 | font_size: 10.5 48 | #line_height_length: 15 49 | # correct line height for Noto Serif metrics 50 | line_height_length: 12 51 | #font_size: 11.25 52 | #line_height_length: 18 53 | line_height: $base_line_height_length / $base_font_size 54 | font_size_large: round($base_font_size * 1.25) 55 | font_size_small: round($base_font_size * 0.85) 56 | font_size_min: $base_font_size * 0.75 57 | font_style: normal 58 | border_color: eeeeee 59 | border_radius: 4 60 | border_width: 0.5 61 | # FIXME vertical_rhythm is weird; we should think in terms of ems 62 | #vertical_rhythm: $base_line_height_length * 2 / 3 63 | # correct line height for Noto Serif metrics (comes with built-in line height) 64 | vertical_rhythm: $base_line_height_length 65 | horizontal_rhythm: $base_line_height_length 66 | # QUESTION should vertical_spacing be block_spacing instead? 67 | vertical_spacing: $vertical_rhythm 68 | link: 69 | font_color: 428bca 70 | # literal is currently used for inline monospaced in prose and table cells 71 | literal: 72 | font_color: b12146 73 | font_family: M+ 1mn 74 | menu_caret_content: " \u203a " 75 | heading: 76 | align: left 77 | #font_color: 181818 78 | font_color: $base_font_color 79 | font_family: $base_font_family 80 | font_style: bold 81 | # h1 is used for part titles (book doctype only) 82 | h1_font_size: floor($base_font_size * 2.6) 83 | # h2 is used for chapter titles (book doctype only) 84 | h2_font_size: floor($base_font_size * 2.15) 85 | h3_font_size: round($base_font_size * 1.7) 86 | h4_font_size: $base_font_size_large 87 | h5_font_size: $base_font_size 88 | h6_font_size: $base_font_size_small 89 | #line_height: 1.4 90 | # correct line height for Noto Serif metrics (comes with built-in line height) 91 | line_height: 1 92 | margin_top: $vertical_rhythm * 0.4 93 | margin_bottom: $vertical_rhythm * 0.9 94 | title_page: 95 | align: right 96 | logo: 97 | top: 10% 98 | title: 99 | top: 55% 100 | font_size: $heading_h1_font_size 101 | font_color: 999999 102 | line_height: 0.9 103 | subtitle: 104 | font_size: $heading_h3_font_size 105 | font_style: bold_italic 106 | line_height: 1 107 | authors: 108 | margin_top: $base_font_size * 1.25 109 | font_size: $base_font_size_large 110 | font_color: 181818 111 | revision: 112 | margin_top: $base_font_size * 1.25 113 | block: 114 | margin_top: 0 115 | margin_bottom: $vertical_rhythm 116 | caption: 117 | align: left 118 | font_size: $base_font_size * 0.95 119 | font_style: italic 120 | # FIXME perhaps set line_height instead of / in addition to margins? 121 | margin_inside: $vertical_rhythm / 3 122 | #margin_inside: $vertical_rhythm / 4 123 | margin_outside: 0 124 | lead: 125 | font_size: $base_font_size_large 126 | line_height: 1.4 127 | abstract: 128 | font_color: 5c6266 129 | font_size: $lead_font_size 130 | line_height: $lead_line_height 131 | font_style: italic 132 | first_line_font_style: bold 133 | title: 134 | align: center 135 | font_color: $heading_font_color 136 | font_family: $heading_font_family 137 | font_size: $heading_h4_font_size 138 | font_style: $heading_font_style 139 | admonition: 140 | column_rule_color: $base_border_color 141 | column_rule_width: $base_border_width 142 | padding: [0, $horizontal_rhythm, 0, $horizontal_rhythm] 143 | #icon: 144 | # tip: 145 | # name: fa-lightbulb-o 146 | # stroke_color: 111111 147 | # size: 24 148 | label: 149 | text_transform: uppercase 150 | font_style: bold 151 | blockquote: 152 | font_color: $base_font_color 153 | font_size: $base_font_size_large 154 | border_color: $base_border_color 155 | border_width: 5 156 | # FIXME disable negative padding bottom once margin collapsing is implemented 157 | padding: [0, $horizontal_rhythm, $block_margin_bottom * -0.75, $horizontal_rhythm + $blockquote_border_width / 2] 158 | cite_font_size: $base_font_size_small 159 | cite_font_color: 999999 160 | # code is used for source blocks (perhaps change to source or listing?) 161 | code: 162 | font_color: $base_font_color 163 | font_family: $literal_font_family 164 | font_size: ceil($base_font_size) 165 | padding: $code_font_size 166 | line_height: 1.25 167 | # line_gap is an experimental property to control how a background color is applied to an inline block element 168 | line_gap: 3.8 169 | background_color: f5f5f5 170 | border_color: cccccc 171 | border_radius: $base_border_radius 172 | border_width: 0.75 173 | conum: 174 | font_family: M+ 1mn 175 | font_color: $literal_font_color 176 | font_size: $base_font_size 177 | line_height: 4 / 3 178 | example: 179 | border_color: $base_border_color 180 | border_radius: $base_border_radius 181 | border_width: 0.75 182 | background_color: ffffff 183 | # FIXME reenable padding bottom once margin collapsing is implemented 184 | padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm] 185 | image: 186 | align: center 187 | prose: 188 | margin_top: $block_margin_top 189 | margin_bottom: $block_margin_bottom 190 | sidebar: 191 | background_color: eeeeee 192 | border_color: e1e1e1 193 | border_radius: $base_border_radius 194 | border_width: $base_border_width 195 | # FIXME reenable padding bottom once margin collapsing is implemented 196 | padding: [$vertical_rhythm, $vertical_rhythm * 1.25, 0, $vertical_rhythm * 1.25] 197 | title: 198 | align: center 199 | font_color: $heading_font_color 200 | font_family: $heading_font_family 201 | font_size: $heading_h4_font_size 202 | font_style: $heading_font_style 203 | thematic_break: 204 | border_color: $base_border_color 205 | border_style: solid 206 | border_width: $base_border_width 207 | margin_top: $vertical_rhythm * 0.5 208 | margin_bottom: $vertical_rhythm * 1.5 209 | description_list: 210 | term_font_style: bold 211 | term_spacing: $vertical_rhythm / 4 212 | description_indent: $horizontal_rhythm * 1.25 213 | outline_list: 214 | indent: $horizontal_rhythm * 1.5 215 | #marker_font_color: 404040 216 | # NOTE outline_list_item_spacing applies to list items that do not have complex content 217 | item_spacing: $vertical_rhythm / 2 218 | table: 219 | background_color: $page_background_color 220 | #head_background_color: 221 | #head_font_color: $base_font_color 222 | head_font_style: bold 223 | #body_background_color: 224 | body_stripe_background_color: f9f9f9 225 | foot_background_color: f0f0f0 226 | border_color: dddddd 227 | border_width: $base_border_width 228 | cell_padding: 3 229 | toc: 230 | indent: $horizontal_rhythm 231 | line_height: 1.4 232 | dot_leader: 233 | #content: ". " 234 | font_color: a9a9a9 235 | #levels: 2 3 236 | # NOTE in addition to footer, header is also supported 237 | footer: 238 | font_size: $base_font_size_small 239 | # NOTE if background_color is set, background and border will span width of page 240 | border_color: dddddd 241 | border_width: 0.25 242 | height: $base_line_height_length * 2.5 243 | line_height: 1 244 | padding: [$base_line_height_length / 2, 1, 0, 1] 245 | vertical_align: top 246 | #image_vertical_align: or 247 | # additional attributes for content: 248 | # * {page-count} 249 | # * {page-number} 250 | # * {document-title} 251 | # * {document-subtitle} 252 | # * {chapter-title} 253 | # * {section-title} 254 | # * {section-or-chapter-title} 255 | recto: 256 | #columns: "<50% =0% >50%" 257 | right: 258 | content: '{page-number}' 259 | #content: '{section-or-chapter-title} | {page-number}' 260 | #content: '{document-title} | {page-number}' 261 | #center: 262 | # content: '{page-number}' 263 | verso: 264 | #columns: $footer_recto_columns 265 | left: 266 | content: $footer_recto_right_content 267 | #content: '{page-number} | {chapter-title}' 268 | #center: 269 | # content: '{page-number}' 270 | -------------------------------------------------------------------------------- /stopwatch/guide/themes/pae-theme.yml: -------------------------------------------------------------------------------- 1 | font: 2 | catalog: 3 | # Noto Serif supports Latin, Latin-1 Supplement, Latin Extended-A, Greek, Cyrillic, Vietnamese & an assortment of symbols 4 | Noto Serif: 5 | normal: notoserif-regular-subset.ttf 6 | bold: notoserif-bold-subset.ttf 7 | italic: notoserif-italic-subset.ttf 8 | bold_italic: notoserif-bold_italic-subset.ttf 9 | # M+ 1mn supports ASCII and the circled numbers used for conums 10 | M+ 1mn: 11 | normal: mplus1mn-regular-ascii-conums.ttf 12 | bold: mplus1mn-bold-ascii.ttf 13 | italic: mplus1mn-italic-ascii.ttf 14 | bold_italic: mplus1mn-bold_italic-ascii.ttf 15 | # M+ 1p supports Latin, Latin-1 Supplement, Latin Extended, Greek, Cyrillic, Vietnamese, Japanese & an assortment of symbols 16 | # It also provides arrows for ->, <-, => and <= replacements in case these glyphs are missing from font 17 | M+ 1p Fallback: 18 | normal: mplus1p-regular-fallback.ttf 19 | bold: mplus1p-regular-fallback.ttf 20 | italic: mplus1p-regular-fallback.ttf 21 | bold_italic: mplus1p-regular-fallback.ttf 22 | fallbacks: 23 | - M+ 1p Fallback 24 | page: 25 | background_color: ffffff 26 | layout: portrait 27 | margin: [0.75in, 0.77in, 0.77in, 0.75in] 28 | # margin_inner and margin_outer keys are used for recto/verso print margins when media=prepress 29 | margin_inner: 0.75in 30 | margin_outer: 1.75in 31 | size: letter 32 | base: 33 | align: justify 34 | # color as hex string (leading # is optional) 35 | font_color: 000000 36 | # color as RGB array 37 | #font_color: [51, 51, 51] 38 | # color as CMYK array (approximated) 39 | #font_color: [0, 0, 0, 0.92] 40 | #font_color: [0, 0, 0, 92%] 41 | font_family: Noto Serif 42 | # choose one of these font_size/line_height_length combinations 43 | #font_size: 14 44 | #line_height_length: 20 45 | #font_size: 11.25 46 | #line_height_length: 18 47 | #font_size: 11.2 48 | #line_height_length: 16 49 | #font_size: 10.5 50 | #line_height_length: 15 51 | # correct line height for Noto Serif metrics 52 | #line_height_length: 12 53 | #font_size: 11.25 54 | #line_height_length: 18 55 | font_size: 12 56 | line_height_length: 14 57 | line_height: $base_line_height_length / $base_font_size 58 | font_size_large: round($base_font_size * 1.25) 59 | font_size_small: round($base_font_size * 0.85) 60 | font_size_min: $base_font_size * 0.75 61 | font_style: normal 62 | border_color: eeeeee 63 | border_radius: 4 64 | border_width: 0.5 65 | # FIXME vertical_rhythm is weird; we should think in terms of ems 66 | #vertical_rhythm: $base_line_height_length * 2 / 3 67 | # correct line height for Noto Serif metrics (comes with built-in line height) 68 | vertical_rhythm: $base_line_height_length 69 | horizontal_rhythm: $base_line_height_length 70 | # QUESTION should vertical_spacing be block_spacing instead? 71 | vertical_spacing: $vertical_rhythm 72 | link: 73 | font_color: 428bca 74 | # literal is currently used for inline monospaced in prose and table cells 75 | literal: 76 | font_color: b12146 77 | font_family: M+ 1mn 78 | font_style: bold 79 | menu_caret_content: " \u203a " 80 | heading: 81 | align: left 82 | #font_color: 181818 83 | font_color: $base_font_color 84 | font_family: $base_font_family 85 | font_style: bold 86 | # h1 is used for part titles (book doctype only) 87 | h1_font_size: floor($base_font_size * 2.6) 88 | # h2 is used for chapter titles (book doctype only) 89 | h2_font_size: floor($base_font_size * 2.15) 90 | h3_font_size: round($base_font_size * 1.7) 91 | h4_font_size: $base_font_size_large 92 | h5_font_size: $base_font_size 93 | h6_font_size: $base_font_size_small 94 | #line_height: 1.4 95 | # correct line height for Noto Serif metrics (comes with built-in line height) 96 | line_height: 1 97 | margin_top: $vertical_rhythm * 0.4 98 | margin_bottom: $vertical_rhythm * 0.9 99 | title_page: 100 | align: right 101 | background: 102 | image: cover.png 103 | logo: 104 | bottom: 10% 105 | title: 106 | top: 45% 107 | font_size: $heading_h1_font_size 108 | font_color: aaaaaa 109 | line_height: 0.9 110 | subtitle: 111 | font_size: $heading_h3_font_size 112 | font_color: aaaaaa 113 | font_style: italic 114 | line_height: 1 115 | authors: 116 | margin_top: $base_font_size * 1.25 117 | font_size: $base_font_size_large 118 | font_color: 181818 119 | revision: 120 | margin_top: $base_font_size * 1.25 121 | block: 122 | margin_top: 0 123 | margin_bottom: $vertical_rhythm 124 | caption: 125 | align: left 126 | font_size: $base_font_size * 1.1 127 | font_style: bold_italic 128 | # FIXME perhaps set line_height instead of / in addition to margins? 129 | margin_inside: $vertical_rhythm / 3 130 | #margin_inside: $vertical_rhythm / 4 131 | margin_outside: 0 132 | lead: 133 | font_size: $base_font_size_large 134 | line_height: 1.4 135 | abstract: 136 | font_color: 5c6266 137 | font_size: $lead_font_size 138 | line_height: $lead_line_height 139 | font_style: italic 140 | first_line_font_style: bold 141 | title: 142 | align: center 143 | font_color: $heading_font_color 144 | font_family: $heading_font_family 145 | font_size: $heading_h4_font_size 146 | font_style: $heading_font_style 147 | admonition: 148 | column_rule_color: $base_border_color 149 | column_rule_width: $base_border_width 150 | padding: [0, $horizontal_rhythm, 0, $horizontal_rhythm] 151 | #icon: 152 | # tip: 153 | # name: fa-lightbulb-o 154 | # stroke_color: 111111 155 | # size: 24 156 | label: 157 | text_transform: uppercase 158 | font_style: bold 159 | blockquote: 160 | font_color: $base_font_color 161 | font_size: $base_font_size_large 162 | border_color: $base_border_color 163 | border_width: 5 164 | # FIXME disable negative padding bottom once margin collapsing is implemented 165 | padding: [0, $horizontal_rhythm, $block_margin_bottom * -0.75, $horizontal_rhythm + $blockquote_border_width / 2] 166 | cite_font_size: $base_font_size_small 167 | cite_font_color: 999999 168 | # code is used for source blocks (perhaps change to source or listing?) 169 | code: 170 | font_color: $base_font_color 171 | font_family: $literal_font_family 172 | font_size: ceil($base_font_size) 173 | font_style: bold 174 | padding: $code_font_size 175 | line_height: 1.25 176 | # line_gap is an experimental property to control how a background color is applied to an inline block element 177 | line_gap: 3.8 178 | background_color: f5f5f5 179 | border_color: cccccc 180 | border_radius: $base_border_radius 181 | border_width: 0.75 182 | conum: 183 | font_family: M+ 1mn 184 | font_color: $literal_font_color 185 | font_size: $base_font_size 186 | line_height: 4 / 3 187 | example: 188 | border_color: $base_border_color 189 | border_radius: $base_border_radius 190 | border_width: 0.75 191 | background_color: ffffff 192 | # FIXME reenable padding bottom once margin collapsing is implemented 193 | padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm] 194 | image: 195 | align: center 196 | prose: 197 | margin_top: $block_margin_top 198 | margin_bottom: $block_margin_bottom 199 | sidebar: 200 | background_color: eeeeee 201 | border_color: e1e1e1 202 | border_radius: $base_border_radius 203 | border_width: $base_border_width 204 | # FIXME reenable padding bottom once margin collapsing is implemented 205 | padding: [$vertical_rhythm, $vertical_rhythm * 1.25, 0, $vertical_rhythm * 1.25] 206 | title: 207 | align: center 208 | font_color: $heading_font_color 209 | font_family: $heading_font_family 210 | font_size: $heading_h4_font_size 211 | font_style: $heading_font_style 212 | thematic_break: 213 | border_color: $base_border_color 214 | border_style: solid 215 | border_width: $base_border_width 216 | margin_top: $vertical_rhythm * 0.5 217 | margin_bottom: $vertical_rhythm * 1.5 218 | description_list: 219 | term_font_style: bold 220 | term_spacing: $vertical_rhythm / 4 221 | description_indent: $horizontal_rhythm * 1.25 222 | outline_list: 223 | indent: $horizontal_rhythm * 1.5 224 | #marker_font_color: 404040 225 | # NOTE outline_list_item_spacing applies to list items that do not have complex content 226 | item_spacing: $vertical_rhythm / 3 227 | table: 228 | background_color: $page_background_color 229 | #head_background_color: 230 | #head_font_color: $base_font_color 231 | head_font_style: bold 232 | #body_background_color: 233 | body_stripe_background_color: f9f9f9 234 | foot_background_color: f0f0f0 235 | border_color: dddddd 236 | border_width: $base_border_width 237 | cell_padding: 3 238 | toc: 239 | indent: $horizontal_rhythm 240 | line_height: 1.4 241 | dot_leader: 242 | #content: ". " 243 | font_color: a9a9a9 244 | #levels: 2 3 245 | # NOTE in addition to footer, header is also supported 246 | header: 247 | font_size: $base_font_size_small 248 | font_color: 888888 249 | # NOTE if background_color is set, background and border will span width of page 250 | border_color: 888888 251 | border_width: 0 252 | height: $base_line_height_length * 2.5 253 | line_height: 2 254 | padding: [$base_line_height_length / 2, 1, 0, 1] 255 | vertical_align: top 256 | recto: 257 | right: 258 | content: '{section-title}' 259 | verso: 260 | left: 261 | content: '{section-title}' 262 | footer: 263 | font_size: $base_font_size_small 264 | #font_color: 888888 265 | # NOTE if background_color is set, background and border will span width of page 266 | border_color: 888888 267 | border_width: 0.25 268 | height: $base_line_height_length * 2.5 269 | line_height: 1 270 | padding: [$base_line_height_length / 2, 1, 0, 1] 271 | vertical_align: top 272 | #image_vertical_align: or 273 | # additional attributes for content: 274 | # * {page-count} 275 | # * {page-number} 276 | # * {document-title} 277 | # * {document-subtitle} 278 | # * {chapter-title} 279 | # * {section-title} 280 | # * {section-or-chapter-title} 281 | recto: 282 | #columns: "<50% =0% >50%" 283 | right: 284 | content: '{chapter-title} | {page-number}' 285 | verso: 286 | #columns: $footer_recto_columns 287 | left: 288 | content: '{page-number} | {document-title}' 289 | right: 290 | content: '(C)2019 1BitSquared.com' 291 | -------------------------------------------------------------------------------- /stopwatch/guide/themes/fullsize-theme.yml: -------------------------------------------------------------------------------- 1 | font: 2 | catalog: 3 | # Noto Serif supports Latin, Latin-1 Supplement, Latin Extended-A, Greek, Cyrillic, Vietnamese & an assortment of symbols 4 | Noto Serif: 5 | normal: notoserif-regular-subset.ttf 6 | bold: notoserif-bold-subset.ttf 7 | italic: notoserif-italic-subset.ttf 8 | bold_italic: notoserif-bold_italic-subset.ttf 9 | # M+ 1mn supports ASCII and the circled numbers used for conums 10 | M+ 1mn: 11 | normal: mplus1mn-regular-ascii-conums.ttf 12 | bold: mplus1mn-bold-ascii.ttf 13 | italic: mplus1mn-italic-ascii.ttf 14 | bold_italic: mplus1mn-bold_italic-ascii.ttf 15 | # M+ 1p supports Latin, Latin-1 Supplement, Latin Extended, Greek, Cyrillic, Vietnamese, Japanese & an assortment of symbols 16 | # It also provides arrows for ->, <-, => and <= replacements in case these glyphs are missing from font 17 | M+ 1p Fallback: 18 | normal: mplus1p-regular-fallback.ttf 19 | bold: mplus1p-regular-fallback.ttf 20 | italic: mplus1p-regular-fallback.ttf 21 | bold_italic: mplus1p-regular-fallback.ttf 22 | fallbacks: 23 | - M+ 1p Fallback 24 | page: 25 | background_color: ffffff 26 | layout: portrait 27 | margin: [0.75in, 0.75in, 0.75in, 0.75in] 28 | # margin_inner and margin_outer keys are used for recto/verso print margins when media=prepress 29 | margin_inner: 0.75in 30 | margin_outer: 0.75in 31 | size: letter 32 | base: 33 | align: justify 34 | # color as hex string (leading # is optional) 35 | font_color: 000000 36 | # color as RGB array 37 | #font_color: [51, 51, 51] 38 | # color as CMYK array (approximated) 39 | #font_color: [0, 0, 0, 0.92] 40 | #font_color: [0, 0, 0, 92%] 41 | font_family: Noto Serif 42 | # choose one of these font_size/line_height_length combinations 43 | #font_size: 14 44 | #line_height_length: 20 45 | #font_size: 11.25 46 | #line_height_length: 18 47 | #font_size: 11.2 48 | #line_height_length: 16 49 | font_size: 10.5 50 | #line_height_length: 15 51 | # correct line height for Noto Serif metrics 52 | line_height_length: 12 53 | #font_size: 11.25 54 | #line_height_length: 18 55 | #font_size: 12 56 | #line_height_length: 14 57 | line_height: $base_line_height_length / $base_font_size 58 | font_size_large: round($base_font_size * 1.25) 59 | font_size_small: round($base_font_size * 0.85) 60 | font_size_min: $base_font_size * 0.75 61 | font_style: normal 62 | border_color: eeeeee 63 | border_radius: 4 64 | border_width: 0.5 65 | # FIXME vertical_rhythm is weird; we should think in terms of ems 66 | #vertical_rhythm: $base_line_height_length * 2 / 3 67 | # correct line height for Noto Serif metrics (comes with built-in line height) 68 | vertical_rhythm: $base_line_height_length 69 | horizontal_rhythm: $base_line_height_length 70 | # QUESTION should vertical_spacing be block_spacing instead? 71 | vertical_spacing: $vertical_rhythm 72 | link: 73 | font_color: 428bca 74 | # literal is currently used for inline monospaced in prose and table cells 75 | literal: 76 | font_color: b12146 77 | font_family: M+ 1mn 78 | font_style: bold 79 | menu_caret_content: " \u203a " 80 | heading: 81 | align: left 82 | #font_color: 181818 83 | font_color: $base_font_color 84 | font_family: $base_font_family 85 | font_style: bold 86 | # h1 is used for part titles (book doctype only) 87 | h1_font_size: floor($base_font_size * 2.6) 88 | # h2 is used for chapter titles (book doctype only) 89 | h2_font_size: floor($base_font_size * 2.15) 90 | h3_font_size: round($base_font_size * 1.7) 91 | h4_font_size: $base_font_size_large 92 | h5_font_size: $base_font_size 93 | h6_font_size: $base_font_size_small 94 | #line_height: 1.4 95 | # correct line height for Noto Serif metrics (comes with built-in line height) 96 | line_height: 1 97 | margin_top: $vertical_rhythm * 0.4 98 | margin_bottom: $vertical_rhythm * 0.9 99 | title_page: 100 | align: right 101 | background: 102 | image: cover.png 103 | logo: 104 | bottom: 10% 105 | title: 106 | top: 45% 107 | font_size: $heading_h1_font_size 108 | font_color: aaaaaa 109 | line_height: 0.9 110 | subtitle: 111 | font_size: $heading_h3_font_size 112 | font_color: aaaaaa 113 | font_style: italic 114 | line_height: 1 115 | authors: 116 | margin_top: $base_font_size * 1.25 117 | font_size: $base_font_size_large 118 | font_color: 181818 119 | revision: 120 | margin_top: $base_font_size * 1.25 121 | block: 122 | margin_top: 0 123 | margin_bottom: $vertical_rhythm 124 | caption: 125 | align: left 126 | font_size: $base_font_size * 1.1 127 | font_style: bold_italic 128 | # FIXME perhaps set line_height instead of / in addition to margins? 129 | margin_inside: $vertical_rhythm / 3 130 | #margin_inside: $vertical_rhythm / 4 131 | margin_outside: 0 132 | lead: 133 | font_size: $base_font_size_large 134 | line_height: 1.4 135 | abstract: 136 | font_color: 5c6266 137 | font_size: $lead_font_size 138 | line_height: $lead_line_height 139 | font_style: italic 140 | first_line_font_style: bold 141 | title: 142 | align: center 143 | font_color: $heading_font_color 144 | font_family: $heading_font_family 145 | font_size: $heading_h4_font_size 146 | font_style: $heading_font_style 147 | admonition: 148 | column_rule_color: $base_border_color 149 | column_rule_width: $base_border_width 150 | padding: [0, $horizontal_rhythm, 0, $horizontal_rhythm] 151 | #icon: 152 | # tip: 153 | # name: fa-lightbulb-o 154 | # stroke_color: 111111 155 | # size: 24 156 | label: 157 | text_transform: uppercase 158 | font_style: bold 159 | blockquote: 160 | font_color: $base_font_color 161 | font_size: $base_font_size_large 162 | border_color: $base_border_color 163 | border_width: 5 164 | # FIXME disable negative padding bottom once margin collapsing is implemented 165 | padding: [0, $horizontal_rhythm, $block_margin_bottom * -0.75, $horizontal_rhythm + $blockquote_border_width / 2] 166 | cite_font_size: $base_font_size_small 167 | cite_font_color: 999999 168 | # code is used for source blocks (perhaps change to source or listing?) 169 | code: 170 | font_color: $base_font_color 171 | font_family: $literal_font_family 172 | font_size: ceil($base_font_size) 173 | font_style: bold 174 | padding: $code_font_size 175 | line_height: 1.25 176 | # line_gap is an experimental property to control how a background color is applied to an inline block element 177 | line_gap: 3.8 178 | background_color: f5f5f5 179 | border_color: cccccc 180 | border_radius: $base_border_radius 181 | border_width: 0.75 182 | conum: 183 | font_family: M+ 1mn 184 | font_color: $literal_font_color 185 | font_size: $base_font_size 186 | line_height: 4 / 3 187 | example: 188 | border_color: $base_border_color 189 | border_radius: $base_border_radius 190 | border_width: 0.75 191 | background_color: ffffff 192 | # FIXME reenable padding bottom once margin collapsing is implemented 193 | padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm] 194 | image: 195 | align: center 196 | prose: 197 | margin_top: $block_margin_top 198 | margin_bottom: $block_margin_bottom 199 | sidebar: 200 | background_color: eeeeee 201 | border_color: e1e1e1 202 | border_radius: $base_border_radius 203 | border_width: $base_border_width 204 | # FIXME reenable padding bottom once margin collapsing is implemented 205 | padding: [$vertical_rhythm, $vertical_rhythm * 1.25, 0, $vertical_rhythm * 1.25] 206 | title: 207 | align: center 208 | font_color: $heading_font_color 209 | font_family: $heading_font_family 210 | font_size: $heading_h4_font_size 211 | font_style: $heading_font_style 212 | thematic_break: 213 | border_color: $base_border_color 214 | border_style: solid 215 | border_width: $base_border_width 216 | margin_top: $vertical_rhythm * 0.5 217 | margin_bottom: $vertical_rhythm * 1.5 218 | description_list: 219 | term_font_style: bold 220 | term_spacing: $vertical_rhythm / 4 221 | description_indent: $horizontal_rhythm * 1.25 222 | outline_list: 223 | indent: $horizontal_rhythm * 1.5 224 | #marker_font_color: 404040 225 | # NOTE outline_list_item_spacing applies to list items that do not have complex content 226 | item_spacing: $vertical_rhythm / 3 227 | table: 228 | background_color: $page_background_color 229 | #head_background_color: 230 | #head_font_color: $base_font_color 231 | head_font_style: bold 232 | #body_background_color: 233 | body_stripe_background_color: f9f9f9 234 | foot_background_color: f0f0f0 235 | border_color: dddddd 236 | border_width: $base_border_width 237 | cell_padding: 3 238 | toc: 239 | indent: $horizontal_rhythm 240 | line_height: 1.4 241 | dot_leader: 242 | #content: ". " 243 | font_color: a9a9a9 244 | #levels: 2 3 245 | # NOTE in addition to footer, header is also supported 246 | header: 247 | font_size: $base_font_size_small 248 | font_color: 888888 249 | # NOTE if background_color is set, background and border will span width of page 250 | border_color: 888888 251 | border_width: 0 252 | height: $base_line_height_length * 2.5 253 | line_height: 2 254 | padding: [$base_line_height_length / 2, 1, 0, 1] 255 | vertical_align: top 256 | recto: 257 | right: 258 | content: '{section-title}' 259 | verso: 260 | left: 261 | content: '{section-title}' 262 | footer: 263 | font_size: $base_font_size_small 264 | #font_color: 888888 265 | # NOTE if background_color is set, background and border will span width of page 266 | border_color: 888888 267 | border_width: 0.25 268 | height: $base_line_height_length * 2.5 269 | line_height: 1 270 | padding: [$base_line_height_length / 2, 1, 0, 1] 271 | vertical_align: top 272 | #image_vertical_align: or 273 | # additional attributes for content: 274 | # * {page-count} 275 | # * {page-number} 276 | # * {document-title} 277 | # * {document-subtitle} 278 | # * {chapter-title} 279 | # * {section-title} 280 | # * {section-or-chapter-title} 281 | recto: 282 | #columns: "<50% =0% >50%" 283 | right: 284 | content: '{chapter-title} | {page-number}' 285 | verso: 286 | #columns: $footer_recto_columns 287 | left: 288 | content: '{page-number} | {document-title}' 289 | right: 290 | content: '(C)2019 1BitSquared.com' 291 | -------------------------------------------------------------------------------- /stopwatch/guide/themes/6x9-theme.yml: -------------------------------------------------------------------------------- 1 | font: 2 | catalog: 3 | # Noto Serif supports Latin, Latin-1 Supplement, Latin Extended-A, Greek, Cyrillic, Vietnamese & an assortment of symbols 4 | Noto Serif: 5 | normal: notoserif-regular-subset.ttf 6 | bold: notoserif-bold-subset.ttf 7 | italic: notoserif-italic-subset.ttf 8 | bold_italic: notoserif-bold_italic-subset.ttf 9 | # M+ 1mn supports ASCII and the circled numbers used for conums 10 | M+ 1mn: 11 | normal: mplus1mn-regular-ascii-conums.ttf 12 | bold: mplus1mn-bold-ascii.ttf 13 | italic: mplus1mn-italic-ascii.ttf 14 | bold_italic: mplus1mn-bold_italic-ascii.ttf 15 | # M+ 1p supports Latin, Latin-1 Supplement, Latin Extended, Greek, Cyrillic, Vietnamese, Japanese & an assortment of symbols 16 | # It also provides arrows for ->, <-, => and <= replacements in case these glyphs are missing from font 17 | M+ 1p Fallback: 18 | normal: mplus1p-regular-fallback.ttf 19 | bold: mplus1p-regular-fallback.ttf 20 | italic: mplus1p-regular-fallback.ttf 21 | bold_italic: mplus1p-regular-fallback.ttf 22 | fallbacks: 23 | - M+ 1p Fallback 24 | page: 25 | background_color: ffffff 26 | layout: portrait 27 | margin: [0.75in, 0.75in, 0.75in, 0.75in] 28 | # margin_inner and margin_outer keys are used for recto/verso print margins when media=prepress 29 | margin_inner: 0.75in 30 | margin_outer: 0.75in 31 | size: [6in, 9in] 32 | base: 33 | align: justify 34 | # color as hex string (leading # is optional) 35 | font_color: 000000 36 | # color as RGB array 37 | #font_color: [51, 51, 51] 38 | # color as CMYK array (approximated) 39 | #font_color: [0, 0, 0, 0.92] 40 | #font_color: [0, 0, 0, 92%] 41 | font_family: Noto Serif 42 | # choose one of these font_size/line_height_length combinations 43 | #font_size: 14 44 | #line_height_length: 20 45 | #font_size: 11.25 46 | #line_height_length: 18 47 | #font_size: 11.2 48 | #line_height_length: 16 49 | font_size: 10.5 50 | #line_height_length: 15 51 | # correct line height for Noto Serif metrics 52 | line_height_length: 12 53 | #font_size: 11.25 54 | #line_height_length: 18 55 | #font_size: 12 56 | #line_height_length: 14 57 | line_height: $base_line_height_length / $base_font_size 58 | font_size_large: round($base_font_size * 1.25) 59 | font_size_small: round($base_font_size * 0.85) 60 | font_size_min: $base_font_size * 0.75 61 | font_style: normal 62 | border_color: eeeeee 63 | border_radius: 4 64 | border_width: 0.5 65 | # FIXME vertical_rhythm is weird; we should think in terms of ems 66 | #vertical_rhythm: $base_line_height_length * 2 / 3 67 | # correct line height for Noto Serif metrics (comes with built-in line height) 68 | vertical_rhythm: $base_line_height_length 69 | horizontal_rhythm: $base_line_height_length 70 | # QUESTION should vertical_spacing be block_spacing instead? 71 | vertical_spacing: $vertical_rhythm 72 | link: 73 | font_color: 428bca 74 | # literal is currently used for inline monospaced in prose and table cells 75 | literal: 76 | font_color: b12146 77 | font_family: M+ 1mn 78 | font_style: bold 79 | menu_caret_content: " \u203a " 80 | heading: 81 | align: left 82 | #font_color: 181818 83 | font_color: $base_font_color 84 | font_family: $base_font_family 85 | font_style: bold 86 | # h1 is used for part titles (book doctype only) 87 | h1_font_size: floor($base_font_size * 2.6) 88 | # h2 is used for chapter titles (book doctype only) 89 | h2_font_size: floor($base_font_size * 2.15) 90 | h3_font_size: round($base_font_size * 1.7) 91 | h4_font_size: $base_font_size_large 92 | h5_font_size: $base_font_size 93 | h6_font_size: $base_font_size_small 94 | #line_height: 1.4 95 | # correct line height for Noto Serif metrics (comes with built-in line height) 96 | line_height: 1 97 | margin_top: $vertical_rhythm * 0.4 98 | margin_bottom: $vertical_rhythm * 0.9 99 | title_page: 100 | align: right 101 | background: 102 | #image: cover.png 103 | logo: 104 | bottom: 10% 105 | title: 106 | top: 45% 107 | font_size: $heading_h1_font_size * 0.9 108 | font_color: aaaaaa 109 | line_height: 0.9 110 | subtitle: 111 | font_size: $heading_h3_font_size 112 | font_color: aaaaaa 113 | font_style: italic 114 | line_height: 1 115 | authors: 116 | margin_top: $base_font_size * 1.25 117 | font_size: $base_font_size_large 118 | font_color: 181818 119 | revision: 120 | margin_top: $base_font_size * 1.25 121 | block: 122 | margin_top: 0 123 | margin_bottom: $vertical_rhythm 124 | caption: 125 | align: left 126 | font_size: $base_font_size * 1.1 127 | font_style: bold_italic 128 | # FIXME perhaps set line_height instead of / in addition to margins? 129 | margin_inside: $vertical_rhythm / 3 130 | #margin_inside: $vertical_rhythm / 4 131 | margin_outside: 0 132 | lead: 133 | font_size: $base_font_size_large 134 | line_height: 1.4 135 | abstract: 136 | font_color: 5c6266 137 | font_size: $lead_font_size 138 | line_height: $lead_line_height 139 | font_style: italic 140 | first_line_font_style: bold 141 | title: 142 | align: center 143 | font_color: $heading_font_color 144 | font_family: $heading_font_family 145 | font_size: $heading_h4_font_size 146 | font_style: $heading_font_style 147 | admonition: 148 | column_rule_color: $base_border_color 149 | column_rule_width: $base_border_width 150 | padding: [0, $horizontal_rhythm, 0, $horizontal_rhythm] 151 | #icon: 152 | # tip: 153 | # name: fa-lightbulb-o 154 | # stroke_color: 111111 155 | # size: 24 156 | label: 157 | text_transform: uppercase 158 | font_style: bold 159 | blockquote: 160 | font_color: $base_font_color 161 | font_size: $base_font_size_large 162 | border_color: $base_border_color 163 | border_width: 5 164 | # FIXME disable negative padding bottom once margin collapsing is implemented 165 | padding: [0, $horizontal_rhythm, $block_margin_bottom * -0.75, $horizontal_rhythm + $blockquote_border_width / 2] 166 | cite_font_size: $base_font_size_small 167 | cite_font_color: 999999 168 | # code is used for source blocks (perhaps change to source or listing?) 169 | code: 170 | font_color: $base_font_color 171 | font_family: $literal_font_family 172 | font_size: ceil($base_font_size) 173 | font_style: bold 174 | padding: $code_font_size 175 | line_height: 1.25 176 | # line_gap is an experimental property to control how a background color is applied to an inline block element 177 | line_gap: 3.8 178 | background_color: f5f5f5 179 | border_color: cccccc 180 | border_radius: $base_border_radius 181 | border_width: 0.75 182 | conum: 183 | font_family: M+ 1mn 184 | font_color: $literal_font_color 185 | font_size: $base_font_size 186 | line_height: 4 / 3 187 | example: 188 | border_color: $base_border_color 189 | border_radius: $base_border_radius 190 | border_width: 0.75 191 | background_color: ffffff 192 | # FIXME reenable padding bottom once margin collapsing is implemented 193 | padding: [$vertical_rhythm, $horizontal_rhythm, 0, $horizontal_rhythm] 194 | image: 195 | align: center 196 | prose: 197 | margin_top: $block_margin_top 198 | margin_bottom: $block_margin_bottom 199 | sidebar: 200 | background_color: eeeeee 201 | border_color: e1e1e1 202 | border_radius: $base_border_radius 203 | border_width: $base_border_width 204 | # FIXME reenable padding bottom once margin collapsing is implemented 205 | padding: [$vertical_rhythm, $vertical_rhythm * 1.25, 0, $vertical_rhythm * 1.25] 206 | title: 207 | align: center 208 | font_color: $heading_font_color 209 | font_family: $heading_font_family 210 | font_size: $heading_h4_font_size 211 | font_style: $heading_font_style 212 | thematic_break: 213 | border_color: $base_border_color 214 | border_style: solid 215 | border_width: $base_border_width 216 | margin_top: $vertical_rhythm * 0.5 217 | margin_bottom: $vertical_rhythm * 1.5 218 | description_list: 219 | term_font_style: bold 220 | term_spacing: $vertical_rhythm / 4 221 | description_indent: $horizontal_rhythm * 1.25 222 | outline_list: 223 | indent: $horizontal_rhythm * 1.5 224 | #marker_font_color: 404040 225 | # NOTE outline_list_item_spacing applies to list items that do not have complex content 226 | item_spacing: $vertical_rhythm / 3 227 | table: 228 | background_color: $page_background_color 229 | #head_background_color: 230 | #head_font_color: $base_font_color 231 | head_font_style: bold 232 | #body_background_color: 233 | body_stripe_background_color: f9f9f9 234 | foot_background_color: f0f0f0 235 | border_color: dddddd 236 | border_width: $base_border_width 237 | cell_padding: 3 238 | toc: 239 | indent: $horizontal_rhythm 240 | line_height: 1.4 241 | dot_leader: 242 | #content: ". " 243 | font_color: a9a9a9 244 | #levels: 2 3 245 | # NOTE in addition to footer, header is also supported 246 | header: 247 | font_size: $base_font_size_small 248 | font_color: 888888 249 | # NOTE if background_color is set, background and border will span width of page 250 | border_color: 888888 251 | border_width: 0 252 | height: $base_line_height_length * 2.5 253 | line_height: 2 254 | padding: [$base_line_height_length / 2, 1, 0, 1] 255 | vertical_align: top 256 | recto: 257 | right: 258 | content: '{section-title}' 259 | verso: 260 | left: 261 | content: '{section-title}' 262 | footer: 263 | font_size: $base_font_size_small 264 | #font_color: 888888 265 | # NOTE if background_color is set, background and border will span width of page 266 | border_color: 888888 267 | border_width: 0.25 268 | height: $base_line_height_length * 2.5 269 | line_height: 1 270 | padding: [$base_line_height_length / 2, 1, 0, 1] 271 | vertical_align: top 272 | #image_vertical_align: or 273 | # additional attributes for content: 274 | # * {page-count} 275 | # * {page-number} 276 | # * {document-title} 277 | # * {document-subtitle} 278 | # * {chapter-title} 279 | # * {section-title} 280 | # * {section-or-chapter-title} 281 | recto: 282 | #columns: "<50% =0% >50%" 283 | right: 284 | content: '{chapter-title} | {page-number}' 285 | verso: 286 | #columns: $footer_recto_columns 287 | left: 288 | content: '{page-number} | {document-title}' 289 | right: 290 | content: '(C)2019 1BitSquared.com' 291 | -------------------------------------------------------------------------------- /stopwatch/guide/icebreaker-fpga-stopwatch-workshop.adoc: -------------------------------------------------------------------------------- 1 | = iCEBreaker FPGA Stopwatch Workshop 2 | Piotr Esden-Tempski, Sylvain Munaut, Mike Walters and friends 3 | v2.1, 27 October 2021 4 | :doctype: book 5 | :imagesdir: images/ 6 | //:pdf-page-size: Executive 7 | :pdf-page-size: Letter 8 | //:pdf-page-size: [5.5in, 8.5in] 9 | //:pdf-page-size: [6in, 9in] 10 | :media: prepress 11 | //:pdf-style: half 12 | //:pdf-style: pae 13 | :pdf-style: 6x9 14 | :pdf-stylesdir: ./themes 15 | :sectnums: 16 | :toc: 17 | :toclevels: 2 18 | :toc-placement!: 19 | ifdef::env-github[] 20 | :imagesdir: https://github.com/icebreaker-fpga/icebreaker-workshop/tree/master/stopwatch/guide/images 21 | endif::[] 22 | 23 | include::sections/macros.adoc[] 24 | 25 | toc::[] 26 | 27 | [preface] 28 | == Overview 29 | include::sections/objectives.adoc[] 30 | 31 | == Introduction 32 | 33 | Welcome to the workshop! This is a hands-on crash-course in Verilog and FPGAs in general. It is self-guided and self-paced. Instructors and assistants are here to answer questions, not drone on with text-laden slides. 34 | 35 | While microcontrollers run code, FPGAs let you define wires that connect things together, as well as logic that continuously combines and manipulates the values carried by those wires. Verilog is a hardware description language that lets you define how the FPGA should work. 36 | 37 | Because of this, FPGAs are well suited to timing-precise or massively-parallel tasks. If you need to repeatedly process a consistent amount of data with minimal delay, an FPGA would be a good choice. Signal and graphics processing problems, often done with GPUs if power and cost are no object, are often easy to parallelize and FPGAs allow you to widen your pipeline until you run out of resources. As your processing becomes more complicated, or your data becomes more variable, micro controllers can become a better solution. 38 | 39 | The objective of this workshop is to do something cool with FPGAs in only two hours. In order to introduce such a huge topic in such a short time, LOTS of details will be glossed over. Two hours from now you’re likely to have more questions about FPGAs than when you started - but at least you’ll know the important questions to ask if you choose to learn more. 40 | 41 | If you have any questions or run into trouble let any of the helpers know, we are here to help. If you are working on this outside of an organized workshop join the 1BitSquared https://1bitsquared.com/pages/chat[1BitSquared discord] and ask away in the *icebreaker* and/or *fpga* channels. 42 | 43 | === What We Won’t Learn 44 | 45 | In order to introduce Verilog and FPGAs in such a short time, we’re going to skip over several things that will be important when you build your own FPGA-based designs, but are not necessary to kickstart your tinkering: 46 | 47 | . *IP Cores*: FPGA vendors pre-build or automatically generate code to let you easily interface your FPGA to interfaces like RAM, network, or PCIe. We’ll stick to LEDs and switches today. 48 | . *Simulation*: Didn’t work right the first time? Simulation lets you look at all the signals in your design without having to use hardware or potentially expensive observation equipment. 49 | . *Testbenches*: For effective simulation, you need to write even more Verilog code to stimulate the inputs to your system. 50 | 51 | === Hardware Overview 52 | 53 | This is an iCEBreaker FPGA demonstration/learning board. It’s great for learning because it has so many user-accessible inputs and outputs. 54 | 55 | image::icebreaker-v10b-with-7seg.jpg[,400,] 56 | 57 | [.center] 58 | [%autowidth,frame="none",grid="none"] 59 | |==== 60 | | 1. | iCE40UP5K FPGA | 61 | | 2. | USB Programmer & UART adapter | 62 | | 3. | 7-segment display Pmod 1A | `P1A1-4, P1A7-10` 63 | | 4. | LEDs | `LED1-5` 64 | | 5. | User (negative logic) button | `BTN_N` 65 | | 6. | More Buttons | `BTN1, BTN2, BTN3` 66 | |==== 67 | 68 | [.text.center] 69 | [%autowidth,cols="^",frame="none",grid="none"] 70 | |==== 71 | | https://icebreaker-fpga.com/ 72 | |==== 73 | 74 | . Take a look at the board, and identify each of the components listed above. There are a few components not listed that we won’t use in this workshop. 75 | . Connect the USB cable from your laptop USB port to the connector on the iCEBreaker board. The FPGA will automatically load a demo configuration from the onboard serial flash. Play around: 76 | .. What do the pushbuttons do? 77 | .. Do you see the blink patterns on the LEDs? 78 | 79 | 80 | == Setting Up 81 | 82 | === Get the toolchain 83 | 84 | If you did not already you will need to install the FPGA toolchain first. 85 | 86 | Follow the instructions for the https://github.com/YosysHQ/oss-cad-suite-build/#installation[OSS CAD Suite]. 87 | 88 | If you are having trouble with the setup due to internet connectivity the helpers might have a USB stick you can use to copy the toolchain and the workshop materials to your laptop. You will need to unzip the toolchain archive and add the `bin` directory to your `PATH` environment variable or `source` the `environment` script. On windows you can run the `environment.bat` in your existing shell or start a new shell with `start.bat`. 89 | 90 | === Toolchain Troubleshooting 91 | 92 | **I am running iceprog and the programmer is not being detected** 93 | 94 | **Linux** 95 | 96 | * Check if the device is being detected by the kernel with 'lsusb' it will 97 | either show up as a Future Electronics device or the name of the programmer 98 | vendor. 99 | * If the device is being detected by the kernel you might not have permissions 100 | to access the device. If you run `sudo iceprog ...` and the device is 101 | decected you can give yourself permissions by creating a udev file at: 102 | `/etc/udev/rules.d/53-icebreaker-ftdi.rules` and adding the following line in 103 | that file: 104 | ``` 105 | ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="0660", GROUP="plugdev", TAG+="uaccess" 106 | ``` 107 | After adding that file you need to at least replug the programmer or even 108 | reload the udev rules. 109 | 110 | **Windows** 111 | 112 | You will need the https://zadig.akeo.ie[zadig drivers], choose icebreaker interface 0 and then choose winusb. If the icebreaker interface does not show up, check that "List all devices" is ticked under "Options". 113 | 114 | === Get the workshop repository 115 | 116 | You probably already have it on your drive as you are reading this, but for good measure here is how you obtain the workshop git repository: 117 | 118 | ``` 119 | git clone https://github.com/icebreaker-fpga/icebreaker-workshop.git 120 | cd icebreaker-workshop/stopwatch 121 | ``` 122 | 123 | == Your first digital design 124 | 125 | Now that everything is set up let's dive into it and build our first digital design. 126 | 127 | === Configuring an FPGA 128 | 129 | Now that we are familiar with the hardware as-is, let’s walk through the process of synthesizing an FPGA design of your own and uploading it to the iCEBreaker. We will be using the amazing open source tools called icestorm, nextpnr and Yosys. 130 | 131 | . Open the command line terminal: 132 | .. Enter the iCEBreaker stopwatch workshop directory directory by typing `cd icebreaker_workshop/stopwatch` 133 | .. If it’s not already connected, plug your iCEBreaker board into your laptop with a USB cable. 134 | .. Run the build and upload process by executing make in the directory by typing: `make prog` 135 | .. Confirm that you were able to replace the default configuration with a new one by checking to see if the behavior has changed. 136 | .. Test the buttons and switches. Does this new configuration do anything useful? 137 | 138 | === Reading Verilog 139 | 140 | Now that we know how to use the tools to configure our FPGA, let’s start by examining some simple Verilog code. Programming languages give you different ways of storing and passing data between blocks of code. Hardware Description Languages (HDLs) allow you to write code that defines how things are connected. 141 | 142 | . Open `stopwatch.v` (in the repository we cloned previously) in the text editor of your choosing. 143 | .. Our `module` definition comes first, and defines all the inputs and outputs to our system. Can you locate them on your board? 144 | .. Next are `wire` definitions. Wires are used to directly connect inputs to one or more outputs. 145 | .. Next are parallel `assign` statements. All of these assignments are always happening, concurrently. 146 | .. Next are always blocks. These are blocks of statements that happen sequentially, and are triggered by the _sensitivity list_ contained in the following `@( )`. 147 | .. Finally we can instantiate modules. There is one already instantiated that drives the 7-segment display. 148 | . Now let’s try and map our board’s functionality to the Verilog that makes it happen. 149 | .. What happened when you pressed buttons? 150 | .. Can you find the pushbuttons in the `module` definition? What are they called? 151 | .. Can you find an assignment that uses each of the pushbuttons? What are they assigned to? 152 | .. Can you follow the assignments to an output? 153 | .. Do you notice anything interesting about the order of the `assign` statements? 154 | 155 | You should be able to trace the `BTN1` and `BTN3` push button inputs, through a pair of wires, to a pair of LED outputs. Note that these aren’t sequential commands. All of these things happen at once. It doesn’t actually matter what order the `assign` statements occur. 156 | 157 | === Making Assignments and Combinatorial Logic 158 | 159 | Let’s start with some minor changes to our Verilog, then configure our board. We will be changing the way the three buttons (`BTN1-3`) on the “head” Pmod of the iCEBreaker are affecting the five LED (`LED1-5`): 160 | 161 | . Change the assignments for `LED1`..`LED5` so that 162 | .. `LED1` is on when buttons 1 and 2 are pressed simultaneously. 163 | .. `LED2` is on when buttons 1 and 3 are pressed simultaneously. 164 | .. `LED3` is on when buttons 2 and 3 are pressed simultaneously. 165 | .. `LED4` is on when the button `BTN_N` is pressed. (Note that this button is inverted, i.e. the value of `BTN_N` is zero when pressed.) 166 | .. `LED5` is on when any of the four buttons is pressed. 167 | . Next, we need to create a new configuration for our FPGA. Brace yourself - it will be really quick! ;-) 168 | .. In the command line terminal that we opened earlier, type `make prog` or use the up arrow on your keyboard to recall the previous command, then press `enter`. 169 | . You should see some text scroll by and the new design should be uploaded and running within a few seconds. If we were using proprietary tools (Vivado or Quartus) as we did in the early versions of the WTFPGA workshop V1 and V2, that this workshop is the descendant of, the synthesis would take about 8 minutes depending on the computer used. We instead used these 8 minutes to talk about the synthesis process itself. Even though we don’t have to wait that long, let’s talk about what the software is doing and what tools are used to accomplish those steps. It is a bit different from a software compiler. 170 | .. First, the software will *synthesize* the design - turn the Verilog code into basic logical blocks, optimizing it in the process using yosys. (http://www.clifford.at/yosys/) 171 | .. Next, the tools will *implement* the design. This takes the optimized list of registers and assignments, and *places* them into the logical blocks available on the specific FPGA we have configured, then *routes* the connections between them using the tool called nextpnr. 172 | (https://github.com/YosysHQ/nextpnr) 173 | .. When that completes, the fully laid out implementation needs to be packaged into a format for programming the FPGA. There are a number of options, but we will use a .bin bitstream file for programming over SPI interface using *icepack* from the icestorm tool collection. (http://www.clifford.at/icestorm) 174 | .. Hopefully everything will go as planned. If you have issues, look in the console for possible build errors. If you have trouble, ask for help! 175 | .. Finally, the .bin file needs to be sent to the FPGA over USB. When this happens, the demo configuration will be cleared and the new design will take its place using the *iceprog* tool. 176 | .. Test your system. Did it do what you expected? 177 | 178 | === Add missing 7-segment digits 179 | 180 | If you have not done that already, this is the time to solder on the missing Pmod connector closest to the USB connector (marked Pmod1A) on your iCEBreaker. After you do that you should plug in the 7-segment display Pmod. 181 | 182 | The 7-segment display Pmod module that is attached to your iCEBreaker has the following schematic. 183 | 184 | image::pmod-7segment-schematic.png[] 185 | 186 | As you can see in the Verilog code the pins of the iCEBreaker Pmod get assigned a vector of wires called `seven_segment`. 187 | 188 | These vectors are being fed through the module `seven_seg_ctrl` that switches very quickly between the two digits to create the impression that both segments are illuminated at the same time. That module in turn uses the `seven_seg_hex` module. The module `seven_seg_hex` is converting a 4-bit binary number into a 7-bit seven segment control vector. 189 | 190 | The mapping of the segment vector bits to the segments looks like this: 191 | 192 | image::7segment-segments.png[] 193 | 194 | . For example, hex ‘1’ looks like `7’b0000110`. We can express this as: `4’h1: dout = 7’b0000110;` 195 | which roughly translates to: 196 | + 197 | [width="50%",cols="25%,75%",frame="none",grid="none"] 198 | |==== 199 | | `4’` | when our 4 bits 200 | | `h1:` | equal hex 0x01 201 | | `dout =` | assign a value to dout 202 | | `7’b` | of seven bit 203 | | `0000110;` | leds 1 and 2 illuminated 204 | |==== 205 | + 206 | .. Figure out what you need to set for each of the hex values using the diagram. 207 | . We are missing the definitions for digits `3` and `8`. Go ahead and add them based on the above diagram. 208 | . Now `make prog` your design. Does it work? 209 | 210 | === Switch to decimal counting 211 | 212 | The module `bcd8_increment` reads a 8-bit BCD (Binary Coded Decimal) number (a decimal digit in each nibble) and increments it by one. Replace the line `assign display_value_inc = display_value + 1;` with an instance of `bcd8_increment` so that the stopwatch counts in decimal instead of hexadecimal. 213 | 214 | (See the instances of `seven_seg_ctrl` for how to instantiate a module.) 215 | 216 | === Add RESET button 217 | 218 | Add an if-statement to the `always @(posedge CLK)` block in the top module that will reset `display_value` to zero when the "user button" `BTN_N` is pressed. 219 | 220 | === Add START/STOP buttons 221 | 222 | While there is so much more to combinational logic than we actually touched on, let’s move on to a new concept - registers. Assignments are excellent at connecting blocks together, but they’re more similar to passing parameters to a function than actual variables. Registers allow you to capture and store data for repeated or later use. 223 | 224 | Add a (1 bit) `running` register (initialized to zero), and change the code that increments `display_value` so that it only applies the increment when running is `1`. 225 | 226 | Add if-statements to the `always @(posedge CLK)` block in the top module that will set `running` to `1` when `BTN3` is pressed, and reset running to `0` when `BTN1` is pressed. Now these two buttons function as START and STOP buttons for the stop watch. 227 | 228 | Also change the RESET functionality so that `running` and `display_value` is reset to `0` when the "user button" `BTN_N` is pressed. 229 | 230 | === Add lap time measurement 231 | 232 | Finally let's also add lap time measurement: pressing the center button `BTN2` on the board should display the current time for two seconds while we keep counting in the background. 233 | 234 | For this, we need to add a 8-bit register `lap_value` and an 5-bit register `lap_timeout`. 235 | 236 | `lap_timeout` should be decremented in every `clkdiv_pulse` cycle until it reaches zero. The seven segment display should show the value of `lap_value` instead of `display_value` when `lap_timeout` has a nonzero value. 237 | 238 | Pressing the center button `BTN2` should set `lap_timeout` to `20` and copy the value from `display_value` to `lap_value`. 239 | 240 | NOTE: The syntax `x = a ? b : c` can be used to assign value `b` to `x` when `a` is nonzero, and value `c` otherwise. 241 | 242 | === Exploring More 243 | 244 | You’ve now completed a basic stop watch! While simple, this design demonstrates most of the core concepts needed to design almost all silicon devices in use today. If time permits, here are a few additional things you can explore or try with this board: 245 | 246 | * Can you change the design so that the digits flash when `lap_value` is being displayed? 247 | * Can you make BTN3 toggle between START/STOP on each press? 248 | * Can you display something other than numbers? 249 | * Examine the `icebreaker.pcf` file. This contains all the mappings of the FPGA’s pins to the names you use in your code. 250 | * Add additional math functions to your stop watch, like switching to displaying minutes and seconds when the seconds counter rolls over. 251 | * Modify the design to flash the LEDs. 252 | * Modify the design to PWM fade the LEDs. 253 | * Add display dimming. 254 | 255 | == Final notes 256 | 257 | I hope you had fun with this workshop. There is so much more to learn about digital design and what you can do with iCEBreaker itself as well as FPGA development. 258 | 259 | If you want to continue hacking with the iCEBreaker we have a few of them here with us if you want to get them. Just find Esden. :D 260 | 261 | Definitely post on twitter and tag @esden if you do something cool with your iCEBreaker. 262 | 263 | You can find more information about the iCEBreaker at 1BitSquared: 264 | 265 | [.text.center] 266 | [%autowidth,cols="^",frame="none",grid="none"] 267 | |==== 268 | | https://1bitsquared.com/products/icebreaker 269 | |==== 270 | 271 | If you continue playing with your iCEBreaker make sure to share with us what you built, and ask questions. You can find us on the 1BitSquared Discord server: 272 | 273 | [.text.center] 274 | [%autowidth,cols="^",frame="none",grid="none"] 275 | |==== 276 | | https://1bitsquared.com/pages/chat 277 | |==== 278 | 279 | If you want some further reading and more examples, check out the iCEBreaker examples repositories. If you come up with additional examples make sure to send us a pull request! :D 280 | 281 | [.text.center] 282 | [%autowidth,cols="^",frame="none",grid="none"] 283 | |==== 284 | | https://github.com/icebreaker-fpga/ 285 | |==== 286 | 287 | 288 | See you around! :D 289 | --------------------------------------------------------------------------------