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

Subversion Repositories rtf_sprite_controller

[/] [rtf_sprite_controller/] [trunk/] [rtl/] [verilog/] [rtfSpriteController.v] - Diff between revs 2 and 3

Show entire file | Details | Blame | View Log

Rev 2 Rev 3
Line 1... Line 1...
`timescale 1ns / 1ps
`timescale 1ns / 1ps
// ============================================================================
// ============================================================================
//        __
//        __
//   \\__/ o\    (C) 2005-2013  Robert Finch, Stratford
//   \\__/ o\    (C) 2005-2015  Robert Finch, Stratford
//    \  __ /    All rights reserved.
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@opencores.org
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//       ||
//
//
//      rtfSpriteController.v
//      rtfSpriteController.v
//              sprite / hardware cursor controller
//              sprite / hardware cursor controller
//
//
Line 24... Line 24...
//
//
//
//
//      Sprite Controller
//      Sprite Controller
//
//
//      FEATURES
//      FEATURES
//      - parameterized number of sprites 1,2,4,6,8 or 14
//      - parameterized number of sprites 1,2,4,6,8,14 or 32
//      - sprite image cache buffers
//      - sprite image cache buffers
//              - each image cache is capable of holding multiple
//              - each image cache is capable of holding multiple
//                sprite images
//                sprite images
//              - cache may be accessed like a memory by the processor
//              - cache may be accessed like a memory by the processor
//              - an embedded DMA controller may also be used for
//              - an embedded DMA controller may also be used for
//                      sprite reload
//                      sprite reload
//      - programmable image offset within cache
//      - programmable image offset within cache
//      - programmable sprite width,height, and pixel size
//      - programmable sprite width,height, and pixel size
//              - sprite width and height may vary from 1 to 64 as long
//              - sprite width and height may vary from 1 to 64 as long
//                as the product doesn't exceed 2048.
//                as the product doesn't exceed 4096.
//          - pixels may be programmed to be 1,2,3 or 4 video clocks
//          - pixels may be programmed to be 1,2,3 or 4 video clocks
//            both height and width are programmable
//            both height and width are programmable
//      - programmable sprite position
//      - programmable sprite position
//      - 8 or 16 bits for color
//      - 8 or 16 bits for color
//              eg 32k color + 1 bit alpha blending indicator (1,5,5,5)
//              eg 32k color + 1 bit alpha blending indicator (1,5,5,5)
//      - fixed display and DMA priority
//      - fixed display and DMA priority
//          sprite 0 highest, sprite 13 lowest
//          sprite 0 highest, sprite 31 lowest
//
//
//              This core requires an external timing generator to
//              This core requires an external timing generator to
//      provide horizontal and vertical sync signals, but
//      provide horizontal and vertical sync signals, but
//      otherwise can be used as a display controller on it's
//      otherwise can be used as a display controller on it's
//      own. However, normally this core would be embedded
//      own. However, normally this core would be embedded
Line 69... Line 69...
//      and pertain to each sprite
//      and pertain to each sprite
//      00:     - position register
//      00:     - position register
//              HPOS    [11: 0] horizontal position (hctr value)
//              HPOS    [11: 0] horizontal position (hctr value)
//          VPOS        [27:16] vertical position (vctr value)
//          VPOS        [27:16] vertical position (vctr value)
//
//
//      04:     SZ      - size and offset register
//      04:     SZ      - size register
//                      bits
//                      bits
//                      [ 5: 0] width of sprite in pixels - 1
//                      [ 7: 0] width of sprite in pixels - 1
//                      [ 7: 6] size of horizontal pixels - 1 in clock cycles
//                      [15: 8] height of sprite in pixels -1
//                      [13: 8] height of sprite in pixels -1
//                      [19:16] size of horizontal pixels - 1 in clock cycles
//                      [15:14] size of vertical pixels in scan-lines - 1
//                      [23:20] size of vertical pixels in scan-lines - 1
//                              * the product of width * height cannot exceed 2048 !
//                              * the product of width * height cannot exceed 2048 !
//                              if it does, the display will begin repeating
//                              if it does, the display will begin repeating
//                              
//                              
//              OFFS    [26:16] image offset bits [10:0]
//      08: ADR [31:12] 20 bits sprite image address bits
//                      offset of the sprite image within the sprite image cache
//                      This registers contain the high order address bits of the
//                      typically zero
 
//
 
//      08: ADR 21 bits sprite image address bits [31:11]
 
//                      This registers contain the low order address bits of the
 
//          location of the sprite image in system memory.
//          location of the sprite image in system memory.
//                      The DMA controller will assign the low order 11 bits
//                      The DMA controller will assign the low order 12 bits
//                      during DMA.
//                      during DMA.
 
//                  [11:0] image offset bits [11:0]
 
//                      offset of the sprite image within the sprite image cache
 
//                      typically zero
//      
//      
//      0C: TC  [7:0]   transparent color
//      0C: TC  [15:0]  transparent color
//                      This register identifies which color of the sprite
//                      This register identifies which color of the sprite
//                      is transparent
//                      is transparent
//
//
//
//
//      0C-DC:  registers reserved for up to thirteen other sprites
//
 
//      0C-1FC: registers reserved for up to thirty-one other sprites
//
//
//      Global status and control
//      Global status and control
//      E8: BTC [23:0] background transparent color
//      3C0: EN [31:0] sprite enable register
//      EC: BC  [23:0] background color
//  3C4: IE     [31:0] sprite interrupt enable / status
//      F0: EN  [13:0] sprite enable register
//      3C8: SCOL       [31:0] sprite-sprite collision register
//              IE      [29:16] sprite interrupt enable / status
//      3CC: BCOL       [31:0] sprite-background collision register
//      F4: SCOL        [13:0] sprite-sprite collision register
//      3D0: DT         [31:0] sprite DMA trigger on
//              BCOL    [29:16] sprite-background collision register
//      3D4: DT         [31:0] sprite DMA trigger off
//      F8: DT          [13:0] sprite DMA trigger
//      3E8: BTC        [23:0] background transparent color
//  FC: ADDR    [31:0] sprite DMA address bits [63:32]
//      3EC: BC     [23:0] background color
 
