main.v (3156B)
1 /* 2 * Copyright 2022 Gerd Beuster (gerd@frombelow.net). This is free 3 * soft-/hardware under the GNU GPL v3 license or any later 4 * version. See COPYING in the root directory for details. 5 */ 6 7 `include "ecpu.v" 8 9 module main(input CLK_IN, // System clock (12 Mhz) 10 // External clock generated by NE555; user can set frequency. 11 // This clock is used by the CPU. 12 input USER_CLOCK, 13 // Switch to choose between continously running clock and single stepping 14 input SWITCH_SINGLE_CONT, 15 // Single step (exeuction mode) / write (programming mode) signal 16 input BUTTON_STEP, 17 input BUTTON_SKIP, // Skip memory cell (programming mode) signal 18 input BUTTON_RESET, 19 input SWITCH_PROGRAM, // Program or execute mode 20 // Manual input to data bus 21 input SWITCH_D0, SWITCH_D1, SWITCH_D2, SWITCH_D3, 22 input SWITCH_D4, SWITCH_D5, SWITCH_D6, SWITCH_D7, 23 output GREEN, output RED_N, output RED_E, 24 output RED_S, output RED_W, input RX, output TX, 25 output WS2811_DOUT); 26 27 wire button_step_debounced, button_skip_debounced; 28 debouncer deb0(.clk(CLK_IN), .button(BUTTON_STEP), .debounced(button_step_debounced)); 29 debouncer deb1(.clk(CLK_IN), .button(BUTTON_SKIP), .debounced(button_skip_debounced)); 30 31 // The SOC uses two clocks: The internal 12 Mhz clock of the 32 // iCEstick is used for updating the WS2811 LED matrix and for 33 // timing serial communication. An external, user-supplied clock 34 // generated by an NE555 is used for running the CPU. The speed of 35 // this clock can be set via the speed dial. Since the high and low 36 // phases of the external clock have different length, we use a prescaler 37 // to "convert" some to same length phases. 38 wire slow_clk; 39 prescaler #(.bits(1)) B1(.clk_in(USER_CLOCK), .clk_out(slow_clk)); 40 41 esoc s(.slow_clk(slow_clk), .fast_clk(CLK_IN), 42 .reset_in(BUTTON_RESET), 43 .program_mode(SWITCH_PROGRAM), 44 .single_cont(SWITCH_SINGLE_CONT), 45 .step(button_step_debounced), 46 .skip(button_skip_debounced), 47 .din({ !SWITCH_D7, !SWITCH_D6, !SWITCH_D5, !SWITCH_D4, 48 !SWITCH_D3, !SWITCH_D2, !SWITCH_D1, !SWITCH_D0 }), 49 .green(GREEN), .red_n(RED_N), .red_e(RED_E), .red_s(RED_S), 50 .red_w(RED_W), 51 .tx(TX), .rx(RX), .ws2811_dout(WS2811_DOUT)); 52 53 endmodule 54 55 module debouncer(input clk, input button, output reg debounced); 56 57 parameter delay = 20; 58 59 reg [delay:0] debounce_timer; 60 always @(posedge(clk)) 61 begin 62 if (button && (debounce_timer == 0)) 63 begin 64 debounced <= 1; 65 debounce_timer <= -1; 66 end 67 else 68 begin 69 if (debounce_timer > 0) 70 debounce_timer <= debounce_timer - 1; 71 debounced <= 0; 72 end 73 end 74 endmodule 75 76 module prescaler(input clk_in, output clk_out); 77 78 parameter bits = 24; 79 reg [bits-1:0] c = 0; 80 81 assign clk_out = c[bits-1]; 82 83 always @(posedge(clk_in)) 84 c <= c + 1; 85 86 endmodule