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

Subversion Repositories fwrisc

[/] [fwrisc/] [trunk/] [rtl/] [fwrisc_fpga_top.sv] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 mballance
/****************************************************************************
2
 * fwrisc_fpga_top.sv
3
 *
4
 * Copyright 2018 Matthew Ballance
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in
8
 * compliance with the License.  You may obtain a copy of
9
 * the License at
10
 *
11
 * http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in
14
 * writing, software distributed under the License is
15
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
16
 * CONDITIONS OF ANY KIND, either express or implied.  See
17
 * the License for the specific language governing
18
 * permissions and limitations under the License.
19
 *
20
 ****************************************************************************/
21
 
22
/**
23
 * Module: fwrisc_fpga_top
24
 *
25
 * TODO: Add module documentation
26
 */
27
module fwrisc_fpga_top (
28
                input                   clock,
29
                output                  clock_o,
30
                output                  led0,
31
                output                  led1,
32
                output                  tx,
33
                output                  d0_p,
34
                output                  d0_n,
35
                output                  clk_o);
36
 
37
        wire                            reset;
38
        wire                            iaddr_ok;
39
        wire                            idata_ok;
40
 
41
        reg[1:0]                        clk_cnt;
42
 
43
        // /4 clock divider
44
        always @(posedge clock)
45
                clk_cnt <= clk_cnt + 1;
46
 
47
        wire    clock4 = clk_cnt[1];
48
        assign clock_o = clock4;
49
 
50
 
51
        reg[15:0]                       reset_cnt;
52
        reg[15:0]                       reset_key;
53
 
54
        always @(posedge clock4) begin
55
                if (reset_key != 16'ha520) begin
56
                        reset_key <= 16'ha520;
57
                        reset_cnt <= 16'h0000;
58
                end else if (reset_cnt != 1000) begin
59
                        reset_cnt <= reset_cnt + 1;
60
                end
61
        end
62
 
63
        assign reset = (reset_key != 16'ha520 || reset_cnt != 1000);
64
 
65
        wire[31:0]                      iaddr;
66
        reg[31:0]                       idata;
67
        wire                            ivalid;
68
        wire                            iready;
69
        wire[31:0]                      daddr;
70
        wire[31:0]                      dwdata;
71
        reg[31:0]                       drdata;
72
        wire[3:0]                       dstrb;
73
        wire                            dwrite;
74
        wire                            dvalid;
75
        wire                            dready;
76
 
77
        fwrisc u_core (
78
                .clock   (clock4  ),
79
                .reset   (reset  ),
80
                .iaddr   (iaddr  ),
81
                .idata   (idata  ),
82
                .ivalid  (ivalid ),
83
                .iready  (iready ),
84
                .daddr   (daddr  ),
85
                .dwdata  (dwdata ),
86
                .drdata  (drdata ),
87
                .dstrb   (dstrb  ),
88
                .dwrite  (dwrite ),
89
                .dvalid  (dvalid ),
90
                .dready  (dready ));
91
 
92
        // ROM: 'h8000_0000
93
        // RAM: 'h8000_8000
94
        // LED: 'hC000_0000
95
        reg[31:0]                       ram_0[1023:0]; // 16k ram
96
        reg[31:0]                       ram_1[1023:0]; // 16k ram
97
        reg[31:0]                       ram_2[1023:0]; // 16k ram
98
        reg[31:0]                       ram_3[1023:0]; // 16k ram
99
        reg[31:0]                       rom[4095:0];   // 16k rom
100
        reg[31:0]                       led;
101
        reg[31:0]                       tx_r;
102
        reg                                     iready_r, dready_r;
103
 
104
        assign iready = iready_r;
105
        assign dready = dready_r;
106
 
107
        assign d0_p = iaddr_ok; // iaddr[4]; // clk_cnt[0]; // iaddr[2]; // led[1];
108
        assign d0_n = led[3]; //data_ok; // clk_cnt[1]; // iaddr[3]; // led[2];
109
        assign tx   = tx_r[0];
110
        assign led0 = led[0];
111
        assign led1 = led[1];
112
 
113
        assign clk_o = led[2];
114
 
115
        initial begin
116
                $readmemh("rom.hex", rom);
117
        end
118
 
119
        reg[31:0]                       addr_d;
120
        reg[31:0]                       addr_i;
121
 
122
        always @(posedge clock4) begin
123
                addr_d <= daddr;
124
                addr_i <= iaddr;
125
 
126
                if (dvalid && dready && dwrite) begin
127
                        if (daddr[31:28] == 4'h8 &&
128
                                daddr[15:12] == 4'h2) begin
129
                                if (dstrb[0]) ram_0[daddr[13:2]]<=dwdata[7:0];
130
                                if (dstrb[1]) ram_1[daddr[13:2]]<=dwdata[15:8];
131
                                if (dstrb[2]) ram_2[daddr[13:2]]<=dwdata[23:16];
132
                                if (dstrb[3]) ram_3[daddr[13:2]]<=dwdata[31:24];
133
                        end else if (daddr[31:28] == 4'hc) begin
134
                                if (daddr[3:2] == 4'h0) begin
135
                                        led <= dwdata;
136
                                end else if (daddr[3:2] == 4'h1) begin
137
                                        tx_r <= dwdata;
138
                                end
139
                        end
140
                end
141
        end
142
 
143
        always @(posedge clock4) begin
144
                // Prefer data access
145
                if (dvalid) begin
146
                        dready_r <= 1;
147
                        iready_r <= 0;
148
                end else if (ivalid) begin
149
                        iready_r <= 1;
150
                        dready_r <= 0;
151
                end else begin
152
                        iready_r <= 0;
153
                        dready_r <= 0;
154
                end
155
        end
156
 
157
        always @* begin
158
                if (addr_d[31:28] == 4'h8 && addr_d[15:12] == 4'h2) begin
159
                        drdata = {
160
                                ram_3[addr_d[13:2]],
161
                                ram_2[addr_d[13:2]],
162
                                ram_1[addr_d[13:2]],
163
                                ram_0[addr_d[13:2]]
164
                                };
165
                end else begin
166
                        drdata = rom[addr_d[13:2]];
167
                end
168
 
169
                if (addr_i[31:28] == 4'h8 && addr_i[15:12] == 4'h2) begin
170
                        idata = {
171
                                ram_3[addr_d[13:2]],
172
                                ram_2[addr_d[13:2]],
173
                                ram_1[addr_d[13:2]],
174
                                ram_0[addr_d[13:2]]
175
                                };
176
                end else begin
177
                        idata = rom[addr_i[13:2]];
178
                end
179
        end
180
 
181
endmodule
182
 
183
 

powered by: WebSVN 2.1.0

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