//  3FC: ADDR   [31:0] sprite DMA address bits [63:32]
//
//
//
//
//      1635 LUTs/ 1112 slices/ 82MHz - Spartan3e-4 (8 sprites)
//      2200 LUTs/ 188MHz - xc7a100t (8 sprites)
//      3 8x8 multipliers (for alpha blending)
//      3 8x8 multipliers (for alpha blending)
//      14 block rams
//      16 block rams
//=============================================================== */
//=============================================================== */
 
 
`define VENDOR_XILINX   // block ram vendor (only one defined for now)
 
 
 
module rtfSpriteController(
module rtfSpriteController(
// Bus Slave interface
// Bus Slave interface
//------------------------------
//------------------------------
// Slave signals
// Slave signals
input rst_i,                    // reset
input rst_i,                    // reset
Line 124... Line 123...
input         s_cyc_i,  // cycle valid
input         s_cyc_i,  // cycle valid
input         s_stb_i,  // data transfer
input         s_stb_i,  // data transfer
output        s_ack_o,  // transfer acknowledge
output        s_ack_o,  // transfer acknowledge
input         s_we_i,   // write
input         s_we_i,   // write
input  [ 3:0] s_sel_i,   // byte select
input  [ 3:0] s_sel_i,   // byte select
input  [23:0] s_adr_i,   // address
input  [31:0] s_adr_i,   // address
input  [31:0] s_dat_i,   // data input
input  [31:0] s_dat_i,   // data input
output reg [31:0] s_dat_o,       // data output
output reg [31:0] s_dat_o,       // data output
output vol_o,                   // volatile register
output vol_o,                   // volatile register
//------------------------------
//------------------------------
// Bus Master Signals
// Bus Master Signals
output reg [1:0] m_bte_o,        // burst type
input m_clk_i,                          // clock
output reg [2:0] m_cti_o,        // cycle type
output [1:0]  m_bte_o,
output reg [5:0] m_bl_o, // burst length
output [2:0]  m_cti_o,
output reg    m_cyc_o,  // cycle is valid
output reg    m_cyc_o,  // cycle is valid
output reg    m_stb_o,  // strobe output
output        m_stb_o,  // strobe output
input         m_ack_i,  // input data is ready
input         m_ack_i,  // input data is ready
output reg    m_we_o,           // write (always inactive)
input         m_err_i,
output reg [ 3:0] m_sel_o,       // byte select
output        m_we_o,
output reg [63:0] m_adr_o,       // DMA address
output reg [31:0] m_adr_o,       // DMA address
input  [31:0] m_dat_i,   // data input
input  [31:0] m_dat_i,   // data input
output reg [31:0] m_dat_o,       // data output (always zero)
output [31:0] m_dat_o,
//--------------------------
//--------------------------
input vclk,                                     // video dot clock
input vclk,                                     // video dot clock
input hSync,                            // horizontal sync pulse
input hSync,                            // horizontal sync pulse
input vSync,                            // vertical sync pulse
input vSync,                            // vertical sync pulse
input blank,                            // blanking signal
input blank,                            // blanking signal
input [24:0] rgbIn,                      // input pixel stream
input [1:0] rgbPriority,
 
input [23:0] rgbIn,                      // input pixel stream
output reg [23:0] rgbOut,        // output pixel stream
output reg [23:0] rgbOut,        // output pixel stream
output irq                                      // interrupt request
output irq                                      // interrupt request
);
);
 
 
reg m_soc_o;
reg m_soc_o;
 
 
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Core Parameters
// Core Parameters
//--------------------------------------------------------------------
//--------------------------------------------------------------------
parameter pnSpr = 8;            // number of sprites
parameter pnSpr = 8;            // number of sprites
parameter phBits = 11;          // number of bits in horizontal timing counter
parameter phBits = 12;          // number of bits in horizontal timing counter
parameter pvBits = 11;          // number of bits in vertical timing counter
parameter pvBits = 12;          // number of bits in vertical timing counter
parameter pColorBits = 16;      // number of bits used for color data
parameter pColorBits = 16;      // number of bits used for color data
localparam pnSprm = pnSpr-1;
localparam pnSprm = pnSpr-1;
 
 
 
 
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// Variable Declarations
// Variable Declarations
//--------------------------------------------------------------------
//--------------------------------------------------------------------
 
 
wire [3:0] sprN = s_adr_i[7:4];
wire [4:0] sprN = s_adr_i[8:4];
 
 
reg [phBits-1:0] hctr;           // horizontal reference counter (counts dots since hSync)
reg [phBits-1:0] hctr;           // horizontal reference counter (counts dots since hSync)
reg [pvBits-1:0] vctr;           // vertical reference counter (counts scanlines since vSync)
reg [pvBits-1:0] vctr;           // vertical reference counter (counts scanlines since vSync)
reg sprSprIRQ;
reg sprSprIRQ;
reg sprBkIRQ;
reg sprBkIRQ;
Line 185... Line 185...
 
 
reg [pnSprm:0] sprWe;    // block ram write enable for image cache update
reg [pnSprm:0] sprWe;    // block ram write enable for image cache update
reg [pnSprm:0] sprRe;    // block ram read enable for image cache update
reg [pnSprm:0] sprRe;    // block ram read enable for image cache update
 
 
// Global control registers
// Global control registers
reg [15:0] sprEn;        // enable sprite
reg [31:0] sprEn;        // enable sprite
reg [pnSprm:0] sprCollision;         // sprite-sprite collision
reg [pnSprm:0] sprCollision;         // sprite-sprite collision
reg sprSprIe;                   // sprite-sprite interrupt enable
reg sprSprIe;                   // sprite-sprite interrupt enable
reg sprBkIe;            // sprite-background interrupt enable
reg sprBkIe;            // sprite-background interrupt enable
reg sprSprIRQPending;   // sprite-sprite collision interrupt pending
reg sprSprIRQPending;   // sprite-sprite collision interrupt pending
reg sprBkIRQPending;    // sprite-background collision interrupt pending
reg sprBkIRQPending;    // sprite-background collision interrupt pending
Line 197... Line 197...
reg sprBkIRQPending1;   // sprite-background collision interrupt pending
reg sprBkIRQPending1;   // sprite-background collision interrupt pending
reg sprSprIRQ1;                 // vclk domain regs
reg sprSprIRQ1;                 // vclk domain regs
reg sprBkIRQ1;
reg sprBkIRQ1;
 
 
// Sprite control registers
// Sprite control registers
reg [15:0] sprSprCollision;
reg [31:0] sprSprCollision;
reg [pnSprm:0] sprSprCollision1;
reg [pnSprm:0] sprSprCollision1;
reg [15:0] sprBkCollision;
reg [31:0] sprBkCollision;
reg [pnSprm:0] sprBkCollision1;
reg [pnSprm:0] sprBkCollision1;
reg [pColorBits-1:0] sprTc [pnSprm:0];            // sprite transparent color code
reg [pColorBits-1:0] sprTc [pnSprm:0];            // sprite transparent color code
// How big the pixels are:
// How big the pixels are:
// 1,2,3,or 4 video clocks
// 1 to 16 video clocks
reg [1:0] hSprRes [pnSprm:0];             // sprite horizontal resolution
reg [3:0] hSprRes [pnSprm:0];             // sprite horizontal resolution
reg [1:0] vSprRes [pnSprm:0];             // sprite vertical resolution
reg [3:0] vSprRes [pnSprm:0];             // sprite vertical resolution
reg [5:0] sprWidth [pnSprm:0];            // number of pixels in X direction
reg [7:0] sprWidth [pnSprm:0];            // number of pixels in X direction
reg [5:0] sprHeight [pnSprm:0];           // number of vertical pixels
reg [7:0] sprHeight [pnSprm:0];           // number of vertical pixels
 
 
// display and timing signals
// display and timing signals
reg [13:0] hSprReset;   // horizontal reset
reg [31:0] hSprReset;   // horizontal reset
reg [13:0] vSprReset;   // vertical reset
reg [31:0] vSprReset;   // vertical reset
reg [13:0] hSprDe;               // sprite horizontal display enable
reg [31:0] hSprDe;               // sprite horizontal display enable
reg [13:0] vSprDe;               // sprite vertical display enable
reg [31:0] vSprDe;               // sprite vertical display enable
reg [13:0] sprDe;                        // display enable
reg [31:0] sprDe;                        // display enable
reg [phBits-1:0] hSprPos [pnSprm:0];      // sprite horizontal position
reg [phBits-1:0] hSprPos [pnSprm:0];      // sprite horizontal position
reg [pvBits-1:0] vSprPos [pnSprm:0];      // sprite vertical position
reg [pvBits-1:0] vSprPos [pnSprm:0];      // sprite vertical position
reg [5:0] hSprCnt [pnSprm:0];     // sprite horizontal display counter
reg [7:0] hSprCnt [pnSprm:0];     // sprite horizontal display counter
reg [5:0] vSprCnt [pnSprm:0];     // vertical display counter
reg [7:0] vSprCnt [pnSprm:0];     // vertical display counter
reg [10:0] sprImageOffs [pnSprm:0];       // offset within sprite memory
reg [11:0] sprImageOffs [pnSprm:0];       // offset within sprite memory
reg [10:0] sprAddr [pnSprm:0];    // index into sprite memory
reg [11:0] sprAddr [pnSprm:0];    // index into sprite memory
reg [10:0] sprAddrB [pnSprm:0];   // backup address cache for rescan
reg [11:0] sprAddrB [pnSprm:0];   // backup address cache for rescan
wire [pColorBits-1:0] sprOut [pnSprm:0];  // sprite image data output
wire [pColorBits-1:0] sprOut [pnSprm:0];  // sprite image data output
 
 
// DMA access
// DMA access
reg [63:32] sprSysAddrHx;       // high order 32 bits of sprite memory address
reg [31:12] sprSysAddr [pnSprm:0];       // system memory address of sprite image (low bits)
reg [26:11] sprSysAddrL [pnSprm:0];      // system memory address of sprite image (low bits)
reg [4:0] dmaOwner;                      // which sprite has the DMA channel
reg [31:27] sprSysAddrH [pnSprm:0];      // system memory address of sprite image (high bits)
reg [31:0] sprDt;                // DMA trigger register
reg [3:0] dmaOwner;                      // which sprite has the DMA channel
 
reg [15:0] sprDt;                // DMA trigger register
 
reg dmaActive;                          // this flag indicates that a block DMA transfer is active
reg dmaActive;                          // this flag indicates that a block DMA transfer is active
 
 
integer n;
integer n;
 
 
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// DMA control / bus interfacing
// DMA control / bus interfacing
//--------------------------------------------------------------------
//--------------------------------------------------------------------
wire cs_ram = s_cyc_i && s_stb_i && (s_adr_i[23:16]==8'hD8);
wire cs_ram = s_cyc_i && s_stb_i && (s_adr_i[31:16]==16'hFFD8 || s_adr_i[31:16]==16'hFFD9);
wire cs_regs = s_cyc_i && s_stb_i && (s_adr_i[23:8]==16'hDA_D0);
wire cs_regs = s_cyc_i && s_stb_i && (s_adr_i[31:12]==20'hFFDAD);
 
 
reg sprRdy;
reg sprRdy;
always @(posedge clk_i)
always @(posedge clk_i)
        sprRdy = (cs_ram|cs_regs);
        sprRdy = (cs_ram|cs_regs);
 
 
//assign s_ack_o = cs_regs ? 1'b1 : cs_ram ? (s_we_i ? 1 : sprRamRdy) : 0;
//assign s_ack_o = cs_regs ? 1'b1 : cs_ram ? (s_we_i ? 1 : sprRamRdy) : 0;
assign s_ack_o = (cs_regs|cs_ram) ? (s_we_i ? 1'b1 : sprRdy) : 1'b0;
assign s_ack_o = (cs_regs|cs_ram) ? (s_we_i ? 1'b1 : sprRdy) : 1'b0;
assign vol_o = cs_regs & s_adr_i[8:2]>7'd111;
assign vol_o = cs_regs & s_adr_i[9:2]>=8'b11110000;
assign irq = sprSprIRQ|sprBkIRQ;
assign irq = sprSprIRQ|sprBkIRQ;
 
 
//--------------------------------------------------------------------
//--------------------------------------------------------------------
// DMA control / bus interfacing
// DMA control / bus interfacing
//--------------------------------------------------------------------
//--------------------------------------------------------------------
reg dmaStart;
reg dmaStart;
 
 
wire btout;
wire sbi_rdy1 = m_ack_i|m_err_i;
wire sbi_rdy1 = m_ack_i|btout;
 
busTimeoutCtr #(20) br0(
 
        .rst(rst_i),
 
        .crst(1'b0),
 
        .clk(clk_i),
 
        .ce(1'b1),
 
        .req(m_soc_o),
 
        .rdy(m_ack_i),
 
        .timeout(btout)
 
);
 
 
 
reg [4:0] cob;   // count of burst cycles
reg [7:0] cob;   // count of burst cycles
 
 
always @(posedge clk_i)
assign m_bte_o = 2'b00;
 
assign m_cti_o = 3'b000;
 
assign m_stb_o = 1'b1;
 
assign m_we_o = 1'b0;
 
assign m_dat_o = 32'h00000;
 
 
 
always @(posedge m_clk_i)
if (rst_i) begin
if (rst_i) begin
        dmaStart <= 1'b0;
        dmaStart <= 1'b0;
        dmaActive <= 1'b0;
        dmaActive <= 1'b0;
        dmaOwner <= 4'd0;
        dmaOwner <= 4'd0;
        m_bte_o <= 2'b00;
        wb_m_nack();
        m_cti_o <= 3'b000;
        cob <= 8'd0;
        m_bl_o <= 6'd63;
 
        m_soc_o <= 1'b0;
 
        m_cyc_o <= 1'b0;
 
        m_stb_o <= 1'b0;
 
        m_we_o <= 1'b0;
 
        m_sel_o <= 4'h0;
 
        m_adr_o <= 44'd0;
 
        m_dat_o <= 32'd0;
 
        cob <= 5'd0;
 
end
end
else begin
else begin
        dmaStart <= 1'b0;
        dmaStart <= 1'b0;
        m_soc_o <= 1'b0;
        m_soc_o <= 1'b0;
        if (!dmaActive) begin
        if (!dmaActive) begin
                cob <= 5'd0;
                cob <= 8'd0;
                dmaStart <= |sprDt;
                dmaStart <= |sprDt;
                dmaActive <= |sprDt;
                dmaActive <= |sprDt;
                dmaOwner  <= 0;
                dmaOwner  <= 0;
                for (n = pnSprm; n >= 0; n = n - 1)
                for (n = pnSprm; n >= 0; n = n - 1)
                        if (sprDt[n]) dmaOwner <= n;
                        if (sprDt[n]) dmaOwner <= n;
        end
        end
        else begin
        else begin
                if (!m_cyc_o) begin
                if (!m_cyc_o) begin
                        m_bte_o <= 2'b00;
 
                        m_cti_o <= 3'b010;
 
                        m_cyc_o <= 1'b1;
                        m_cyc_o <= 1'b1;
                        m_stb_o <= 1'b1;
                        m_adr_o <= {sprSysAddr[dmaOwner],cob[7:0],4'h0};
                        m_sel_o <= 4'b1111;
 
                        m_bl_o <= 6'd63;
 
                        m_adr_o <= {sprSysAddrHx,sprSysAddrH[dmaOwner],sprSysAddrL[dmaOwner],cob[2:0],8'h00};
 
                        m_soc_o <= 1'b1;
                        m_soc_o <= 1'b1;
                        cob <= cob + 5'd1;
                        cob <= cob + 8'd1;
                end
                end
                else if (m_ack_i|btout) begin
                else if (m_ack_i|m_err_i) begin
                        m_soc_o <= 1'b1;
                        m_soc_o <= 1'b1;
                        m_adr_o[7:0] <= m_adr_o[7:0] + 8'd4;
                        m_adr_o[3:0] <= m_adr_o[3:0] + 8'd4;
                        // Flag last cycle of burst
                        if (m_adr_o[3:0]==4'hC) begin
                        if (m_adr_o[7:0]==8'hF8)
                                wb_m_nack();
                                m_cti_o <= 3'b111;
                                if (cob==8'd255)
                        if (m_adr_o[7:0]==8'hFC) begin
 
                                m_soc_o <= 1'b0;
 
                                m_cyc_o <= 1'b0;
 
                                m_stb_o <= 1'b0;
 
                                m_sel_o <= 4'b0000;
 
                                m_cti_o <= 3'b000;
 
                                m_adr_o <= 44'd0;
 
                                if (cob==5'd8)
 
                                        dmaActive <= 1'b0;
                                        dmaActive <= 1'b0;
                        end
                        end
                end
                end
        end
        end
end
end
 
 
 
task wb_m_nack;
 
begin
 
        m_soc_o <= 1'b0;
 
        m_cyc_o <= 1'b0;
 
end
 
endtask
 
 
// generate a write enable strobe for the sprite image memory
// generate a write enable strobe for the sprite image memory
always @(dmaOwner, dmaActive, s_adr_i, cs_ram, s_we_i, m_ack_i)
always @(dmaOwner, dmaActive, s_adr_i, cs_ram, s_we_i, m_ack_i)
for (n = 0; n < pnSpr; n = n + 1)
for (n = 0; n < pnSpr; n = n + 1)
        sprWe[n] = (dmaOwner==n && dmaActive && m_ack_i)||(cs_ram && s_we_i && s_adr_i[14:11]==n);
        sprWe[n] = (dmaOwner==n && dmaActive && m_ack_i)||(cs_ram && s_we_i && s_adr_i[16:12]==n);
 
 
always @(cs_ram, s_adr_i)
always @(cs_ram, s_adr_i)
for (n = 0; n < pnSpr; n = n + 1)
for (n = 0; n < pnSpr; n = n + 1)
        sprRe[n] = cs_ram && s_adr_i[14:11]==n;
        sprRe[n] = cs_ram && s_adr_i[16:12]==n;
 
 
 
//--------------------------------------------------------------------
 
//--------------------------------------------------------------------
 
 
wire [31:0] sr_dout [pnSprm:0];
wire [31:0] sr_dout [pnSprm:0];
reg [31:0] sr_dout_all;
reg [31:0] sr_dout_all;
 
 
generate
generate
Line 356... Line 338...
else if (pnSpr==8)
else if (pnSpr==8)
        sr_dout_all <= sr_dout[0]|sr_dout[1]|sr_dout[2]|sr_dout[3]|sr_dout[4]|sr_dout[5]|sr_dout[6]|sr_dout[7];//|
        sr_dout_all <= sr_dout[0]|sr_dout[1]|sr_dout[2]|sr_dout[3]|sr_dout[4]|sr_dout[5]|sr_dout[6]|sr_dout[7];//|
else if (pnSpr==14)
else if (pnSpr==14)
        sr_dout_all <= sr_dout[0]|sr_dout[1]|sr_dout[2]|sr_dout[3]|sr_dout[4]|sr_dout[5]|sr_dout[6]|sr_dout[7]|
        sr_dout_all <= sr_dout[0]|sr_dout[1]|sr_dout[2]|sr_dout[3]|sr_dout[4]|sr_dout[5]|sr_dout[6]|sr_dout[7]|
                                                        sr_dout[8]|sr_dout[9]|sr_dout[10]|sr_dout[11]|sr_dout[12]|sr_dout[13];
                                                        sr_dout[8]|sr_dout[9]|sr_dout[10]|sr_dout[11]|sr_dout[12]|sr_dout[13];
 
else if (pnSpr==32)
 
        sr_dout_all <= sr_dout[0]|sr_dout[1]|sr_dout[2]|sr_dout[3]|sr_dout[4]|sr_dout[5]|sr_dout[6]|sr_dout[7]|
 
                                   sr_dout[8]|sr_dout[9]|sr_dout[10]|sr_dout[11]|sr_dout[12]|sr_dout[13]|sr_dout[14]|sr_dout[15]|
 
                                   sr_dout[16]|sr_dout[17]|sr_dout[18]|sr_dout[19]|sr_dout[20]|sr_dout[21]|sr_dout[22]|sr_dout[23]|
 
                                   sr_dout[24]|sr_dout[25]|sr_dout[26]|sr_dout[27]|sr_dout[28]|sr_dout[29]|sr_dout[30]|sr_dout[31]
 
                                   ;
end
end
endgenerate
endgenerate
 
 
// register/sprite memory output mux
// register/sprite memory output mux
always @(posedge clk_i)
always @(posedge clk_i)
        if (cs_ram)
        if (cs_ram)
                s_dat_o <= sr_dout_all;
                s_dat_o <= sr_dout_all;
        else if (cs_regs)
        else if (cs_regs)
                case (s_adr_i[7:1])             // synopsys full_case parallel_case
                case (s_adr_i[9:2])             // synopsys full_case parallel_case
                7'd120: s_dat_o <= {2{sprEn}};
                8'b11110000:    s_dat_o <= sprEn;
                7'd121: s_dat_o <= {2{sprBkIRQPending|sprSprIRQPending,5'b0,sprBkIRQPending,sprSprIRQPending,6'b0,sprBkIe,sprSprIe}};
                8'b11110001:    s_dat_o <= {sprBkIRQPending|sprSprIRQPending,5'b0,sprBkIRQPending,sprSprIRQPending,6'b0,sprBkIe,sprSprIe};
                7'd122: s_dat_o <= {2{sprSprCollision}};
                8'b11110010:    s_dat_o <= sprSprCollision;
                7'd123: s_dat_o <= {2{sprBkCollision}};
                8'b11110011:    s_dat_o <= sprBkCollision;
                7'd124: s_dat_o <= {2{sprDt}};
                8'b11110100:    s_dat_o <= sprDt;
                default:        s_dat_o <= 0;
                default:        s_dat_o <= 32'd0;
                endcase
                endcase
        else
        else
                s_dat_o <= 32'd0;
                s_dat_o <= 32'd0;
 
 
 
 
Line 395... Line 383...
always @(posedge clk_i)
always @(posedge clk_i)
if (rst_i) begin
if (rst_i) begin
        sprEn <= {pnSpr{1'b1}};
        sprEn <= {pnSpr{1'b1}};
        sprDt <= 0;
        sprDt <= 0;
    for (n = 0; n < pnSpr; n = n + 1) begin
    for (n = 0; n < pnSpr; n = n + 1) begin
                sprSysAddrL[n] <= 5'b0100_0 + n;        //xxxx_4000
                sprSysAddr[n] <= 20'b0001_0000_0000_0100 + n;    //1000_4000
                sprSysAddrH[n] <= 16'h0000;                     //0000_xxxx
 
        end
        end
        sprSprIe <= 0;
        sprSprIe <= 0;
        sprBkIe  <= 0;
        sprBkIe  <= 0;
 
 
    // Set reasonable starting positions on the screen
    // Set reasonable starting positions on the screen
    // so that the sprites might be visible for testing
    // so that the sprites might be visible for testing
    for (n = 0; n < pnSpr; n = n + 1) begin
    for (n = 0; n < pnSpr; n = n + 1) begin
        hSprPos[n] <= 440 + n * 50;
        hSprPos[n] <= 400 + (n & 15) * 60;
        vSprPos[n] <= 200;
        vSprPos[n] <= 200 + (n > 16 ? 100 : 0);
        sprTc[n] <= 16'h6739;
        sprTc[n] <= 16'h6739;
                sprWidth[n] <= 47;  // 48x42 sprites
                sprWidth[n] <= 56;  // 56x36 sprites
                sprHeight[n] <= 41;
                sprHeight[n] <= 36;
                hSprRes[n] <= 0; // our standard display
                hSprRes[n] <= 0; // our standard display
                vSprRes[n] <= 0;
                vSprRes[n] <= 0;
                sprImageOffs[n] <= 0;
                sprImageOffs[n] <= 0;
        end
        end
    hSprPos[0] <= 290;
    hSprPos[0] <= 290;
Line 426... Line 413...
        if (dmaStart)
        if (dmaStart)
                sprDt[dmaOwner] <= 1'b0;
                sprDt[dmaOwner] <= 1'b0;
 
 
        if (cs_regs & s_we_i) begin
        if (cs_regs & s_we_i) begin
 
 
                casex (s_adr_i[8:1])
                casex (s_adr_i[9:2])
 
                8'b11110000:    // 3C0
                8'd116,8'd117:
 
                        begin
 
                                if (s_sel_i[0]) bgTc[7:0] <= s_dat_i[7:0];
 
                                if (s_sel_i[1]) bgTc[15:8] <= s_dat_i[15:8];
 
                                if (s_sel_i[2]) bgTc[23:16] <= s_dat_i[23:16];
 
                        end
 
                8'd118,8'd119:
 
                        begin
 
                                if (s_sel_i[0]) bkColor[7:0] <= s_dat_i[7:0];
 
                                if (s_sel_i[1]) bkColor[15:8] <= s_dat_i[15:8];
 
                                if (s_sel_i[2]) bkColor[23:16] <= s_dat_i[23:16];
 
                        end
 
                8'd120,8'd121:
 
                        begin
                        begin
                                if (s_sel_i[0]) sprEn[7:0] <= s_dat_i[7:0];
                                if (s_sel_i[0]) sprEn[7:0] <= s_dat_i[7:0];
                                if (s_sel_i[1]) sprEn[13:8] <= s_dat_i[13:8];
                                if (s_sel_i[1]) sprEn[15:8] <= s_dat_i[15:8];
                                if (s_sel_i[2]) begin
                                if (s_sel_i[2]) sprEn[23:16] <= s_dat_i[23:16];
                                        sprSprIe <= s_dat_i[16];
                                if (s_sel_i[3]) sprEn[31:24] <= s_dat_i[31:24];
                                        sprBkIe <= s_dat_i[17];
 
                                end
                                end
 
                8'b11110001:    // 3C4
 
                        if (s_sel_i[0]) begin
 
                                sprSprIe <= s_dat_i[0];
 
                                sprBkIe <= s_dat_i[1];
                        end
                        end
                // update DMA trigger
                // update DMA trigger
                // s_dat_i[7:0] indicates which triggers to set  (1=set,0=ignore)
                // s_dat_i[7:0] indicates which triggers to set  (1=set,0=ignore)
                // s_dat_i[7:0] indicates which triggers to clear (1=clear,0=ignore)
                // s_dat_i[7:0] indicates which triggers to clear (1=clear,0=ignore)
                8'd124,8'd125:
                8'b11110100:    // 3D0
                        begin
                        begin
                                if (s_sel_i[0])  sprDt[7:0] <= sprDt[7:0] | s_dat_i[7:0];
                                if (s_sel_i[0])  sprDt[7:0] <= sprDt[7:0] | s_dat_i[7:0];
                                if (s_sel_i[1]) sprDt[13:8] <= sprDt[13:8] | s_dat_i[13:8];
                                if (s_sel_i[1]) sprDt[15:8] <= sprDt[15:8] | s_dat_i[15:8];
                                if (s_sel_i[2]) sprDt[7:0] <= sprDt[7:0] & ~s_dat_i[23:16];
                                if (s_sel_i[2]) sprDt[23:16] <= sprDt[23:16] | s_dat_i[23:16];
                                if (s_sel_i[3]) sprDt[13:8] <= sprDt[13:8] & ~s_dat_i[29:24];
                                if (s_sel_i[3]) sprDt[31:24] <= sprDt[31:24] | s_dat_i[31:24];
                        end
                        end
                8'd126,8'd127:
                8'b11110101:    // 3D4
                        begin
                        begin
                                if (sel_i[0]) sprSysAddrHx[39:32] <= s_dat_i[ 7: 0];
                                if (s_sel_i[0])  sprDt[7:0] <= sprDt[7:0] & ~s_dat_i[7:0];
                                if (sel_i[1]) sprSysAddrHx[47:40] <= s_dat_i[15: 8];
                                if (s_sel_i[1]) sprDt[15:8] <= sprDt[15:8] & ~s_dat_i[15:8];
                                if (sel_i[2]) sprSysAddrHx[55:48] <= s_dat_i[23:16];
                                if (s_sel_i[2]) sprDt[23:16] <= sprDt[23:16] & ~s_dat_i[23:16];
                                if (sel_i[3]) sprSysAddrHx[63:56] <= s_dat_i[31:24];
                                if (s_sel_i[3]) sprDt[31:24] <= sprDt[31:24] & ~s_dat_i[31:24];
                        end
                        end
                8'b0xxxx00x:
                8'b11111010:    // 3E8
 
                        begin
 
                                if (s_sel_i[0])  bgTc[7:0] <= s_dat_i[7:0];
 
                                if (s_sel_i[1]) bgTc[15:8] <= s_dat_i[15:8];
 
                                if (s_sel_i[2]) bgTc[23:16] <= s_dat_i[23:16];
 
                        end
 
                8'b11111011:    // 3EC
 
                        begin
 
                                if (s_sel_i[0]) bkColor[7:0] <= s_dat_i[7:0];
 
                                if (s_sel_i[1]) bkColor[15:8] <= s_dat_i[15:8];
 
                                if (s_sel_i[2]) bkColor[23:16] <= s_dat_i[23:16];
 
                        end
 
                8'b0xxxxx00:
                         begin
                         begin
                        if (s_sel_i[0]) hSprPos[sprN][ 7:0] <= s_dat_i[ 7: 0];
                        if (s_sel_i[0]) hSprPos[sprN][ 7:0] <= s_dat_i[ 7: 0];
                        if (s_sel_i[1]) hSprPos[sprN][10:8] <= s_dat_i[10: 8];
                        if (s_sel_i[1]) hSprPos[sprN][10:8] <= s_dat_i[10: 8];
                        if (s_sel_i[2]) vSprPos[sprN][ 7:0] <= s_dat_i[23:16];
                        if (s_sel_i[2]) vSprPos[sprN][ 7:0] <= s_dat_i[23:16];
                        if (s_sel_i[3]) vSprPos[sprN][10:8] <= s_dat_i[26:24];
                        if (s_sel_i[3]) vSprPos[sprN][10:8] <= s_dat_i[26:24];
                end
                end
        8'b0xxxx01x:
        8'b0xxxxx01:
                        begin
                        begin
                        if (s_sel_i[0]) begin
                        if (s_sel_i[0]) begin
                                        sprWidth[sprN] <= s_dat_i[5:0];
                                        sprWidth[sprN] <= s_dat_i[7:0];
                        hSprRes[sprN] <= s_dat_i[7:6];
 
                    end
                    end
                        if (s_sel_i[1]) begin
                        if (s_sel_i[1]) begin
                                        sprHeight[sprN] <= s_dat_i[13:8];
                                        sprHeight[sprN] <= s_dat_i[15:8];
                        vSprRes[sprN] <= s_dat_i[15:14];
 
                    end
                    end
                    if (s_sel_i[2]) sprImageOffs[sprN][ 7:0] <= s_dat_i[23:16];
                                if (s_sel_i[2]) begin
                    if (s_sel_i[3]) sprImageOffs[sprN][10:8] <= s_dat_i[26:24];
                        hSprRes[sprN] <= s_dat_i[19:16];
 
                        vSprRes[sprN] <= s_dat_i[23:20];
                        end
                        end
                8'b0xxxx10x:
                        end
 
                8'b0xxxxx10:
                        begin   // DMA address set on clk_i domain
                        begin   // DMA address set on clk_i domain
                                if (s_sel_i[0]) sprSysAddrL[sprN][18:11] <= s_dat_i[ 7: 0];
                    if (s_sel_i[0]) sprImageOffs[sprN][ 7:0] <= s_dat_i[7:0];
                                if (s_sel_i[1]) sprSysAddrL[sprN][26:19] <= s_dat_i[15: 8];
                    if (s_sel_i[1]) sprImageOffs[sprN][10:8] <= s_dat_i[11:8];
                                if (s_sel_i[2]) sprSysAddrH[sprN][34:27] <= s_dat_i[23:16];
                                if (s_sel_i[1]) sprSysAddr[sprN][15:12] <= s_dat_i[15:12];
                                if (s_sel_i[3]) sprSysAddrH[sprN][42:35] <= s_dat_i[31:24];
                                if (s_sel_i[2]) sprSysAddr[sprN][23:16] <= s_dat_i[23:16];
 
                                if (s_sel_i[3]) sprSysAddr[sprN][31:24] <= s_dat_i[31:24];
                        end
                        end
                8'b0xxxx11x:
                8'b0xxxxx11:
                        begin
                        begin
                                if (s_sel_i[0]) sprTc[sprN][ 7:0] <= s_dat_i[ 7:0];
                                if (s_sel_i[0]) sprTc[sprN][ 7:0] <= s_dat_i[ 7:0];
                                if (pColorBits>8)
                                if (pColorBits>8)
                                        if (s_sel_i[1]) sprTc[sprN][15:8] <= s_dat_i[15:8];
                                        if (s_sel_i[1]) sprTc[sprN][15:8] <= s_dat_i[15:8];
                        end
                        end
Line 511... Line 501...
//-------------------------------------------------------------
//-------------------------------------------------------------
// Sprite Image Cache RAM
// Sprite Image Cache RAM
// This RAM is dual ported with an SoC side and a display
// This RAM is dual ported with an SoC side and a display
// controller side.
// controller side.
//-------------------------------------------------------------
//-------------------------------------------------------------
wire [10:2] sr_adr = m_cyc_o ? m_adr_o[10:2] : s_adr_i[10:2];
wire [11:2] sr_adr = m_cyc_o ? m_adr_o[11:2] : s_adr_i[11:2];
wire [31:0] sr_din = m_cyc_o ? m_dat_i[31:0] : s_dat_i[31:0];
wire [31:0] sr_din = m_cyc_o ? m_dat_i[31:0] : s_dat_i[31:0];
wire sr_ce = m_cyc_o ? sbi_rdy1 : cs_ram;
wire sr_ce = m_cyc_o ? sbi_rdy1 : cs_ram;
 
 
// Note: the sprite output can't be zeroed out using the rst input!!!
// Note: the sprite output can't be zeroed out using the rst input!!!
// We need to know what the output is to determine if it's the 
// We need to know what the output is to determine if it's the 
Line 542... Line 532...
                        );
                        );
                else if (pColorBits==16)
                else if (pColorBits==16)
                        rtfSpriteRam16 sprRam0
                        rtfSpriteRam16 sprRam0
                        (
                        (
                                .clka(vclk),
                                .clka(vclk),
                                .adra(sprAddr[g]),
                                .adra(sprAddr[g][10:0]),
                                .doa(sprOut[g]),
                                .doa(sprOut[g]),
                                .cea(1'b1),
                                .cea(1'b1),
 
 
                                .clkb(~clk_i),
                                .clkb(~clk_i),
                                .adrb(sr_adr),
                                .adrb(sr_adr),
Line 592... Line 582...
always @(posedge vclk)
always @(posedge vclk)
for (n = 0; n < pnSpr; n = n + 1)
for (n = 0; n < pnSpr; n = n + 1)
        vSprReset[n] <= vctr==vSprPos[n];
        vSprReset[n] <= vctr==vSprPos[n];
 
 
always @(hSprDe, vSprDe)
always @(hSprDe, vSprDe)
for (n = 0; n < 14; n = n + 1)
for (n = 0; n < pnSpr; n = n + 1)
        sprDe[n] <= hSprDe[n] & vSprDe[n];
        sprDe[n] <= hSprDe[n] & vSprDe[n];
 
 
 
 
// take care of sprite size scaling
// take care of sprite size scaling
// video clock division
// video clock division
reg [13:0] hSprNextPixel;
reg [31:0] hSprNextPixel;
reg [13:0] vSprNextPixel;
reg [31:0] vSprNextPixel;
reg [1:0] hSprPt [13:0];   // horizontal pixel toggle
reg [3:0] hSprPt [31:0];   // horizontal pixel toggle
reg [1:0] vSprPt [13:0];   // vertical pixel toggle
reg [3:0] vSprPt [31:0];   // vertical pixel toggle
always @(n)
always @(n)
for (n = 0; n < pnSpr; n = n + 1)
for (n = 0; n < pnSpr; n = n + 1)
    hSprNextPixel[n] = hSprPt[n]==hSprRes[n];
    hSprNextPixel[n] = hSprPt[n]==hSprRes[n];
always @(n)
always @(n)
for (n = 0; n < pnSpr; n = n + 1)
for (n = 0; n < pnSpr; n = n + 1)
Line 727... Line 717...
end
end
endfunction
endfunction
 
 
 
 
// pipeline delays for display enable
// pipeline delays for display enable
reg [14:0] sprDe1;
reg [31:0] sprDe1;
reg [14:0] sproact;
reg [31:0] sproact;
always @(posedge vclk)
always @(posedge vclk)
for (n = 0; n < pnSpr; n = n + 1) begin
for (n = 0; n < pnSpr; n = n + 1) begin
        sprDe1[n] <= sprDe[n];
        sprDe1[n] <= sprDe[n];
end
end
 
 
Line 774... Line 764...
// display color priority bit [24] 1=display is over sprite
// display color priority bit [24] 1=display is over sprite
always @(posedge vclk)
always @(posedge vclk)
if (blank)
if (blank)
        rgbOut <= 0;
        rgbOut <= 0;
else begin
else begin
        if (rgbIn[24] && rgbIn[23:0] != bgTc)    // color is in front of sprite
        if (rgbPriority==2'b10 && rgbIn[23:0] != bgTc)   // color is in front of sprite
                rgbOut <= rgbIn[23:0];
                rgbOut <= rgbIn[23:0];
        else if (outact) begin
        else if (outact) begin
                if (!out[15]) begin                     // a sprite is displayed without alpha blending
                if (!out[15]) begin                     // a sprite is displayed without alpha blending
                        if (pColorBits==8)
                        if (pColorBits==8)
                                rgbOut <= {out[7:5],5'b0,out[4:2],5'b0,out[1:0],6'b0};
                                rgbOut <= {out[7:5],5'b0,out[4:2],5'b0,out[1:0],6'b0};
Line 866... Line 856...
        14'b00100000000000,
        14'b00100000000000,
        14'b01000000000000,
        14'b01000000000000,
        14'b10000000000000:     sprCollision = 0;
        14'b10000000000000:     sprCollision = 0;
        default:                        sprCollision = 1;
        default:                        sprCollision = 1;
        endcase
        endcase
 
else if (pnSpr==32)
 
        case (sproact)
 
        32'h00000000,
 
        32'h00000001,
 
        32'h00000002,
 
        32'h00000004,
 
        32'h00000008,
 
        32'h00000010,
 
        32'h00000020,
 
        32'h00000040,
 
        32'h00000080,
 
        32'h00000100,
 
        32'h00000200,
 
        32'h00000400,
 
        32'h00000800,
 
        32'h00001000,
 
        32'h00002000,
 
        32'h00004000,
 
        32'h00008000,
 
        32'h00010000,
 
        32'h00020000,
 
        32'h00040000,
 
        32'h00080000,
 
        32'h00100000,
 
        32'h00200000,
 
        32'h00400000,
 
        32'h00800000,
 
        32'h01000000,
 
        32'h02000000,
 
        32'h04000000,
 
        32'h08000000,
 
        32'h10000000,
 
        32'h20000000,
 
        32'h40000000,
 
        32'h80000000:           sprCollision = 0;
 
        default:                        sprCollision = 1;
 
        endcase
end
end
endgenerate
endgenerate
 
 
// Detect when a sprite-background collision has occurred
// Detect when a sprite-background collision has occurred
assign bkCollision = (rgbIn[24] && rgbIn[23:0] != bgTc) ? 0 :
assign bkCollision = //(rgbIn[24] && rgbIn[23:0] != bgTc) ? 0 :
                outact && rgbIn[23:0] != bkColor;
                outact && rgbPriority==2'b01;//rgbIn[23:0] != bkColor;
 
 
// Load the sprite collision register. This register continually
// Load the sprite collision register. This register continually
// accumulates collision bits until reset by reading the register.
// accumulates collision bits until reset by reading the register.
// Set the collision IRQ on the first collision and don't set it
// Set the collision IRQ on the first collision and don't set it
// again until after the collision register has been read.
// again until after the collision register has been read.
Line 885... Line 912...
        sprSprCollision1 <= 0;
        sprSprCollision1 <= 0;
        sprSprIRQ1 <= 0;
        sprSprIRQ1 <= 0;
end
end
else if (sprCollision) begin
else if (sprCollision) begin
        // isFirstCollision
        // isFirstCollision
        if ((sprSprCollision1==0)||(cs_regs && s_sel_i[0] && s_adr_i[7:1]==7'd122)) begin
        if ((sprSprCollision1==0)||(cs_regs && s_sel_i[0] && s_adr_i[9:2]==8'b11110010)) begin
                sprSprIRQPending1 <= 1;
                sprSprIRQPending1 <= 1;
                sprSprIRQ1 <= sprSprIe;
                sprSprIRQ1 <= sprSprIe;
                sprSprCollision1 <= sproact;
                sprSprCollision1 <= sproact;
        end
        end
        else
        else
                sprSprCollision1 <= sprSprCollision1|sproact;
                sprSprCollision1 <= sprSprCollision1|sproact;
end
end
else if (cs_regs && s_sel_i[0] && s_adr_i[7:1]==7'd122) begin
else if (cs_regs && s_sel_i[0] && s_adr_i[9:2]==8'b11110010) begin
        sprSprCollision1 <= 0;
        sprSprCollision1 <= 0;
        sprSprIRQPending1 <= 0;
        sprSprIRQPending1 <= 0;
        sprSprIRQ1 <= 0;
        sprSprIRQ1 <= 0;
end
end
 
 
Line 917... Line 944...
end
end
else if (bkCollision) begin
else if (bkCollision) begin
        // Is the register being cleared at the same time
        // Is the register being cleared at the same time
        // a collision occurss ?
        // a collision occurss ?
        // isFirstCollision
        // isFirstCollision
        if ((sprBkCollision1==0) || (cs_regs && s_sel_i[0] && s_adr_i[7:1]==7'd123)) begin
        if ((sprBkCollision1==0) || (cs_regs && s_sel_i[0] && s_adr_i[9:2]==8'b11110011)) begin
                sprBkIRQ1 <= sprBkIe;
                sprBkIRQ1 <= sprBkIe;
                sprBkCollision1 <= sproact;
                sprBkCollision1 <= sproact;
                sprBkIRQPending1 <= 1;
                sprBkIRQPending1 <= 1;
        end
        end
        else
        else
                sprBkCollision1 <= sprBkCollision1|sproact;
                sprBkCollision1 <= sprBkCollision1|sproact;
end
end
else if (cs_regs && s_sel_i[0] && s_adr_i[7:1]==7'd123) begin
else if (cs_regs && s_sel_i[0] && s_adr_i[9:2]==8'b11110011) begin
        sprBkCollision1 <= 0;
        sprBkCollision1 <= 0;
        sprBkIRQPending1 <= 0;
        sprBkIRQPending1 <= 0;
        sprBkIRQ1 <= 0;
        sprBkIRQ1 <= 0;
end
end
 
 
Line 939... Line 966...
module rtfSpriteRam8 (
module rtfSpriteRam8 (
        clka, adra, doa, cea,
        clka, adra, doa, cea,
        clkb, adrb, dib, dob, ceb, web, rstb
        clkb, adrb, dib, dob, ceb, web, rstb
);
);
input clka;
input clka;
input [10:0] adra;
input [11:0] adra;
output [7:0] doa;
output [7:0] doa;
reg [7:0] doa;
reg [7:0] doa;
input cea;
input cea;
input clkb;
input clkb;
input [8:0] adrb;
input [9:0] adrb;
input [31:0] dib;
input [31:0] dib;
output [31:0] dob;
output [31:0] dob;
input ceb;
input ceb;
input web;
input web;
input rstb;
input rstb;
 
 
reg [31:0] mem [0:511];
reg [31:0] mem [0:1023];
reg [10:0] radra;
reg [11:0] radra;
reg [8:0] radrb;
reg [9:0] radrb;
 
 
always @(posedge clka)  if (cea) radra <= adra;
always @(posedge clka)  if (cea) radra <= adra;
always @(posedge clkb)  if (ceb) radrb <= adrb;
always @(posedge clkb)  if (ceb) radrb <= adrb;
always @(radra)
always @(radra)
        case(radra[1:0])
        case(radra[1:0])
        2'b00:  doa <= mem[radra[10:2]][ 7: 0];
        2'b00:  doa <= mem[radra[11:2]][ 7: 0];
        2'b01:  doa <= mem[radra[10:2]][15: 8];
        2'b01:  doa <= mem[radra[11:2]][15: 8];
        2'b10:  doa <= mem[radra[10:2]][23:16];
        2'b10:  doa <= mem[radra[11:2]][23:16];
        2'b11:  doa <= mem[radra[10:2]][31:24];
        2'b11:  doa <= mem[radra[11:2]][31:24];
        endcase
        endcase
assign dob = rstb ? 32'd0 : mem [radrb];
assign dob = rstb ? 32'd0 : mem [radrb];
always @(posedge clkb)
always @(posedge clkb)
        if (ceb & web) mem[adrb] <= dib;
        if (ceb & web) mem[adrb] <= dib;
 
 
Line 976... Line 1003...
module rtfSpriteRam16 (
module rtfSpriteRam16 (
        clka, adra, doa, cea,
        clka, adra, doa, cea,
        clkb, adrb, dib, dob, ceb, web, rstb
        clkb, adrb, dib, dob, ceb, web, rstb
);
);
input clka;
input clka;
input [9:0] adra;
input [10:0] adra;
output [15:0] doa;
output [15:0] doa;
reg [15:0] doa;
reg [15:0] doa;
input cea;
input cea;
input clkb;
input clkb;
input [8:0] adrb;
input [9:0] adrb;
input [31:0] dib;
input [31:0] dib;
output [31:0] dob;
output [31:0] dob;
input ceb;
input ceb;
input web;
input web;
input rstb;
input rstb;
 
 
reg [31:0] mem [0:511];
reg [31:0] mem [0:1023];
reg [9:0] radra;
reg [10:0] radra;
reg [8:0] radrb;
reg [9:0] radrb;
 
 
always @(posedge clka)  if (cea) radra <= adra;
always @(posedge clka)  if (cea) radra <= adra;
always @(posedge clkb)  if (ceb) radrb <= adrb;
always @(posedge clkb)  if (ceb) radrb <= adrb;
always @(radra)
always @(radra)
        case(radra[1])
        case(radra[1])
        1'b0:   doa <= mem[radra[9:1]][15: 0];
        1'b0:   doa <= mem[radra[10:1]][15: 0];
        1'b1:   doa <= mem[radra[9:1]][31:16];
        1'b1:   doa <= mem[radra[10:1]][31:16];
        endcase
        endcase
assign dob = rstb ? 32'd0 : mem [radrb];
assign dob = rstb ? 32'd0 : mem [radrb];
always @(posedge clkb)
always @(posedge clkb)
        if (ceb & web) mem[adrb] <= dib;
        if (ceb & web) mem[adrb] <= dib;
 
 

powered by: WebSVN 2.1.0

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