/ src / hal / components / mux16.comp
mux16.comp
 1  component mux16 "Select from one of sixteen input values";
 2  pin in bit use_graycode"""\
 3  This signifies the input will use Gray code instead of binary.
 4  Gray code is a good choice when using physical switches because
 5  for each increment only one select input changes at a time.
 6  """;
 7  pin in bit suppress_no_input"""\
 8  This suppresses changing the output if all select lines are false.
 9  This stops unwanted jumps in output between transitions of input.
10  but make in00 unavaliable.
11  """;
12  pin in float debounce_time"""\
13  sets debouce time in seconds.  eg. .10 = a tenth of a second
14  input must be stable this long before outputs changes. This
15  helps to ignore 'noisy' switches.
16  """;
17  pin in bit sel#[4] """\
18  Together, these determine which \\fBin\\fIN\\fR value is copied to \\fBout\\fR.
19  """;
20  pin out float out_f;
21  pin out s32 out_s """\
22  Follows the value of one of the \\fBin\\fIN\\fR values according to the four \\fBsel\\fR values
23  and whether use-graycode is active.
24  The s32 value will be trunuated and limited to the max and min values of signed values. 
25  .RS
26  .TP
27  \\fBsel3=FALSE\\fR, \\fBsel2=FALSE\\fR, \\fBsel1=FALSE\\fR, \\fBsel0=FALSE\\fR
28  \\fBout\\fR follows \\fBin0\\fR
29  .TP
30  \\fBsel3=FALSE\\fR, \\fBsel2=FALSE\\fR, \\fBsel1=FALSE\\fR, \\fBsel0=TRUE\\fR
31  \\fBout\\fR follows \\fBin1\\fR
32  .TP
33  etc.
34  .RE
35  """;
36  param r float elapsed "Current value of the internal debounce timer\n for debugging.";
37  param r s32 selected "Current value of the internal selection variable after conversion\n for debugging";
38  pin in float in##[16] "array of selectable outputs";
39  variable double delaytime;
40  variable int lastnum;
41  variable int running;
42  function _;
43  license "GPL";
44  ;;
45  FUNCTION(_) {
46      int i,num = 0;
47      int internal[4];
48  
49      if(suppress_no_input) {
50          if (sel(0) + sel(1) + sel(2) + sel(3) == 0) {
51              return;
52          }
53      }
54      if (use_graycode) {
55          internal[0] = sel(3);
56          internal[1] = sel(2);
57          internal[2] = sel(1);
58          internal[3] = sel(0);
59          for(i = 1; i < 4; i++){
60              internal[i] = internal[i] ^ internal[i - 1];
61          }
62          selected = num = internal[3]+(internal[2]*2) + (internal[1]*4) + (internal[0]*8);
63      }else{
64          selected = num = (sel(0))+(sel(1)*2) + (sel(2)*4) + (sel(3)*8);
65      }
66      if(debounce_time) {
67          if (num != lastnum) {
68              if (!running) {
69                  running = 1;
70                  delaytime = 0;
71              }
72              if (delaytime < debounce_time) {
73                  delaytime += fperiod;
74                  elapsed = delaytime;
75                  return;
76              }else{
77              running = 0;
78              lastnum = num;
79              out_s = out_f = in(num);
80              return;
81              }
82          }
83      }
84      /* select the output */
85      out_s = out_f = in(num);
86  
87  }