Newer
Older
/**
* gl_avalon_intf
*
* Avalon-MM interface for GL modules
*
* Slave 1: GL MM Registers
* * gl[0]: Status flags (readonly)
* * gl[1]: Draw time (readonly)
* * gl[2]: Draw command
* * gl[4-7]: Unused
* * gl[8-15]: Args
*
* Before issuing any new commands, please first make sure no command is in
* progress by waiting for GL_DONE flag going low. You should also check the
* GL_TIMEOUT flag.
* To issue a drawing command, first set the args registers. Then set gl[2]
* to the desired drawing command. This will instantly starts drawing and set
* draw enable to high. You could then wait for GL_DONE flag to go low, but
* postponing this waiting till the beginning of the next command is
* recommended so that software could utilize the meantime. To issue the next
* command, set the command register again, even if the command is the same
* because painting execution is initiated on each write request. In the same
* way, the command register should be set exactly once per execution, otherwse
* the same operation may be repeated and cause undefined behavior.
*
* Slave 2: SRAM
input logic AVL_GL_READ,
input logic AVL_GL_WRITE,
input logic AVL_GL_CS,
input logic [3:0] AVL_GL_BYTE_EN,
input logic [3:0] AVL_GL_ADDR,
input logic [31:0] AVL_GL_WRITEDATA,
output logic [31:0] AVL_GL_READDATA,
// SRAM Slave
input logic AVL_SRAM_READ,
input logic AVL_SRAM_WRITE,
input logic AVL_SRAM_CS,
input logic [3:0] AVL_SRAM_BYTE_EN,
input logic [19:0] AVL_SRAM_ADDR,
input logic [31:0] AVL_SRAM_WRITEDATA,
output logic [31:0] AVL_SRAM_READDATA,
output logic AVL_SRAM_WAITREQ,
// Palette Slave
input logic AVL_PLT_READ,
input logic AVL_PLT_WRITE,
input logic AVL_PLT_CS,
input logic [3:0] AVL_PLT_BYTE_EN,
input logic [7:0] AVL_PLT_ADDR,
input logic [31:0] AVL_PLT_WRITEDATA,
output logic [31:0] AVL_PLT_READDATA,
// SRAM Conduit
output logic [19:0] SRAM_ADDR,
inout wire [15:0] SRAM_DQ,
output logic SRAM_UB_N, SRAM_LB_N, SRAM_CE_N, SRAM_OE_N, SRAM_WE_N,
// VGA Conduit
output logic VGA_CLK,
output logic [7:0] VGA_R, VGA_G, VGA_B,
output logic VGA_SYNC_N, VGA_BLANK_N, VGA_VS, VGA_HS
);
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// GL
logic gl_frame_finished, gl_done, gl_timeout;
logic [9:0] gl_drawtime;
logic [3:0] gl_cmd, gl_cmd_in;
logic [31:0] gl_args[8], gl_args_in[8];
logic gl_exec, gl_exec_next;
logic avl_sram_ready;
gl_mgr gl_inst(
.CLOCK (CLOCK),
.RESET (RESET),
.GL_FRAME_FINISHED(gl_frame_finished),
.GL_TIMEOUT (gl_timeout),
.GL_DRAWTIME (gl_drawtime),
.GL_CMD (gl_cmd),
.GL_ARG1 (gl_args[0]),
.GL_ARG2 (gl_args[1]),
.GL_ARG3 (gl_args[2]),
.GL_ARG4 (gl_args[3]),
.GL_ARG5 (gl_args[4]),
.GL_ARG6 (gl_args[5]),
.GL_ARG7 (gl_args[6]),
.GL_ARG8 (gl_args[7]),
.GL_EXEC (gl_exec),
.GL_DONE (gl_done),
.AVL_REQ (avl_sram_writereq),
.AVL_ADDR (avl_sram_addr),
.AVL_DATA (avl_sram_data),
.AVL_READY (avl_sram_ready),
.AVL_PLT_RD (AVL_PLT_CS & AVL_PLT_READ),
.AVL_PLT_WR (AVL_PLT_CS & AVL_PLT_WRITE),
.AVL_PLT_INDEX (AVL_PLT_ADDR),
.AVL_PLT_RD_COLOR (AVL_PLT_READDATA[23:0]),
.AVL_PLT_WR_COLOR ({8'h0,AVL_PLT_WRITEDATA}),
.*);
assign AVL_SRAM_READDATA = 32'hCCCCCCCC; // SRAM is write-only
assign AVL_PLT_READDATA[31:24] = 8'h0;
// Avalon SRAM write pipeline
logic avl_sram_wait_next, avl_sram_writereq, avl_sram_writereq_next;
logic [19:0] avl_sram_addr, avl_sram_addr_next;
logic [16:0] avl_sram_data, avl_sram_data_next;
always_ff @(posedge CLOCK) begin
if(RESET) begin
AVL_SRAM_WAITREQ <= 1'b0;
avl_sram_writereq <= 1'b0;
end else begin
AVL_SRAM_WAITREQ <= avl_sram_wait_next;
avl_sram_writereq <= avl_sram_writereq_next;
end
avl_sram_addr <= avl_sram_addr_next;
avl_sram_data <= avl_sram_data_next;
end
always_comb begin
avl_sram_wait_next = AVL_SRAM_WAITREQ;
avl_sram_writereq_next = avl_sram_writereq;
avl_sram_addr_next = avl_sram_addr;
avl_sram_data_next = avl_sram_data;
if(AVL_SRAM_WAITREQ) begin
// IO inhibited, wait for ready signal
if (avl_sram_ready) begin
// Done!
avl_sram_wait_next = 1'b0;
avl_sram_writereq_next = 1'b0;
end
end else begin
// IO available, listen for incoming write request
if (AVL_SRAM_CS & AVL_SRAM_WRITE & (AVL_SRAM_BYTE_EN[1:0] == 2'b11)) begin
avl_sram_wait_next = 1'b1;
avl_sram_writereq_next = 1'b1;
avl_sram_addr_next = AVL_SRAM_ADDR;
avl_sram_data_next = AVL_SRAM_WRITEDATA[16:0];
end
end
end
// GL controller
always_ff @(posedge CLOCK) begin
if(RESET) begin
gl_cmd <= 4'h0;
gl_exec <= 1'b0;
for (int i = 0; i < 8; i++) begin
gl_args[i] <= 0;
end
end else begin
gl_cmd <= gl_cmd_in;
gl_exec <= gl_exec_next;
for (int i = 0; i < 8; i++) begin
gl_args[i] <= gl_args_in[i];
end
end
end
always_comb begin
gl_cmd_in = gl_cmd;
gl_exec_next = gl_exec;
for (int i = 0; i < 8; i++) begin
gl_args_in[i] = gl_args[i];
end
AVL_GL_READDATA = 32'hCCCCCCCC;
if(AVL_GL_CS & AVL_GL_READ) begin
case (AVL_GL_ADDR)
4'd0: AVL_GL_READDATA = {29'b0, gl_timeout, gl_frame_finished, gl_done};
4'd1: AVL_GL_READDATA = {21'b0, gl_drawtime};
4'd2: AVL_GL_READDATA = {28'b0, gl_cmd};
endcase
if (AVL_GL_ADDR[3]) begin
AVL_GL_READDATA = gl_args[AVL_GL_ADDR[2:0]];
end
end
if (AVL_GL_CS & AVL_GL_WRITE) begin
if (AVL_GL_ADDR[3]) begin
if (AVL_GL_BYTE_EN == 4'hf)
gl_args_in[AVL_GL_ADDR[2:0]] = AVL_GL_WRITEDATA;
end else if (AVL_GL_ADDR == 4'd2) begin
if (AVL_GL_BYTE_EN[0]) begin
// Initiate new command
gl_cmd_in = AVL_GL_WRITEDATA[3:0];
gl_exec_next = 1'b1;
end
end
end