-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
806 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module bcd_to_bin #(DIGITS = 4 : DIGITS > 0 && DIGITS < 16) | ||
( | ||
input bcd[DIGITS][4], // bcd digits | ||
output result[$clog2($pow(10, DIGITS)) + 2] // result | ||
|
||
) { | ||
|
||
sig temp[DIGITS][$clog2($pow(10, DIGITS)) + 2] | ||
|
||
always { | ||
temp[DIGITS-1] = bcd[DIGITS-1] | ||
repeat(i, DIGITS-1, DIGITS-1, -1) { | ||
temp[i-1] = (temp[i] << 3) + (temp[i] << 1) + bcd[i-1] | ||
} | ||
result = temp[0] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
### A BCD adder for two 4-digit numbers a and b on the Alchitry AU FPGA kit with the IO Element board. | ||
|
||
The 5 buttons on the IO board allow you to enter the two numbers a and b and compute the sum: | ||
|
||
- use the up/down button to increment/decrement the currently selected digit | ||
- use the left/right button to select the next/previous digit in a or b | ||
- use the center button to advance state: enter a => enter b => show sum => enter a etc... | ||
|
||
The currently selected digit is shown on leds[3:0] an the AU board | ||
|
||
The current state (a, b, sum) is shown on io leds [2][3:0] | ||
|
||
The currently selected digit value of or b is shown on the io board: | ||
- on io_leds[0][3:0] | ||
- on the seven segment display | ||
|
||
The sum is shown on the 7 segment display until the center button is pressed again,ready for the next a value | ||
|
||
An overflow condition is shown on the leftmost io led [2][7:7] | ||
|
||
The code is written in Alchitry Labs Lucid, a more ergonomic version of Verilog. | ||
The Alchitry IDE converts this to Verilog and compiles it with Vivado. | ||
|
||
A picture of the result of adding 9999 + 9999 : | ||
|
||
![bcd adder](https://github.com/user-attachments/assets/99d17364-7336-4259-8767-2ef69e75b5ef) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
{ | ||
"project": { | ||
"type": "V1.2", | ||
"projectName": "io_add_binary", | ||
"board": "Alchitry Au", | ||
"sourceFiles": [ | ||
{ | ||
"file": { | ||
"type": "DiskFile", | ||
"path": "source/alchitry_top.luc" | ||
}, | ||
"top": true | ||
}, | ||
{ | ||
"file": { | ||
"type": "Component", | ||
"path": "Conditioning/reset_conditioner.luc" | ||
} | ||
}, | ||
{ | ||
"file": { | ||
"type": "DiskFile", | ||
"path": "source/multi_seven_seg.luc" | ||
} | ||
}, | ||
{ | ||
"file": { | ||
"type": "DiskFile", | ||
"path": "source/seven_seg.luc" | ||
} | ||
}, | ||
{ | ||
"file": { | ||
"type": "Component", | ||
"path": "Miscellaneous/counter.luc" | ||
} | ||
}, | ||
{ | ||
"file": { | ||
"type": "Component", | ||
"path": "Miscellaneous/decoder.luc" | ||
} | ||
}, | ||
{ | ||
"file": { | ||
"type": "Component", | ||
"path": "Miscellaneous/bin_to_dec.luc" | ||
} | ||
}, | ||
{ | ||
"file": { | ||
"type": "DiskFile", | ||
"path": "source/bcd_to_bin.luc" | ||
} | ||
}, | ||
{ | ||
"file": { | ||
"type": "DiskFile", | ||
"path": "source/btn_press.luc" | ||
} | ||
}, | ||
{ | ||
"file": { | ||
"type": "Component", | ||
"path": "Miscellaneous/pipeline.luc" | ||
} | ||
}, | ||
{ | ||
"file": { | ||
"type": "Component", | ||
"path": "Conditioning/button_conditioner.luc" | ||
} | ||
}, | ||
{ | ||
"file": { | ||
"type": "Component", | ||
"path": "Pulses/edge_detector.luc" | ||
} | ||
} | ||
], | ||
"constraintFiles": [ | ||
{ | ||
"file": { | ||
"type": "Component", | ||
"path": "Constraints/alchitry.acf" | ||
} | ||
}, | ||
{ | ||
"file": { | ||
"type": "Component", | ||
"path": "Constraints/io.acf" | ||
} | ||
} | ||
], | ||
"ipCores": [] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
// reference: https://natalieagus.github.io/50002/fpga/fpga_2 | ||
// Note: Lucid V1 fsm = V2 enum !! | ||
module alchitry_top ( | ||
input clk, // 100MHz clock | ||
input rst_n, // reset button (active low) | ||
output led[8], // 8 user controllable LEDs | ||
input usb_rx, // USB->Serial input | ||
output usb_tx, // USB->Serial output | ||
output io_led[3][8], // LEDs on IO Shield | ||
output io_segment[8], // 7-segment LEDs on IO Shield | ||
output io_select[4], // Digit select on IO Shield | ||
input io_button[5], // 5 buttons on IO Shield | ||
input io_dip[3][8] // DIP switches on IO Shield | ||
) { | ||
|
||
// the push buttons | ||
const UP = 0 | ||
const CENTER = 1 | ||
const DOWN = 2 | ||
const LEFT = 3 | ||
const RIGHT = 4 | ||
const NBUTTONS = 5 | ||
|
||
// the FSM | ||
enum State {A, B, SUM} // A: input a, B: input b, SUM: compute and show sum | ||
|
||
sig rst // reset signal | ||
|
||
bcd_to_bin bcd_to_bin_a(#DIGITS(4)) | ||
bcd_to_bin bcd_to_bin_b(#DIGITS(4)) | ||
|
||
bin_to_dec btd(#DIGITS(4), #LEADING_ZEROS(1)) | ||
|
||
.clk(clk) { | ||
// The reset conditioner is used to synchronize the reset signal to the FPGA | ||
// clock. This ensures the entire FPGA comes out of reset at the same time. | ||
reset_conditioner reset_cond | ||
btn_press btn_chk[NBUTTONS] | ||
.rst(rst) { | ||
dff state[$width(State)](#INIT(State.A)) // state fsm | ||
dff digit_adder[4][4] // 4 bcd adders, one for each decimal digit | ||
dff a[4][4] // 4 bcd digits, a input for adder | ||
dff b[4][4] // 4 bcd digits, b input for adder | ||
dff digit_index[2] // the current decimal digit position in a or b | ||
multi_seven_seg seg (#DIV($is_sim() ? 1 : 16), #DIGITS(4)) // 4 digit 7-segment display | ||
} | ||
} | ||
|
||
|
||
|
||
always { | ||
reset_cond.in = ~rst_n // input raw inverted reset signal | ||
rst = reset_cond.out // conditioned reset | ||
|
||
led = 8h00 // turn LEDs off | ||
io_led = 3x{{8h00}} | ||
io_segment = 8h_f_f | ||
io_select = 4h_f | ||
|
||
// clear the sum | ||
bcd_to_bin_a.bcd = 4x{{4h0}} | ||
bcd_to_bin_b.bcd = 4x{{4h0}} | ||
btd.value = 0 | ||
|
||
// show currently active digit on AU leds [0-3] | ||
led[digit_index.q] = 1 | ||
// show current digit value on right io_leds bank | ||
io_led[0][3:0] = digit_adder.q[digit_index.q] | ||
// show current FSM state on left io_led bank [2:0] | ||
io_led[2][0] = state.q == State.A | ||
io_led[2][1] = state.q == State.B | ||
io_led[2][2] = state.q == State.SUM | ||
|
||
// show the current a or b or sum digits on the display | ||
case (state.q) { | ||
State.A: | ||
seg.values = digit_adder.q | ||
State.B: | ||
seg.values = digit_adder.q | ||
State.SUM: | ||
bcd_to_bin_a.bcd = a.q | ||
sig partiala[16] = bcd_to_bin_a.result | ||
bcd_to_bin_b.bcd = b.q | ||
sig partialb[16] = bcd_to_bin_b.result | ||
sig binsum[18] = partiala + partialb | ||
btd.value = binsum[13:0] | ||
seg.values = btd.digits | ||
sig carry[1] = binsum > 9999 | ||
if (carry) { | ||
seg.values = 4x{{hb}} | ||
} | ||
io_led[2][7:7] = carry // set overflow indicator | ||
default: | ||
// should never happen | ||
seg.values = 4x{{4bxxx}} | ||
} | ||
io_segment = ~seg.seg // connect segments to the driver | ||
io_select = ~seg.sel // connect digit select to the driver | ||
|
||
// get the debounced buttons pressed state | ||
btn_chk.btn_in[NBUTTONS-1:0] = io_button | ||
sig add = btn_chk.btn_down[UP] | ||
sig sub = btn_chk.btn_down[DOWN] | ||
sig nxt = btn_chk.btn_down[LEFT] | ||
sig prv = btn_chk.btn_down[RIGHT] | ||
sig enter = btn_chk.btn_down[CENTER] | ||
|
||
if (add) { // inc the current digit | ||
if (digit_adder.q[digit_index.q] == 9) { | ||
digit_adder.d[digit_index.q] = 0 | ||
} else { | ||
digit_adder.d[digit_index.q] = digit_adder.q[digit_index.q] + 1 | ||
} | ||
} else if (sub) { // dec the current digit | ||
if (digit_adder.q[digit_index.q] == 0) { | ||
digit_adder.d[digit_index.q] = 9 | ||
} else { | ||
digit_adder.d[digit_index.q] = digit_adder.q[digit_index.q] - 1 | ||
} | ||
} else if (nxt) { // next digit position | ||
digit_index.d = digit_index.q + 1 | ||
} else if (prv) { // previous digit position | ||
digit_index.d = digit_index.q - 1 | ||
} else if (enter) { // advance state machine | ||
case (state.q) { | ||
State.A: | ||
a.d = digit_adder.q // remember x value | ||
state.d = State.B // set next state | ||
State.B: | ||
b.d = digit_adder.q // remember y value | ||
state.d = State.SUM // set next state (activates bcd adder) | ||
State.SUM: | ||
state.d = State.A // set next state | ||
default: | ||
// should not happen | ||
state.d = State.A | ||
} | ||
// clean-up for next state | ||
digit_adder.d = 4x{{4h0}} // clear a or b | ||
digit_index.d = 0 // reset to enter 1st digit | ||
} | ||
|
||
/* | ||
va.x = 1 | ||
va.y = 2 | ||
va.cin = 0 | ||
io_led = $build(va.sum, 3) | ||
|
||
btd.value = va.sum[13:0] | ||
sig result[4][4] = btd.digits | ||
seg.values = result | ||
io_segment = ~seg.seg // connect segments to the driver | ||
io_select = ~seg.sel // connect digit select to the driver | ||
*/ | ||
|
||
usb_tx = usb_rx // loop serial port | ||
|
||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module bcd_to_bin #(DIGITS = 4 : DIGITS > 0 && DIGITS < 16) | ||
( | ||
input bcd[DIGITS][4], // bcd digits | ||
output result[$clog2($pow(10, DIGITS)) + 2] // result | ||
|
||
) { | ||
|
||
sig temp[DIGITS][$clog2($pow(10, DIGITS)) + 2] | ||
|
||
always { | ||
temp[DIGITS-1] = bcd[DIGITS-1] | ||
repeat(i, DIGITS-1, DIGITS-1, -1) { | ||
temp[i-1] = (temp[i] << 3) + (temp[i] << 1) + bcd[i-1] | ||
} | ||
result = temp[0] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module btn_press ( | ||
input clk, // clock | ||
input btn_in, | ||
output btn_down | ||
) { | ||
.clk(clk) { | ||
edge_detector edge(#RISE(1), #FALL(0)) // detect rising edges | ||
|
||
button_conditioner btn_cond(#CLK_FREQ($is_sim() ? 1_000 : 100_000_000)) // button input conditioner | ||
|
||
} | ||
always { | ||
btn_cond.in = btn_in // raw button input | ||
edge.in = btn_cond.out // input to the edge_detector | ||
btn_down = edge.out // output the state | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module mul10_addbcd #(DIGITS = 4 : DIGITS > 0 && DIGITS < 16) | ||
( | ||
input bcd[DIGITS][4], // bcd digits | ||
output result[$clog2($pow(10, DIGITS)) + 2] // result | ||
|
||
) { | ||
|
||
sig temp[DIGITS][$clog2($pow(10, DIGITS)) + 2] | ||
|
||
always { | ||
temp[DIGITS-1] = bcd[DIGITS-1] | ||
repeat(i, DIGITS-1, DIGITS-1, -1) { | ||
temp[i-1] = (temp[i] << 3) + (temp[i] << 1) + bcd[i-1] | ||
} | ||
result = temp[0] | ||
} | ||
} |
Oops, something went wrong.