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

Subversion Repositories eco32

[/] [eco32/] [trunk/] [fpga/] [mc-vl/] [src/] [cpu/] [cpu_bus.v] - Blame information for rev 308

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 308 hellwig
//
2
// cpu_bus.v -- the ECO32 CPU bus interface
3
//
4
 
5
 
6
`timescale 1ns/10ps
7
`default_nettype none
8
 
9
 
10
module cpu_bus(clk, rst,
11
               bus_stb, bus_we, bus_addr,
12
               bus_din, bus_dout, bus_ack, bus_irq,
13
               cpu_stb, cpu_we, cpu_size, cpu_addr,
14
               cpu_din, cpu_dout, cpu_ack, cpu_irq);
15
    // bus interface
16
    input clk;
17
    input rst;
18
    output reg bus_stb;
19
    output reg bus_we;
20
    output reg [31:2] bus_addr;
21
    input [31:0] bus_din;
22
    output reg [31:0] bus_dout;
23
    input bus_ack;
24
    input [15:0] bus_irq;
25
    // CPU interface
26
    input cpu_stb;
27
    input cpu_we;
28
    input [1:0] cpu_size;
29
    input [31:0] cpu_addr;
30
    output reg [31:0] cpu_din;
31
    input [31:0] cpu_dout;
32
    output reg cpu_ack;
33
    output [15:0] cpu_irq;
34
 
35
  reg state;
36
  reg next_state;
37
  reg [31:0] wbuf;
38
  reg wbuf_we;
39
  reg [31:0] wbuf_in;
40
 
41
  // ctrl
42
  always @(posedge clk) begin
43
    if (rst) begin
44
      state <= 0;
45
    end else begin
46
      state <= next_state;
47
    end
48
  end
49
 
50
  // output
51
  always @(*) begin
52
    case (state)
53
      1'b0:
54
        if (~cpu_stb) begin
55
          // no bus activity from cpu
56
          bus_stb = 1'b0;
57
          bus_we = 1'bx;
58
          bus_addr[31:2] = 30'bx;
59
          bus_dout[31:0] = 32'bx;
60
          cpu_din[31:0] = 32'bx;
61
          cpu_ack = 1'b0;
62
          next_state = 1'b0;
63
          wbuf_we = 1'b0;
64
          wbuf_in[31:0] = 32'bx;
65
        end else begin
66
          // bus activated by cpu
67
          if (~cpu_we) begin
68
            // cpu read cycle
69
            if (~cpu_size[1]) begin
70
              if (~cpu_size[0]) begin
71
                // cpu read byte
72
                bus_stb = 1'b1;
73
                bus_we = 1'b0;
74
                bus_addr[31:2] = cpu_addr[31:2];
75
                bus_dout[31:0] = 32'bx;
76
                if (~cpu_addr[1]) begin
77
                  if (~cpu_addr[0]) begin
