`include "util.svh" module panel #( DEBOUNCE_MAX = 100 ) ( input bit clk , input bit reset , input bit [8:1][12:1] led , output bit [3:1][12:1] switch , inout wire [10:1] gpioa , inout wire [28:13] gpiob , inout wire [40:31] gpioc ); localparam DEBOUNCE_BITS = $clog2(DEBOUNCE_MAX+1); enum { LED_ROW1 , DEAD_ROW2 , LED_ROW2 , DEAD_ROW3 , LED_ROW3 , DEAD_ROW4 , LED_ROW4 , DEAD_ROW5 , LED_ROW5 , DEAD_ROW6 , LED_ROW6 , DEAD_ROW7 , LED_ROW7 , DEAD_ROW8 , LED_ROW8 , DEAD_ROW9 , SWITCH_PREP , SWITCH_ROW1 , SWITCH_ROW2 , SWITCH_ROW3 } state; bit [3:1][12:1] switch_raw; bit [DEBOUNCE_BITS-1:0] switch_debounce; `define LEDROW1 gpioc[38] `define LEDROW2 gpioc[40] `define LEDROW3 gpiob[15] `define LEDROW4 gpiob[16] `define LEDROW5 gpiob[18] `define LEDROW6 gpiob[22] `define LEDROW7 gpioc[37] `define LEDROW8 gpiob[13] `define SWROW1 gpioc[36] `define SWROW2 gpioa[1] `define SWROW3 gpioa[2] `define COL1 gpioa[8] `define COL2 gpioa[10] `define COL3 gpioa[7] `define COL4 gpiob[27] `define COL5 gpioc[31] `define COL6 gpiob[26] `define COL7 gpiob[24] `define COL8 gpiob[21] `define COL9 gpiob[19] `define COL10 gpiob[23] `define COL11 gpioc[32] `define COL12 gpioc[33] `define DO_LEDS `define DO_SWITCHES always_ff @(posedge clk) begin // LED rows (active high) `LEDROW1 = 1'b0; `LEDROW2 = 1'b0; `LEDROW3 = 1'b0; `LEDROW4 = 1'b0; `LEDROW5 = 1'b0; `LEDROW6 = 1'b0; `LEDROW7 = 1'b0; `LEDROW8 = 1'b0; // Switch rows (active low) `SWROW1 = 1'b1; `SWROW2 = 1'b1; `SWROW3 = 1'b1; if (reset) begin switch = 0; switch_raw = 0; switch_debounce = 0; state = state.first; end else begin automatic bit [3:1][12:1] new_switch = switch_raw; case (state) `ifdef DO_LEDS `define LED_ROW(n) \ LED_ROW``n: begin \ `LEDROW``n = 1'b1; \ `COL1 = ~led[n][1]; \ `COL2 = ~led[n][2]; \ `COL3 = ~led[n][3]; \ `COL4 = ~led[n][4]; \ `COL5 = ~led[n][5]; \ `COL6 = ~led[n][6]; \ `COL7 = ~led[n][7]; \ `COL8 = ~led[n][8]; \ `COL9 = ~led[n][9]; \ `COL10 = ~led[n][10]; \ `COL11 = ~led[n][11]; \ `COL12 = ~led[n][12]; \ end `LED_ROW(1) `LED_ROW(2) `LED_ROW(3) `LED_ROW(4) `LED_ROW(5) `LED_ROW(6) `LED_ROW(7) `LED_ROW(8) `endif `ifdef DO_SWITCHES SWITCH_PREP: begin `SWROW1 = 1'b0; `COL1 = 1'bZ; `COL2 = 1'bZ; `COL3 = 1'bZ; `COL4 = 1'bZ; `COL5 = 1'bZ; `COL6 = 1'bZ; `COL7 = 1'bZ; `COL8 = 1'bZ; `COL9 = 1'bZ; `COL10 = 1'bZ; `COL11 = 1'bZ; `COL12 = 1'bZ; end SWITCH_ROW1: begin `SWROW2 = 1'b0; new_switch[1][1] = ~`COL1; new_switch[1][2] = ~`COL2; new_switch[1][3] = ~`COL3; new_switch[1][4] = ~`COL4; new_switch[1][5] = ~`COL5; new_switch[1][6] = ~`COL6; new_switch[1][7] = ~`COL7; new_switch[1][8] = ~`COL8; new_switch[1][9] = ~`COL9; new_switch[1][10] = ~`COL10; new_switch[1][11] = ~`COL11; new_switch[1][12] = ~`COL12; end SWITCH_ROW2: begin `SWROW3 = 1'b0; new_switch[2][1] = ~`COL1; new_switch[2][2] = ~`COL2; new_switch[2][3] = ~`COL3; new_switch[2][4] = ~`COL4; new_switch[2][5] = ~`COL5; new_switch[2][6] = ~`COL6; new_switch[2][7] = ~`COL7; new_switch[2][8] = ~`COL8; new_switch[2][9] = ~`COL9; new_switch[2][10] = ~`COL10; new_switch[2][11] = ~`COL11; new_switch[2][12] = ~`COL12; end SWITCH_ROW3: begin new_switch[3][1] = ~`COL1; new_switch[3][2] = ~`COL2; new_switch[3][3] = ~`COL3; new_switch[3][4] = ~`COL4; new_switch[3][5] = ~`COL5; new_switch[3][6] = ~`COL6; new_switch[3][7] = ~`COL7; new_switch[3][8] = ~`COL8; new_switch[3][9] = ~`COL9; new_switch[3][10] = ~`COL10; new_switch[3][11] = ~`COL11; new_switch[3][12] = ~`COL12; end `endif endcase if (state == state.last) state = state.first; else state = state.next; if (new_switch == switch_raw) begin if (switch_debounce == 0) switch = switch_raw; else --switch_debounce; end else begin switch_raw = new_switch; switch_debounce = DEBOUNCE_MAX; end end end endmodule