blob: 7785ff882ab5d02e780cb39ca7943cdf04196068 [file] [log] [blame]
Sylvain Munautbd83e532020-09-15 22:11:29 +02001/*
2 * led_blinker.v
3 *
4 * vim: ts=4 sw=4
5 *
6 * Controls E1 led blinking
7 *
8 * Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
9 * SPDX-License-Identifier: CERN-OHL-S-2.0
10 */
11
12`default_nettype none
13
14`define SMALL
15
16module led_blinker (
17 // Requested LED state
18 input wire [7:0] led_state,
19
20 // Shift Register interface
21 output wire [7:0] sr_val,
22 output reg sr_go,
23 input wire sr_rdy,
24
25 // Clock / Reset
26 input wire clk,
27 input wire rst
28);
29
30 // ff00 f0f0 cccc aaaa
31 localparam integer BLINK_SLOW_SPEED = 0;
32 localparam [15:0] BLINK_SLOW_PATTERN = 16'hf0f0;
33 localparam integer BLINK_FAST_SPEED = 0;
34 localparam [15:0] BLINK_FAST_PATTERN = 16'haaaa;
35
36
37 // Signals
38 // -------
39
40 reg [15:0] tick_cnt;
41 wire tick;
42
43 reg [ 9:0] cycle;
44
45 wire blink_slow;
46 wire blink_fast;
47
48 reg [ 3:0] led;
49
50
51 // Counter
52 // -------
53
54 // Tick
55 always @(posedge clk)
56`ifdef SMALL
57 tick_cnt <= (tick_cnt + 1) & (tick ? 16'h0000 : 16'hffff);
58`else
59 tick_cnt <= tick ? 16'h00000 : (tick_cnt+ 1);
60`endif
61
62 assign tick = tick_cnt[15];
63
64 // Cycles
65 always @(posedge clk)
66 cycle <= cycle + tick;
67
68
69 // Blink patterns
70 // --------------
71
72 // Base
73 assign blink_slow = BLINK_SLOW_PATTERN[cycle[9-BLINK_SLOW_SPEED:6-BLINK_SLOW_SPEED]];
74 assign blink_fast = BLINK_FAST_PATTERN[cycle[9-BLINK_FAST_SPEED:6-BLINK_FAST_SPEED]];
75
76 // Per-led
77 always @(*)
Sylvain Munaut7b228842020-09-22 20:00:13 +020078 begin : led_state_proc
Sylvain Munautbd83e532020-09-15 22:11:29 +020079 integer i;
80 for (i=0; i<4; i=i+1)
81 led[i] = led_state[2*i+1] ? (led_state[2*i] ? blink_fast : blink_slow) : led_state[2*i];
82 end
83
84
85 // Request
86 // -------
87
88 // Keep update requests 'pending' for half a cycle
89 always @(posedge clk or posedge rst)
90 if (rst)
91 sr_go <= 1'b0;
92 else
93 sr_go <= (sr_go & ~(sr_rdy | tick_cnt[14])) | tick;
94
95 assign sr_val = {
96 led[1],
97 1'b0,
98 led[0],
99 1'b0,
100 1'b0,
101 led[2],
102 1'b0,
103 led[3]
104 };
105
106endmodule // led_blinker