diff --git a/holeybeepo.gprj.user b/holeybeepo.gprj.user
index 080c63f..531b4b5 100644
--- a/holeybeepo.gprj.user
+++ b/holeybeepo.gprj.user
@@ -20,5 +20,5 @@
- 000000ff00000001fd000000020000000000000100000002cafc0200000001fc00000038000002ca0000008a01000018fa000000020200000004fb00000030004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00440065007300690067006e0100000000ffffffff0000005600fffffffb00000036004600700067006100500072006f006a006500630074002e00500061006e0065006c002e0048006900650072006100720063006800790100000000ffffffff0000007100fffffffb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00500072006f00630065007300730100000000ffffffff0000005200fffffffb00000030004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00440065007300690067006e0100000000ffffffff00000000000000000000000300000776000000f2fc0100000001fc0000000000000776000000a500fffffffa000000000100000003fb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00470065006e006500720061006c0100000000ffffffff0000004700fffffffb0000002e004600700067006100500072006f006a006500630074002e00500061006e0065006c002e004900730073007500650100000000ffffffff000000a500fffffffb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00470065006e006500720061006c0100000000ffffffff000000000000000000000670000002ca00000004000000040000000800000008fc000000010000000200000004000000220043006f00720065002e0054006f006f006c006200610072002e00460069006c00650100000000ffffffff0000000000000000000000220043006f00720065002e0054006f006f006c006200610072002e0045006400690074010000009bffffffff0000000000000000000000240043006f00720065002e0054006f006f006c006200610072002e0054006f006f006c00730100000157ffffffff0000000000000000ffffffff0100000207ffffffff0000000000000000
+ 000000ff00000001fd000000020000000000000100000002cafc0200000001fc00000038000002ca0000008a01000018fa000000000200000004fb00000030004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00440065007300690067006e0100000000ffffffff0000005600fffffffb00000036004600700067006100500072006f006a006500630074002e00500061006e0065006c002e0048006900650072006100720063006800790100000000ffffffff0000007100fffffffb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00500072006f00630065007300730100000000ffffffff0000005200fffffffb00000030004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00440065007300690067006e0100000000ffffffff00000000000000000000000300000776000000f2fc0100000001fc0000000000000776000000a500fffffffa000000000100000003fb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00470065006e006500720061006c0100000000ffffffff0000004700fffffffb0000002e004600700067006100500072006f006a006500630074002e00500061006e0065006c002e004900730073007500650100000000ffffffff000000a500fffffffb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00470065006e006500720061006c0100000000ffffffff000000000000000000000670000002ca00000004000000040000000800000008fc000000010000000200000004000000220043006f00720065002e0054006f006f006c006200610072002e00460069006c00650100000000ffffffff0000000000000000000000220043006f00720065002e0054006f006f006c006200610072002e0045006400690074010000009bffffffff0000000000000000000000240043006f00720065002e0054006f006f006c006200610072002e0054006f006f006c00730100000157ffffffff0000000000000000ffffffff0100000207ffffffff0000000000000000
diff --git a/src/beepo.v b/src/beepo.v
index bb4b706..af0e65a 100644
--- a/src/beepo.v
+++ b/src/beepo.v
@@ -5,7 +5,9 @@ module Beepo #(
) (
input i_clk,
input i_button1,
- output o_uart_tx
+ output o_uart_tx,
+ output [6:0] o_segments_drive,
+ output [3:0] o_displays_neg
);
// State values
localparam IDLE = 0; // Start fetching instruction
@@ -192,6 +194,13 @@ module Beepo #(
.tx_pin(o_uart_tx)
);
+ Multi7 display (
+ .i_clk(i_clk),
+ .i_hex({r_registers[1][7:0], r_registers[2][7:0]}),
+ .o_segments_drive(o_segments_drive),
+ .o_displays_neg(o_displays_neg)
+ );
+
// TODO: Bus
// For now this is just ROM
spMem memory (
diff --git a/src/holeybeepo.cst b/src/holeybeepo.cst
index 36a3edc..2ab57c2 100644
--- a/src/holeybeepo.cst
+++ b/src/holeybeepo.cst
@@ -11,3 +11,25 @@ IO_LOC "o_uart_tx" 69;
IO_PORT "o_uart_tx" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
IO_LOC "i_clk" 4;
IO_PORT "i_clk" PULL_MODE=UP BANK_VCCIO=1.8;
+IO_LOC "o_displays_neg[3]" 80;
+IO_PORT "o_displays_neg[3]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
+IO_LOC "o_displays_neg[2]" 76;
+IO_PORT "o_displays_neg[2]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
+IO_LOC "o_displays_neg[1]" 73;
+IO_PORT "o_displays_neg[1]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
+IO_LOC "o_displays_neg[0]" 74;
+IO_PORT "o_displays_neg[0]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
+IO_LOC "o_segments_drive[6]" 20;
+IO_PORT "o_segments_drive[6]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
+IO_LOC "o_segments_drive[5]" 19;
+IO_PORT "o_segments_drive[5]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
+IO_LOC "o_segments_drive[4]" 86;
+IO_PORT "o_segments_drive[4]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
+IO_LOC "o_segments_drive[3]" 53;
+IO_PORT "o_segments_drive[3]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
+IO_LOC "o_segments_drive[2]" 71;
+IO_PORT "o_segments_drive[2]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
+IO_LOC "o_segments_drive[1]" 18;
+IO_PORT "o_segments_drive[1]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
+IO_LOC "o_segments_drive[0]" 72;
+IO_PORT "o_segments_drive[0]" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
\ No newline at end of file
diff --git a/src/multi7.v b/src/multi7.v
new file mode 100644
index 0000000..3056e31
--- /dev/null
+++ b/src/multi7.v
@@ -0,0 +1,112 @@
+// displays multiple BCD digits on multiplexed seven segment displays
+module Multi7 #(
+ parameter DISPLAYS = 4,
+ parameter FREQ = 27_000_000,
+ parameter DELAY_US = 5000,
+ parameter integer DELAY = FREQ * (DELAY_US / 1_000_000.0),
+ parameter ENABLE_HEX = 1,
+ parameter ENABLE_CUSTOM = 0
+) (
+ i_clk,
+ i_hex,
+ i_custom,
+ i_mode, // if hex and custom are both enabled, 0 selects hex mode and 1 selects custom
+ o_segments_drive,
+ o_displays_neg
+);
+
+ localparam d_0 = 7'b1111110;
+ localparam d_1 = 7'b0110000;
+ localparam d_2 = 7'b1101101;
+ localparam d_3 = 7'b1111001;
+ localparam d_4 = 7'b0110011;
+ localparam d_5 = 7'b1011011;
+ localparam d_6 = 7'b1011111;
+ localparam d_7 = 7'b1110000;
+ localparam d_8 = 7'b1111111;
+ localparam d_9 = 7'b1111011;
+ localparam d_a = 7'b1110111;
+ localparam d_b = 7'b0011111;
+ localparam d_c = 7'b1001110;
+ localparam d_d = 7'b0111101;
+ localparam d_e = 7'b1001111;
+ localparam d_f = 7'b1000111;
+
+ input i_clk, i_mode;
+ input [(ENABLE_HEX * (DISPLAYS*4-1)):0] i_hex;
+ input [(ENABLE_CUSTOM * (DISPLAYS*7-1)):0] i_custom;
+
+ // 6543210
+ // gfedcba
+ output [6:0] o_segments_drive;
+ output [(DISPLAYS-1):0] o_displays_neg;
+
+ reg [$clog2(DELAY):0] r_tick = 0;
+ reg [(DISPLAYS*7-1):0] r_hex_state;
+ reg [$clog2(DISPLAYS):0] r_display_select = 0;
+ reg [(DISPLAYS-1):0] r_displays_neg = ~1;
+ reg [6:0] r_display_output;
+
+ assign o_segments_drive = r_display_output;
+ assign o_displays_neg = r_displays_neg;
+
+ always @(posedge i_clk) begin
+ if (r_tick == DELAY - 1) begin
+ r_tick <= 0;
+ r_displays_neg <= (r_displays_neg << 1) | r_displays_neg[DISPLAYS-1];
+
+ if (r_display_select == DISPLAYS - 1) begin
+ r_display_select <= 0;
+ end else begin
+ r_display_select <= r_display_select + 1;
+ end
+ end else begin
+ r_tick <= r_tick + 1;
+ end
+ end
+
+ generate
+ if (ENABLE_HEX) begin
+ for (genvar i = 0; i < DISPLAYS; i = i + 1) begin
+ localparam TOP = i * 4 + 4 - 1;
+ localparam BOTTOM = i * 4;
+ localparam G = i * 7 + 7 - 1;
+ localparam A = i * 7;
+
+ always @(i_hex[(TOP):(BOTTOM)]) begin
+ case (i_hex[(TOP):(BOTTOM)])
+ 4'h0: r_hex_state[G:A] <= d_0;
+ 4'h1: r_hex_state[G:A] <= d_1;
+ 4'h2: r_hex_state[G:A] <= d_2;
+ 4'h3: r_hex_state[G:A] <= d_3;
+ 4'h4: r_hex_state[G:A] <= d_4;
+ 4'h5: r_hex_state[G:A] <= d_5;
+ 4'h6: r_hex_state[G:A] <= d_6;
+ 4'h7: r_hex_state[G:A] <= d_7;
+ 4'h8: r_hex_state[G:A] <= d_8;
+ 4'h9: r_hex_state[G:A] <= d_9;
+ 4'hA: r_hex_state[G:A] <= d_a;
+ 4'hB: r_hex_state[G:A] <= d_b;
+ 4'hC: r_hex_state[G:A] <= d_c;
+ 4'hD: r_hex_state[G:A] <= d_d;
+ 4'hE: r_hex_state[G:A] <= d_e;
+ 4'hF: r_hex_state[G:A] <= d_f;
+ endcase
+ end
+ end
+ end
+ endgenerate
+
+ generate
+ if (ENABLE_HEX && ENABLE_CUSTOM) begin
+ always @(r_hex_state or i_custom or i_mode or r_display_select)
+ r_display_output <= (i_mode ? i_custom : r_hex_state) >> (r_display_select * 7);
+ end else if (ENABLE_HEX) begin
+ always @(r_hex_state or r_display_select)
+ r_display_output <= r_hex_state >> (r_display_select * 7);
+ end else if (ENABLE_CUSTOM) begin
+ always @(i_custom or r_display_select)
+ r_display_output <= i_custom >> (r_display_select * 7);
+ end
+ endgenerate
+endmodule