/** * 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 */ module gl_avalon_intf ( // Avalon Clock Input input logic CLOCK, RESET, // GL Controller Slave 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 ); // 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 end endmodule // gl_avalon_intf