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
// 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_waitreq, 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_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_WAITREQ = 1'b0;
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;
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;
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
200
201
202
203
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