Peripherals now have internal latches.
authorJoshua Wise <joshua@rebirth.joshuawise.com>
Tue, 6 May 2008 10:29:22 +0000 (06:29 -0400)
committerJoshua Wise <joshua@rebirth.joshuawise.com>
Tue, 6 May 2008 10:29:22 +0000 (06:29 -0400)
Interrupt.v
LCDC.v
Sound1.v
Sound2.v
Soundcore.v
System.v
Timer.v
Uart.v

index fcc396b..2686146 100644 (file)
@@ -19,10 +19,13 @@ module Interrupt(
        reg [7:0] imask = 16'hFFFF;
        reg [7:0] ihold = 8'b0;
        wire [7:0] imasked = ihold & imask;
+       
+       reg rdlatch = 0;
+       reg [15:0] addrlatch = 0;
 
-       assign data = rd ?
-                        (addr == `ADDR_IF) ? ihold :
-                        (addr == `ADDR_IE) ? imask :
+       assign data = rdlatch ?
+                        (addrlatch == `ADDR_IF) ? ihold :
+                        (addrlatch == `ADDR_IE) ? imask :
                         8'bzzzzzzzz :
                      8'bzzzzzzzz;
 
@@ -45,6 +48,8 @@ module Interrupt(
                end
                else
                        ihold <= ihold | iflag;
+               rdlatch <= rd;
+               addrlatch <= addr;
        end
 
 endmodule
diff --git a/LCDC.v b/LCDC.v
index a198c45..add6893 100644 (file)
--- a/LCDC.v
+++ b/LCDC.v
@@ -21,6 +21,10 @@ module LCDC(
        output wire lcdclk, lcdvs, lcdhs,
        output reg [2:0] lcdr, lcdg, output reg [1:0] lcdb);
        
+       /***** Bus latches *****/
+       reg rdlatch = 0;
+       reg [15:0] addrlatch = 0;
+       
        /***** Needed prototypes *****/
        wire [1:0] pixdata;
        
@@ -172,26 +176,28 @@ module LCDC(
        end
   
        /***** Bus interface *****/
-       assign data = rd ?
-                       ((addr == `ADDR_LCDC) ? rLCDC :
-                        (addr == `ADDR_STAT) ? {rSTAT[7:3], (rLYC == posy) ? 1'b1 : 1'b0, mode} :
-                        (addr == `ADDR_SCY) ? rSCY :
-                        (addr == `ADDR_SCX) ? rSCX :
-                        (addr == `ADDR_LY) ? posy :
-                        (addr == `ADDR_LYC) ? rLYC :
-                        (addr == `ADDR_BGP) ? rBGP :
-                        (addr == `ADDR_OBP0) ? rOBP0 :
-                        (addr == `ADDR_OBP1) ? rOBP1 :
-                        (addr == `ADDR_WY) ? rWY :
-                        (addr == `ADDR_WX) ? rWX :
-                        (decode_tiledata && addr[0]) ? tilehigh :
-                        (decode_tiledata && ~addr[0]) ? tilelow :
+       assign data = rdlatch ?
+                       ((addrlatch == `ADDR_LCDC) ? rLCDC :
+                        (addrlatch == `ADDR_STAT) ? {rSTAT[7:3], (rLYC == posy) ? 1'b1 : 1'b0, mode} :
+                        (addrlatch == `ADDR_SCY) ? rSCY :
+                        (addrlatch == `ADDR_SCX) ? rSCX :
+                        (addrlatch == `ADDR_LY) ? posy :
+                        (addrlatch == `ADDR_LYC) ? rLYC :
+                        (addrlatch == `ADDR_BGP) ? rBGP :
+                        (addrlatch == `ADDR_OBP0) ? rOBP0 :
+                        (addrlatch == `ADDR_OBP1) ? rOBP1 :
+                        (addrlatch == `ADDR_WY) ? rWY :
+                        (addrlatch == `ADDR_WX) ? rWX :
+                        (decode_tiledata && addrlatch[0]) ? tilehigh :
+                        (decode_tiledata && ~addrlatch[0]) ? tilelow :
                         (decode_bgmap1) ? tileno :
                         8'bzzzzzzzz) :
                8'bzzzzzzzz;
   
        always @(posedge clk)
        begin
+               rdlatch <= rd;
+               addrlatch <= addr;
                if (wr)
                        case (addr)
                        `ADDR_LCDC:     rLCDC <= data;
index 21b1dec..ca97b17 100644 (file)
--- a/Sound1.v
+++ b/Sound1.v
@@ -23,18 +23,23 @@ module Sound1(
        reg [3:0] delta = 4'b1111;
        reg toggle = 0;
        reg [3:0] snd_out = 0;
+       
+       reg rdlatch;
+       reg [15:0] addrlatch;
 
        assign snd_data = en ? snd_out : 0;
 
-       assign data = rd ?
-                        addr == `ADDR_NR10 ? nr10 :
-                        addr == `ADDR_NR11 ? nr11 :
-                        addr == `ADDR_NR12 ? nr12 :
-                        addr == `ADDR_NR13 ? nr13 :
-                        addr == `ADDR_NR14 ? nr14 : 8'bzzzzzzzz
+       assign data = rdlatch ?
+                        addrlatch == `ADDR_NR10 ? nr10 :
+                        addrlatch == `ADDR_NR11 ? nr11 :
+                        addrlatch == `ADDR_NR12 ? nr12 :
+                        addrlatch == `ADDR_NR13 ? nr13 :
+                        addrlatch == `ADDR_NR14 ? nr14 : 8'bzzzzzzzz
                      : 8'bzzzzzzzz;
 
        always @ (posedge core_clk) begin
+               rdlatch <= rd;
+               addrlatch <= addr;
                if(en && wr) begin
                        case(addr)
                        `ADDR_NR10: nr10 <= data;
index cf8e83a..ef38263 100644 (file)
--- a/Sound2.v
+++ b/Sound2.v
@@ -24,15 +24,20 @@ module Sound2(
        reg [3:0] snd_out = 0;
 
        assign snd_data = en ? snd_out : 0;
+       
+       reg rdlatch;
+       reg [15:0] addrlatch;
 
-       assign data = rd ?
-                        addr == `ADDR_NR21 ? nr21 :
-                        addr == `ADDR_NR22 ? nr22 :
-                        addr == `ADDR_NR23 ? nr23 :
-                        addr == `ADDR_NR24 ? nr24 : 8'bzzzzzzzz
+       assign data = rdlatch ?
+                        addrlatch == `ADDR_NR21 ? nr21 :
+                        addrlatch == `ADDR_NR22 ? nr22 :
+                        addrlatch == `ADDR_NR23 ? nr23 :
+                        addrlatch == `ADDR_NR24 ? nr24 : 8'bzzzzzzzz
                      : 8'bzzzzzzzz;
 
        always @ (posedge core_clk) begin
+               rdlatch <= rd;
+               addrlatch <= addr;
                if(en && wr) begin
                        case(addr)
                        `ADDR_NR21: nr21 <= data;
index 626001d..70c4db1 100644 (file)
@@ -29,14 +29,19 @@ module Soundcore(
                (nr51[7] ? sndout4 : 4'b0);
        assign sndout3 = 0;
        assign sndout4 = 0;
-
-       assign data = rd ?
-                        addr == `ADDR_NR50 ? nr50 :
-                        addr == `ADDR_NR51 ? nr51 :
-                        addr == `ADDR_NR52 ? nr52 : 8'bzzzzzzzz
+       
+       reg rdlatch;
+       reg [15:0] addrlatch;
+       
+       assign data = rdlatch ?
+                        addrlatch == `ADDR_NR50 ? nr50 :
+                        addrlatch == `ADDR_NR51 ? nr51 :
+                        addrlatch == `ADDR_NR52 ? nr52 : 8'bzzzzzzzz
                      : 8'bzzzzzzzz;
 
        always @ (posedge core_clk) begin
+               rdlatch <= rd;
+               addrlatch <= addr;
                if(wr) begin
                        case(addr)
                        `ADDR_NR50: nr50 <= data;
index 4d0ddbb..ebc9be4 100644 (file)
--- a/System.v
+++ b/System.v
@@ -6,6 +6,7 @@ module ROM(
        input clk,
        input wr, rd);
 
+       reg rdlatch = 0;
        reg [7:0] odata;
 
        // synthesis attribute ram_style of rom is block
@@ -13,9 +14,11 @@ module ROM(
        initial $readmemh("rom.hex", rom);
 
        wire decode = address[15:13] == 0;
-       always @(posedge clk)
+       always @(posedge clk) begin
+               rdlatch <= rd && decode;
                odata <= rom[address[10:0]];
-       assign data = (rd && decode) ? odata : 8'bzzzzzzzz;
+       end
+       assign data = rdlatch ? odata : 8'bzzzzzzzz;
 endmodule
 
 module BootstrapROM(
@@ -24,12 +27,15 @@ module BootstrapROM(
        input clk,
        input wr, rd);
 
+       reg rdlatch = 0;
        reg [7:0] brom [255:0];
        initial $readmemh("bootstrap.hex", brom);
 
        wire decode = address[15:8] == 0;
        wire [7:0] odata = brom[address[7:0]];
-       assign data = (rd && decode) ? odata : 8'bzzzzzzzz;
+       always @(posedge clk)
+               rdlatch <= rd && decode;
+       assign data = rdlatch ? odata : 8'bzzzzzzzz;
 endmodule
 
 module MiniRAM(
@@ -41,13 +47,15 @@ module MiniRAM(
        reg [7:0] ram [127:0];
        
        wire decode = (address >= 16'hFF80) && (address <= 16'hFFFE);
+       reg rdlatch = 0;
        reg [7:0] odata;
-       assign data = (rd && decode) ? odata : 8'bzzzzzzzz;
+       assign data = rdlatch ? odata : 8'bzzzzzzzz;
        
        always @(posedge clk)
        begin
-               if (decode)     // This has to go this way. The only way XST knows how to do
-               begin                           // block ram is chip select, write enable, and always
+               rdlatch <= rd && decode;
+               if (decode)             // This has to go this way. The only way XST knows how to do
+               begin                   // block ram is chip select, write enable, and always
                        if (wr)         // reading. "else if rd" does not cut it ...
                                ram[address[6:0]] <= data;
                        odata <= ram[address[6:0]];
@@ -69,6 +77,10 @@ module CellularRAM(
        parameter ADDR_PROGADDRL = 16'hFF62;
        parameter ADDR_PROGDATA = 16'hFF63;
        
+       reg rdlatch = 0, wrlatch = 0;
+       reg [15:0] addrlatch = 0;
+       reg [7:0] datalatch = 0;
+       
        reg [7:0] progaddrh, progaddrm, progaddrl;
        
        assign cr_nADV = 0;     /* Addresses are always valid! :D */
@@ -78,30 +90,35 @@ module CellularRAM(
        assign cr_CRE = 0;      /* Data writes, not config */
        assign cr_CLK = 0;      /* Clock? I think not! */
        
-       wire decode = (address[15:14] == 2'b00) /* extrom */ || (address[15:13] == 3'b101) /* extram */ || (address == ADDR_PROGDATA);
+       wire decode = (addrlatch[15:14] == 2'b00) /* extrom */ || (addrlatch[15:13] == 3'b101) /* extram */ || (addrlatch == ADDR_PROGDATA);
        
-       assign cr_nOE = decode ? ~rd : 1;
-       assign cr_nWE = decode ? ~wr : 1;
+       assign cr_nOE = decode ? ~rdlatch : 1;
+       assign cr_nWE = decode ? ~wrlatch : 1;
        
-       assign cr_DQ = (~cr_nOE) ? 16'bzzzzzzzzzzzzzzzz : {8'b0, data};
-       assign cr_A = (address[15:14] == 2'b00) ? /* extrom */ {9'b0,address[13:0]} :
-                       (address[15:13] == 3'b101) ? {1'b1, 9'b0, address[12:0]} :
-                       (address == ADDR_PROGDATA) ? {progaddrh[6:0], progaddrm[7:0], progaddrl[7:0]} :
+       assign cr_DQ = (~cr_nOE) ? 16'bzzzzzzzzzzzzzzzz : {8'b0, datalatch};
+       assign cr_A = (addrlatch[15:14] == 2'b00) ? /* extrom */ {9'b0,addrlatch[13:0]} :
+                       (addrlatch[15:13] == 3'b101) ? {1'b1, 9'b0, addrlatch[12:0]} :
+                       (addrlatch == ADDR_PROGDATA) ? {progaddrh[6:0], progaddrm[7:0], progaddrl[7:0]} :
                        23'b0;
        
        reg [7:0] regbuf;
        
-       always @(posedge clk)
+       always @(posedge clk) begin
                case (address)
                ADDR_PROGADDRH: if (wr) progaddrh <= data;
                ADDR_PROGADDRM: if (wr) progaddrm <= data;
                ADDR_PROGADDRL: if (wr) progaddrl <= data;
                endcase
+               rdlatch <= rd;
+               wrlatch <= wr;
+               addrlatch <= address;
+               datalatch <= data;
+       end
        
-       assign data = (rd && decode) ?
-                               (address == ADDR_PROGADDRH) ? progaddrh :
-                               (address == ADDR_PROGADDRM) ? progaddrm :
-                               (address == ADDR_PROGADDRL) ? progaddrl :
+       assign data = (rdlatch && decode) ?
+                               (addrlatch == ADDR_PROGADDRH) ? progaddrh :
+                               (addrlatch == ADDR_PROGADDRM) ? progaddrm :
+                               (addrlatch == ADDR_PROGADDRL) ? progaddrl :
                                cr_DQ
                        : 8'bzzzzzzzz;
 endmodule
@@ -117,10 +134,12 @@ module InternalRAM(
        
        wire decode = (address >= 16'hC000) && (address <= 16'hFDFF);   /* This includes echo RAM. */
        reg [7:0] odata;
-       assign data = (rd && decode) ? odata : 8'bzzzzzzzz;
+       reg rdlatch = 0;
+       assign data = rdlatch ? odata : 8'bzzzzzzzz;
        
        always @(posedge clk)
        begin
+               rdlatch <= rd && decode;
                if (decode)             // This has to go this way. The only way XST knows how to do
                begin                   // block ram is chip select, write enable, and always
                        if (wr)         // reading. "else if rd" does not cut it ...
@@ -140,10 +159,12 @@ module Switches(
        
        wire decode = address == 16'hFF51;
        reg [7:0] odata;
-       assign data = (rd && decode) ? odata : 8'bzzzzzzzz;
+       reg rdlatch = 0;
+       assign data = rdlatch ? odata : 8'bzzzzzzzz;
        
        always @(posedge clk)
        begin
+               rdlatch <= rd && decode;
                if (decode && rd)
                        odata <= switches;
                else if (decode && wr)
diff --git a/Timer.v b/Timer.v
index e46b38b..facf20f 100644 (file)
--- a/Timer.v
+++ b/Timer.v
@@ -11,15 +11,17 @@ module Timer(
        inout [7:0] data,
        output reg irq = 0);
 
+       reg rdlatch = 0;
+       reg [15:0] addrlatch = 0;
        reg [7:0] tima = 0, tma = 0, tac = 0, div = 0;
        reg ovf = 0;
        reg [9:0] clkdv = 0;
 
-       wire is_tima = addr == `ADDR_TIMA;
-       wire is_tma  = addr == `ADDR_TMA;
-       wire is_tac  = addr == `ADDR_TAC;
+       wire is_tima = addrlatch == `ADDR_TIMA;
+       wire is_tma  = addrlatch == `ADDR_TMA;
+       wire is_tac  = addrlatch == `ADDR_TAC;
 
-       assign data = rd ?
+       assign data = rdlatch ?
                         is_tima ? tima :
                         is_tma ? tma :
                         is_tac ? tac :
@@ -35,6 +37,9 @@ module Timer(
 
        always @ (posedge clk) 
        begin
+               rdlatch <= rd;
+               addrlatch <= addr;
+               
                if(wr) begin
                        case(addr)
                        `ADDR_DIV: div <= 8'b0;
diff --git a/Uart.v b/Uart.v
index f9d71f4..07f996a 100644 (file)
--- a/Uart.v
+++ b/Uart.v
@@ -10,11 +10,12 @@ module UART(
        input [15:0] addr,
        inout [7:0] data,
        output reg serial = 1);
-       
+
+       reg rdlatch = 0;
        wire decode = (addr == `MMAP_ADDR);
        
        wire [7:0] odata;
-       assign data = (rd && decode) ? odata : 8'bzzzzzzzz;
+       assign data = rdlatch ? odata : 8'bzzzzzzzz;
 
        reg [7:0] data_stor = 0;
        reg [15:0] clkdiv = 0;
@@ -27,6 +28,7 @@ module UART(
 
        always @ (posedge clk)
        begin
+               rdlatch <= rd && decode;
                /* deal with diqing */
                if(newdata) begin
                        data_stor <= data;
This page took 0.099787 seconds and 4 git commands to generate.