78
                    cpu_din[31:0] = { 24'h0, bus_din[31:24] };
79
                  end else begin
80
                    cpu_din[31:0] = { 24'h0, bus_din[23:16] };
81
                  end
82
                end else begin
83
                  if (~cpu_addr[0]) begin
84
                    cpu_din[31:0] = { 24'h0, bus_din[15: 8] };
85
                  end else begin
86
                    cpu_din[31:0] = { 24'h0, bus_din[ 7: 0] };
87
                  end
88
                end
89
                cpu_ack = bus_ack;
90
                next_state = 1'b0;
91
                wbuf_we = 1'b0;
92
                wbuf_in[31:0] = 32'bx;
93
              end else begin
94
                // cpu read halfword
95
                bus_stb = 1'b1;
96
                bus_we = 1'b0;
97
                bus_addr[31:2] = cpu_addr[31:2];
98
                bus_dout[31:0] = 32'bx;
99
                if (~cpu_addr[1]) begin
100
                  cpu_din[31:0] = { 16'h0, bus_din[31:16] };
101
                end else begin
102
                  cpu_din[31:0] = { 16'h0, bus_din[15: 0] };
103
                end
104
                cpu_ack = bus_ack;
105
                next_state = 1'b0;
106
                wbuf_we = 1'b0;
107
                wbuf_in[31:0] = 32'bx;
108
              end
109
            end else begin
110
              // cpu read word
111
              bus_stb = 1'b1;
112
              bus_we = 1'b0;
113
              bus_addr[31:2] = cpu_addr[31:2];
114
              bus_dout[31:0] = 32'bx;
115
              cpu_din[31:0] = bus_din[31:0];
116
              cpu_ack = bus_ack;
117
              next_state = 1'b0;
118
              wbuf_we = 1'b0;
119
              wbuf_in[31:0] = 32'bx;
120
            end
121
          end else begin
122
            // cpu write cycle
123
            if (~cpu_size[1]) begin
124
              if (~cpu_size[0]) begin
125
                // cpu write byte
126
                // part 1: read word into word buffer
127
                bus_stb = 1'b1;
128
                bus_we = 1'b0;
129
                bus_addr[31:2] = cpu_addr[31:2];
130
                bus_dout[31:0] = 32'bx;
131
                cpu_din[31:0] = 32'bx;
132
                cpu_ack = 1'b0;
133
                if (~bus_ack) begin
134
                  next_state = 1'b0;
135
                end else begin
136
                  next_state = 1'b1;
137
                end
138
                wbuf_we = 1'b1;
139
                if (~cpu_addr[1]) begin
140
                  if (~cpu_addr[0]) begin
141
                    wbuf_in[31:0] = { cpu_dout[7:0], bus_din[23:16],
142
                                      bus_din[15:8], bus_din[7:0] };
143
                  end else begin
144
                    wbuf_in[31:0] = { bus_din[31:24], cpu_dout[7:0],
145
                                      bus_din[15:8], bus_din[7:0] };
146
                  end
147
                end else begin
148
                  if (~cpu_addr[0]) begin
149
                    wbuf_in[31:0] = { bus_din[31:24], bus_din[23:16],
150
                                      cpu_dout[7:0], bus_din[7:0] };
151
                  end else begin
152
                    wbuf_in[31:0] = { bus_din[31:24], bus_din[23:16],
153
                                      bus_din[15:8], cpu_dout[7:0] };
154
                  end
155
                end
156
              end else begin
157
                // cpu write halfword
158
                // part 1: read word into word buffer
159
                bus_stb = 1'b1;
160
                bus_we = 1'b0;
161
                bus_addr[31:2] = cpu_addr[31:2];
162
                bus_dout[31:0] = 32'bx;
163
                cpu_din[31:0] = 32'bx;
164
                cpu_ack = 1'b0;
165
                if (~bus_ack) begin
166
                  next_state = 1'b0;
167
                end else begin
168
                  next_state = 1'b1;
169
                end
170
                wbuf_we = 1'b1;
171
                if (~cpu_addr[1]) begin
172
                  wbuf_in[31:0] = { cpu_dout[15:0], bus_din[15:0] };
173
                end else begin
174
                  wbuf_in[31:0] = { bus_din[31:16], cpu_dout[15:0] };
175
                end
176
              end
177
            end else begin
178
              // cpu write word
179
              bus_stb = 1'b1;
180
              bus_we = 1'b1;
181
              bus_addr[31:2] = cpu_addr[31:2];
182
              bus_dout[31:0] = cpu_dout[31:0];
183
              cpu_din[31:0] = 32'bx;
184
              cpu_ack = bus_ack;
185
              next_state = 1'b0;
186
              wbuf_we = 1'b0;
187
              wbuf_in[31:0] = 32'bx;
188
            end
189
          end
190
        end
191
      1'b1:
192
        begin
193
          // cpu write halfword or byte
194
          // part 2: write word from word buffer
195
          bus_stb = 1'b1;
196
          bus_we = 1'b1;
197
          bus_addr[31:2] = cpu_addr[31:2];
198
          bus_dout[31:0] = wbuf[31:0];
199
          cpu_din[31:0] = 32'bx;
200
          cpu_ack = bus_ack;
201
          if (~bus_ack) begin
202
            next_state = 1'b1;
203
          end else begin
204
            next_state = 1'b0;
205
          end
206
          wbuf_we = 1'b0;
207
          wbuf_in[31:0] = 32'bx;
208
        end
209
    endcase
210
  end
211
 
212
  // word buffer
213
  always @(posedge clk) begin
214
    if (wbuf_we) begin
215
      wbuf[31:0] <= wbuf_in[31:0];
216
    end
217
  end
218
 
219
  // interrupt requests
220
  assign cpu_irq[15:0] = bus_irq[15:0];
221
 
222
endmodule

powered by: WebSVN 2.1.0

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