OpenCores
URL https://opencores.org/ocsvn/vtach/vtach/trunk

Subversion Repositories vtach

[/] [vtach/] [trunk/] [alu.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 wd5gnr
`timescale 1us/1ns
2
// This is the main execution unit and ALU
3
// Handles all the instructions except for JMP and TAC
4
// (note that the JMP return address is here
5
// but main execution is in the top.v module)
6
 
7
// Inputs: clock, phase, bug (program counter)
8
// databus (inout), instruction register, reset, input buttons/switches
9
// Outputs: memory address, memwrite, sign (for TAC), halt, output display
10
 
11
module alu(input clk, input [3:0] phase, input [7:0] bug, inout [12:0] dbus, input [11:0] ir, output [7:0] memadd, output reg memwrite, output sign, output reg halt, input rst,
12
        output segA, output segB, output segC, output segD, output segE, output segF, output segG,
13
        output ds0, output ds1, output ds2, output ds3, input _pb0, input _pb1, input _pb2, input [7:0] sw);
14
 
15
   reg [16:0] acc;  // accumulator
16
   wire [16:0] result; // adder output
17
        wire pb0, pb1, pb2;  // debounced switches
18
 
19
   // select input or output devices
20
   reg         isel, osel;
21
 
22
// virtual input and output devices   
23
   io_input       in(clk, isel,dbus,rst,sw);
24
   io_output out(clk,osel,dbus, rst, segA, segB, segC, segD, segE, segF, segG, ds0, ds1, ds2, ds3);
25
 
26
// setup for simulation / reset  
27
   initial memwrite=0;
28
   initial isel=0;
29
   initial osel=0;
30
        initial halt=0;
31
 
32
// send sign for TAC instruction
33
   assign sign=acc[16];
34
 
35
// Location 99 is the one level return stack
36
// so we have to drive 99 to the address bus on a JMP
37
// But usually the mem address is the bottom two digits of the instruction   
38
   assign memadd=(ir[11:8]==4'b1000 && memwrite==1'b1)?8'h99:ir[7:0];
39
 
40
// Drive return address to dbus for JMP
41
   assign dbus=(ir[11:8]==4'b1000 && memwrite==1'b1)?{ 5'b01000, bug}:13'bz;
42
 
43
// Drive accumulator on bus for STO
44
   assign dbus=(ir[11:8]==4'b0110 && memwrite==1'b1)?{acc[16], acc[11:0]}:13'bz;
45
 
46
        // debounce input switches
47
   debounce swprocess0(clk, rst, _pb0, pb0);
48
   debounce swprocess1(clk, rst, _pb1, pb1);
49
        debounce swprocess2(clk, rst, _pb2, pb2);
50
 
51
// Add or subtract
52
   bcdadd adder(acc,{(ir[11:8]==4'b0111)?~dbus[12]:dbus[12] ,dbus[11:0]},result);
53
 
54
// This is where instructions are actually executed
55
   always @(posedge clk)
56
     begin
57
        if (rst==1'b0)  // do nothing if in reset
58
        case (ir[11:8])
59
          4'b0000:   // INP
60
            begin
61
               if (phase==4'b0100)
62
                    begin
63
                      isel<=1'b1;  // drive input on bus and write
64
                      memwrite<=1'b1;
65
                    end
66
               if (phase==4'b1000)
67
                     begin
68
                      isel<=1'b0;   // back to normal state
69
                       memwrite<=1'b0;
70
                     end
71
            end
72
          4'b0001:   // CLA (store memory address to accumumlator)
73
            begin
74
               if (phase==4'b1000)
75
                       acc<={dbus[12], 4'b0, dbus[11:0]};   // note sign extension NOT needed here! 
76
            end
77
          4'b0010:     // ADD
78
            begin
79
               if (phase==4'b1000)  // the adder already did it, just store it
80
                         acc<=result;
81
            end
82
 
83
          4'b0011:;     // TAC -- all handled in vtach.v
84
          4'b0100:     // SFT (extended to do input too)
85
            begin
86
               case (ir[7:4])
87
                 4'b0000: ;  // no shift left
88
                 4'b0001: acc<={acc[16], acc[11:0],4'b0};
89
                 4'b0010: acc<={acc[16], acc[7:0],8'b0};
90
                 4'b0011: acc<={acc[16], acc[3:0],12'b0};
91
                 4'b1000: acc<={ 9'b0, sw };  // load switches
92
                 4'b1001: acc<={pb0, 16'b1 }; // special instruction - set sign to input button
93
                 default: acc<={acc[16], 16'b0};
94
               endcase // case (ir[7:4])
95
               case (ir[3:0])
96
                 4'b0000: ; // no right shift
97
                 4'b0001: acc<={acc[16], 4'b0, acc[15:4]};
98
                 4'b0010: acc<={acc[16], 8'b0, acc[15:8]};
99
                 4'b0011: acc<={acc[16], 12'b0, acc[15:12]};
100
                 4'b1000: acc<={ pb1, 16'b1};
101
                 4'b1001: acc<={pb2, 16'b1 };
102
                 default: acc<={acc[16],16'b0};
103
               endcase // case (ir[3:0])
104
            end
105
 
106
          4'b0101:   // OUT
107
            begin
108
               // tell output unit to do its thing
109
            if (phase==4'b0100) osel<=1'b1;
110
            if (phase==4'b1000) osel<=1'b0;
111
            end
112
          4'b0110:   // STO
113
          begin
114
          // Set up memory for write cycle
115
             if (phase==4'b0100) memwrite<=1'b1;
116
             if (phase==4'b1000) memwrite<=1'b0;
117
          end
118
          4'b0111:   // SUB
119
            begin
120
               if (phase==4'b1000)
121
                        acc<=result;  // adder already did it, so just grab the result
122
            end
123
 
124
          4'b1000:  // JMP
125
            begin
126
               if (phase==4'b0100)
127
                    begin
128
                    memwrite<=1'b1;  // save return address
129
                    end
130
               if (phase==4'b1000)
131
                    begin
132
                    memwrite<=1'b0;  // done
133
                    end
134
// note top actually does the jump
135
            end
136
 
137
  // including 9, halt and reset (HRS)
138
          default: halt<=1'b1;
139
 
140
   endcase
141
        else    // in reset
142
        begin
143
          memwrite<=1'b0;
144
     isel<=1'b0;
145
     osel<=1'b0;
146
          halt<=1'b0;
147
        end
148
  end
149
 
150
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.