csfifo.v
2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**************************************************************************
* *
* Copyright (C) 1994, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
*************************************************************************/
/////////////////////////////////////////////////////////////////////////
//
// Project Reality
//
// module: csfifo.v
// description: Command fifo for RDP command shuffle unit
//
//
// designer: Mike M. Cai 7/22/94
//
/////////////////////////////////////////////////////////////////////////
module csfifo( // outputs
w_addr, req_dma, empty, words_fifo, base_addr,
// inputs
xbus_valid,
update_rptr, one_word_cmd, cmd_size,
reset, start_gclk, clk);
output [4:0] w_addr;
output req_dma, empty, words_fifo;
output [4:0] base_addr;
input xbus_valid;
input update_rptr, one_word_cmd;
input [4:0] cmd_size;
input reset, start_gclk, clk;
reg [5:0] w_addr_in, r_addr;
reg [4:0] r_addr_inc;
reg [5:0] words_fifo_m, words_fifo;
reg empty, req_dma;
reg unrap;
always @(posedge clk) // things sync with clk
begin
// write pointer
if (reset)
w_addr_in <= 6'h0;
else
w_addr_in <= xbus_valid ? (w_addr_in + 1) : w_addr_in;
// fifo status bits
unrap = ~w_addr_in[5] & r_addr[5];
words_fifo_m = {(unrap ^ w_addr_in[5]), w_addr_in[4:0]} -
{(unrap ^ r_addr[5]), r_addr[4:0]};
empty <= words_fifo_m == 6'h0;
req_dma <= words_fifo_m <= 6'h16;
words_fifo <= words_fifo_m;
end
assign w_addr = w_addr_in[4:0];
always @(posedge clk)
if (start_gclk) begin
// read pointer
if (update_rptr)
r_addr_inc = one_word_cmd ? 5'h1 : cmd_size;
else
r_addr_inc = 5'h0;
if (reset)
r_addr <= 6'h0;
else
r_addr <= r_addr + {1'h0, r_addr_inc};
end
assign base_addr = r_addr[4:0];
endmodule // csfifo