]> git.ozlabs.org Git - minimigmac.git/blob - fpga/sim_kbd.v
Initial commit
[minimigmac.git] / fpga / sim_kbd.v
1 `timescale 1ns / 100ps
2
3 module sim_kbd(inout clk, inout dat);
4 `define CLK_HALF        5000    /* faster sim, should be more like 50000 */
5    
6    reg aclk;
7    reg adat;
8    reg [7:0] cmd;       
9    reg       wait_led;
10    
11    
12    task do_send;
13       input [7:0]       d;
14       output            ok;
15       reg [10:0]        sr;
16       reg               p;              
17       integer           i;              
18       begin
19          $display("sim_kbd: Send %x", d);
20          
21          p = ~(d[0] ^ d[1] ^ d[2] ^ d[3] ^
22                d[4] ^ d[5] ^ d[6] ^ d[7]);      
23          sr = { 1'b1, p, d, 1'b0 };
24          aclk = 0;
25          adat = 0;
26          ok = 1;
27          i = 11;
28          while(i > 0 && ok) begin
29             if (clk == 0) begin
30                $display("sim_kbd: Clock low, aborting send");
31                ok = 0;                                  
32             end else begin
33                adat = ~sr[0];
34                #`CLK_HALF aclk = 1;
35                #`CLK_HALF aclk = 0;
36                #1;                              
37                sr = { 1'b0, sr[10:1] };
38                i = i - 1;
39             end
40          end
41          aclk = 0;
42          adat = 0;
43          #`CLK_HALF;                    
44          #`CLK_HALF;                    
45       end
46    endtask
47
48    task do_receive;
49       output [7:0]      d;
50       output            ok;
51       reg [10:0]        sr;
52       reg               p;              
53       integer           i;              
54       begin
55          aclk = 0;
56          adat = 0;
57          sr = 0;                        
58          wait(dat == 0);
59          wait(clk != 0);        
60          ok = 1;
61          i = 10;
62          while(i > 0 && ok) begin
63             if (clk == 0) begin
64                $display("sim_kbd: Clock low, aborting receive");
65                ok = 0;                                  
66             end else begin
67                #`CLK_HALF aclk = 1;
68                #`CLK_HALF aclk = 0;
69                #1;                              
70                sr = { dat != 0, sr[10:1] };
71                i = i - 1;
72             end
73          end // while (i > 0 && ok)
74          adat = 1;
75          #`CLK_HALF aclk = 1;
76          #`CLK_HALF aclk = 0;
77          adat = 0;                      
78          //                     $display("rx shift final: %b", sr);                     
79          aclk = 0;
80          adat = 0;
81          d = sr[8:1];
82          #`CLK_HALF;                    
83          #`CLK_HALF;    
84          $display("sim_kbd: Got %x ok=%b", d, ok);
85       end
86    endtask
87    
88    pullup(clk); 
89    pullup(dat);
90
91    assign clk = aclk ? 1'b0 : 1'bz;
92    assign dat = adat ? 1'b0 : 1'bz;
93
94    reg ok;
95
96    always@(clk, dat) begin
97       while (clk == 0) begin
98          #`CLK_HALF;
99          if (clk == 0) begin
100             #`CLK_HALF;
101             if (clk == 0) begin
102                do_receive(cmd, ok);
103                if (ok) begin
104                   if (wait_led) begin
105                      do_send(8'hfa, ok);
106                      $display("sim_kbd: LEDs set to %x\n", cmd);
107                   end else begin
108                      if (cmd == 8'hed) begin
109                         wait_led = 1;                                              
110                         do_send(8'hfa, ok);
111                      end else if (cmd == 8'hff) begin
112                         if (ok)
113                           do_send(8'hfa, ok);
114                         if (ok)
115                           do_send(8'haa, ok);
116                      end
117                   end            
118                end                                      
119             end
120          end
121       end
122    end
123
124    initial begin        
125       aclk = 0;
126       adat = 0;
127       wait_led = 0;        
128       #`CLK_HALF;
129       #`CLK_HALF;
130       #`CLK_HALF;
131       #`CLK_HALF;
132       do_send(8'haa, ok);
133       #10000000;
134       do_send(8'h1c, ok);
135       #100000;
136       do_send(8'hf0, ok);
137       do_send(8'h1c, ok);
138       #1000000;
139       do_send(8'he0, ok);
140       do_send(8'h75, ok);
141       #100000;
142       do_send(8'he0, ok);
143       do_send(8'hf0, ok);
144       do_send(8'h75, ok);
145    end
146 endmodule
147