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

Subversion Repositories warp

[/] [warp/] [rtl/] [tmu_burst.v] - Blame information for rev 7

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 lekernel
/*
2
 * Milkymist VJ SoC
3
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
4
 *
5
 * This program is free and excepted software; you can use it, redistribute it
6
 * and/or modify it under the terms of the Exception General Public License as
7
 * published by the Exception License Foundation; either version 2 of the
8
 * License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful, but WITHOUT
11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
 * FOR A PARTICULAR PURPOSE. See the Exception General Public License for more
13
 * details.
14
 *
15
 * You should have received a copy of the Exception General Public License along
16
 * with this project; if not, write to the Exception License Foundation.
17
 */
18
 
19
module tmu_burst #(
20
        parameter fml_depth = 26
21
) (
22
        input sys_clk,
23
        input sys_rst,
24
 
25
        input flush,
26
        output reg busy,
27
 
28
        input pipe_stb_i,
29
        output pipe_ack_o,
30
        input [15:0] src_pixel_d,
31
        input [fml_depth-1-1:0] dst_addr, /* in 16-bit words */
32
 
33
        output reg pipe_stb_o,
34
        input pipe_ack_i,
35
        output reg [fml_depth-5-1:0] burst_addr, /* in 256-bit words */
36
        /* 16-bit granularity selection that needs to be expanded
37
         * to 8-bit granularity selection to drive the FML lines.
38
         */
39
        output reg [15:0] burst_sel,
40
        output reg [255:0] burst_do
41
);
42
 
43
wire burst_hit = dst_addr[fml_depth-1-1:4] == burst_addr;
44
 
45
/* Always memorize input in case we have to ack a cycle we cannot immediately handle */
46
reg [15:0] src_pixel_d_r;
47
reg [fml_depth-1-1:0] dst_addr_r;
48
always @(posedge sys_clk) begin
49
        if(pipe_stb_i & pipe_ack_o) begin
50
                src_pixel_d_r <= src_pixel_d;
51
                dst_addr_r <= dst_addr;
52
        end
53
end
54
 
55
/* Write to the burst storage registers */
56
reg clear_en;
57
reg write_en;
58
reg use_memorized;
59
wire [15:0] src_pixel_d_mux = use_memorized ? src_pixel_d_r : src_pixel_d;
60
wire [fml_depth-1-1:0] dst_addr_mux = use_memorized ? dst_addr_r : dst_addr;
61
always @(posedge sys_clk) begin
62
        if(sys_rst)
63
                burst_sel = 16'd0;
64
        else begin
65
                if(clear_en)
66
                        burst_sel = 16'd0;
67
                if(write_en) begin
68
                        burst_addr = dst_addr_mux[fml_depth-1-1:4]; /* update tag */
69
                        case(dst_addr_mux[3:0]) /* unmask */
70
                                4'd00: burst_sel = burst_sel | 16'h8000;
71
                                4'd01: burst_sel = burst_sel | 16'h4000;
72
                                4'd02: burst_sel = burst_sel | 16'h2000;
73
                                4'd03: burst_sel = burst_sel | 16'h1000;
74
                                4'd04: burst_sel = burst_sel | 16'h0800;
75
                                4'd05: burst_sel = burst_sel | 16'h0400;
76
                                4'd06: burst_sel = burst_sel | 16'h0200;
77
                                4'd07: burst_sel = burst_sel | 16'h0100;
78
                                4'd08: burst_sel = burst_sel | 16'h0080;
79
                                4'd09: burst_sel = burst_sel | 16'h0040;
80
                                4'd10: burst_sel = burst_sel | 16'h0020;
81
                                4'd11: burst_sel = burst_sel | 16'h0010;
82
                                4'd12: burst_sel = burst_sel | 16'h0008;
83
                                4'd13: burst_sel = burst_sel | 16'h0004;
84
                                4'd14: burst_sel = burst_sel | 16'h0002;
85
                                4'd15: burst_sel = burst_sel | 16'h0001;
86
                        endcase
87
                        case(dst_addr_mux[3:0]) /* register data */
88
                                4'd00: burst_do[255:240] = src_pixel_d_mux;
89
                                4'd01: burst_do[239:224] = src_pixel_d_mux;
90
                                4'd02: burst_do[223:208] = src_pixel_d_mux;
91
                                4'd03: burst_do[207:192] = src_pixel_d_mux;
92
                                4'd04: burst_do[191:176] = src_pixel_d_mux;
93
                                4'd05: burst_do[175:160] = src_pixel_d_mux;
94
                                4'd06: burst_do[159:144] = src_pixel_d_mux;
95
                                4'd07: burst_do[143:128] = src_pixel_d_mux;
96
                                4'd08: burst_do[127:112] = src_pixel_d_mux;
97
                                4'd09: burst_do[111: 96] = src_pixel_d_mux;
98
                                4'd10: burst_do[ 95: 80] = src_pixel_d_mux;
99
                                4'd11: burst_do[ 79: 64] = src_pixel_d_mux;
100
                                4'd12: burst_do[ 63: 48] = src_pixel_d_mux;
101
                                4'd13: burst_do[ 47: 32] = src_pixel_d_mux;
102
                                4'd14: burst_do[ 31: 16] = src_pixel_d_mux;
103
                                4'd15: burst_do[ 15:  0] = src_pixel_d_mux;
104
                        endcase
105
                end
106
        end
107
end
108
 
109
wire empty = (burst_sel == 16'd0);
110
 
111
reg state;
112
reg next_state;
113
 
114
parameter RUNNING       = 1'b0;
115
parameter DOWNSTREAM    = 1'b1;
116
 
117
always @(posedge sys_clk) begin
118
        if(sys_rst)
119
                state <= RUNNING;
120
        else
121
                state <= next_state;
122
end
123
 
124
/*
125
 * generate pipe_ack_o using an assign statement to work around a bug in CVER
126
 */
127
 
128
assign pipe_ack_o = (state == RUNNING) & (~flush | empty);
129
 
130
always @(*) begin
131
        next_state = state;
132
        busy = 1'b1;
133
        // CVER WA (see above) pipe_ack_o = 1'b0;
134
        pipe_stb_o = 1'b0;
135
        write_en = 1'b0;
136
        clear_en = 1'b0;
137
        use_memorized = 1'b0;
138
 
139
        case(state)
140
                RUNNING: begin
141
                        busy = 1'b0;
142
                        if(flush & ~empty)
143
                                next_state = DOWNSTREAM;
144
                        else begin
145
                                // CVER WA (see above) pipe_ack_o = 1'b1;
146
                                if(pipe_stb_i) begin
147
                                        if(burst_hit | empty)
148
                                                write_en = 1'b1;
149
                                        else
150
                                                next_state = DOWNSTREAM;
151
                                end
152
                        end
153
                end
154
                DOWNSTREAM: begin
155
                        pipe_stb_o = 1'b1;
156
                        use_memorized = 1'b1;
157
                        if(pipe_ack_i) begin
158
                                clear_en = 1'b1;
159
                                write_en = 1'b1;
160
                                next_state = RUNNING;
161
                        end
162
                end
163
        endcase
164
end
165
 
166
endmodule

powered by: WebSVN 2.1.0

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