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

Subversion Repositories vtach

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 wd5gnr
`timescale 1us/1ns
2
 
3
// Vtach - A Verilog implementation of CARDIAC
4
// Target: Digilent Spartan 3 Board
5
// Al Williams, DDJ, May 2013
6
 
7
// This is the main CPU module
8
// inputs are the main clock, external reset, push buttons, and switches
9
// Outputs are the 7 segment display (segX and dsN) and the 8 discrete LEDs
10
module top(input clk,input extreset,
11
        output segA, output segB, output segC, output segD, output segE, output segF, output segG,
12
        output ds0, output ds1, output ds2, output ds3, output [7:0] led, input pb0, input pb1, input pb2, input [7:0] sw);
13
 
14
   reg addsource;  // pick memory address source
15
   reg memoe;    // memory output enable 1
16
   wire memwrite;  // assert to write to memory
17
        wire clkls;   // low speed clock from DLL (still too high)
18
        reg reset;    // internal reset signal
19
 
20
 
21
   reg [7:0] bug;   // the program counter
22
   reg [3:0] clkphase;  // 4 or 5 phase 1 hot counter
23
   reg [11:0] ir;   // instruction register
24
   wire [12:0] dbus;  // data bus
25
   wire [7:0]  memaddr;  // memory address to memory
26
   wire [7:0]  memadd;  // address from execution unit
27
 
28
   wire [7:0]  bugplus1;  // bug + 1
29
   wire        acsign;  // accumulator sign (for TAC)
30
 
31
 
32
 // addsource=1 then instruction, 0 then bug
33
   assign memaddr=addsource?memadd:bug;
34
 
35
   wire        xmemoe;  // memory output enable to memory
36
        wire haltflag;  // don't advance clock when halted
37
 
38
        // The DLL can only go down to 18MHz which is still too fast
39
        // This divides by two to allow the DLL to run at 32MHz
40
        // clk1 should be 1/2 the clk2 (memory clock)
41
        // Would be better to supply a slower clock or
42
        // Use clock enables to "tone down" the speed
43
        // But at these relatively slow speeds this works ok
44
        reg clkdiv;
45
        wire clk1, clk2;
46
        assign clk1=clkdiv;  // 16 MHz
47
        assign clk2=clkls;  // 32MHz
48
 
49
        always @(posedge clkls) clkdiv<=~clkdiv;  // Divide clock by 2
50
 
51
 
52
 
53
 
54
// tell memory to drive the bus unless not memoe or if writing 
55
// except in phase 2 (instruction fetch)
56
   assign xmemoe=memoe && (~memwrite  || clkphase==4'b0010) ;
57
 
58
// Main memory (100 words)
59
   memory mem(clk2,memaddr,dbus,xmemoe,memwrite&~haltflag);
60
// The adder to advance the bug (program counter)
61
   bcdincr bugadder(bug,bugplus1);
62
// Exeuction unit/ALU
63
   alu execunit(clk1,clkphase,bug,dbus,ir,memadd,memwrite,acsign,haltflag, reset,
64
            segA, segB, segC, segD, segE, segF, segG, ds0, ds1, ds2, ds3, pb0, pb1, pb2, sw);
65
 
66
                // Instantiate the DLL clock module
67
mainclock clockdll (
68
    .CLKIN_IN(clk),
69
    .CLKFX_OUT(clkls),
70
         .RST_IN(1'b0)    );
71
 
72
        assign led=memaddr;  // output LEDs
73
 
74
 
75
// Set up for startup   
76
   initial clkphase=4'b0;
77
   initial addsource=1'b0;
78
   initial memoe=1'b0;
79
   initial bug=0;
80
   initial reset=1'b1;
81
   initial ir=12'b100000000000;
82
 
83
 
84
 
85
 
86
 
87
 
88
// generate clock -- must be sure clkphase is set to 1 or 0 on power up
89
   always @(posedge clk1)
90
     begin
91
          if (clkphase==4'b0 || (haltflag && ~extreset))
92
                clkphase<=4'b1;
93
          else
94
          // cycle 0001 -> 1000 
95
            clkphase<={clkphase[2:0],clkphase[3]};
96
                 // sync external reset
97
                 if (clkphase==4'b0100 && extreset==1'b0 && reset==1'b1) reset<=1'b0;
98
                 if (clkphase==4'b1000 && extreset==1'b1) reset<=1'b1;
99
     end
100
 
101
// manage each cycle
102
   always @(posedge clk1)
103
     begin
104
        if (reset==1'b0)
105
        case (clkphase)
106
          4'b0001:
107
            begin  // get next instruction
108
               addsource<=1'b0;
109
               memoe<=1'b1;
110
               end
111
          4'b0010:
112
            begin   // store it and get memory operand on bus, bug++
113
               ir<=dbus;
114
               addsource<=1'b1;
115
               bug<=bugplus1;
116
            end
117
 
118
          4'b0100:
119
            begin
120
               // alu does command so not much to do here now
121
            end
122
 
123
          4'b1000:   // store result
124
            begin
125
// Jump instruction
126
               if (ir[11:8]==4'b1000) bug<=ir[7:0];
127
// TAC instruction
128
               if (acsign==1'b1 && ir[11:8]==4'b0011) bug<=ir[7:0];
129
            end
130
 
131
          default:
132
            begin
133
            end
134
        endcase
135
         else  // in reset
136
         begin
137
      addsource<=1'b0;
138
      memoe<=1'b0;
139
      bug<=8'b0;
140
                ir<=12'b100000000000;
141
         end
142
 
143
  end
144
 
145
 
146
 
147
 
148
endmodule // top
149
 
150
 
151
 
152
 

powered by: WebSVN 2.1.0

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