Improved register access with system to support Wishbone easier and reduce CDC issues.
authorTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Thu, 6 Aug 2020 09:22:49 +0000 (10:22 +0100)
committerTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Thu, 6 Aug 2020 09:22:49 +0000 (10:22 +0100)
src/NvmeStorageUnit.vhd
src/RegAccessClockConvertor.vhd

index 2c3f388792e060d26084954c96da1da848f1f27c..1d1a1223f101bfc59a15fedad40c4408fa0a229e 100644 (file)
@@ -71,6 +71,7 @@ port (
 
        -- Control and status interface
        regWrite        : in std_logic;                         --! Enable write to register
+       regRead         : in std_logic;                         --! Enable read from register
        regAddress      : in unsigned(5 downto 0);              --! Register to read/write
        regDataIn       : in std_logic_vector(31 downto 0);     --! Register write data
        regDataOut      : out std_logic_vector(31 downto 0);    --! Register contents
@@ -110,6 +111,7 @@ port (
        reset1          : in std_logic;                         --! The active high reset line
        
        regWrite1       : in std_logic;                         --! Enable write to register
+       regRead1        : in std_logic;                         --! Enable read from register
        regAddress1     : in unsigned(5 downto 0);              --! Register to read/write
        regDataIn1      : in std_logic_vector(31 downto 0);     --! Register write data
        regDataOut1     : out std_logic_vector(31 downto 0);    --! Register contents
@@ -117,7 +119,8 @@ port (
        clk2            : in std_logic;                         --! The interface clock line
        reset2          : in std_logic;                         --! The active high reset line
 
-       regWrite2       : out std_logic;                                --! Enable write to register
+       regWrite2       : out std_logic;                        --! Enable write to register
+       regRead2        : out std_logic;                        --! Enable read from register
        regAddress2     : out unsigned(5 downto 0);             --! Register to read/write
        regDataIn2      : out std_logic_vector(31 downto 0);    --! Register write data
        regDataOut2     : in std_logic_vector(31 downto 0)      --! Register contents
@@ -433,6 +436,8 @@ type StateType                      is (STATE_START, STATE_IDLE, STATE_WRITE, STATE_READ1, STATE_RE
 signal state                   : StateType := STATE_START;
 
 signal regWrite1               : std_logic;                            --! Enable write to register
+signal regRead1                        : std_logic;                            --! Enable read from register
+signal regReadActive           : std_logic;                            --! Register read in progress
 signal regAddress1             : unsigned(5 downto 0) := (others => '0');      --! Register to read/write
 signal regDataIn1              : std_logic_vector(31 downto 0);        --! Register write data
 signal regDataOut0             : std_logic_vector(31 downto 0);        --! Register contents
@@ -480,6 +485,7 @@ begin
                reset1          => reset,
 
                regWrite1       => regWrite,
+               regRead1        => regRead,
                regAddress1     => regAddress,
                regDataIn1      => regDataIn,
                regDataOut1     => regDataOut0,
@@ -488,6 +494,7 @@ begin
                reset2          => nvme_user_reset,
 
                regWrite2       => regWrite1,
+               regRead2        => regRead1,
                regAddress2     => regAddress1,
                regDataIn2      => regDataIn1,
                regDataOut2     => regDataOut1
@@ -543,15 +550,6 @@ begin
        dataEnabledOut <= dataEnabledOut1;
 
        -- Register access
-       regDataOut1 <= reg_id when(regAddress1 = 0) else
-                       reg_control when(regAddress1 = 1) else
-                       reg_status when(regAddress1 = 2) else
-                       reg_totalBlocks when(regAddress1 = 3) else
-                       reg_blocksLost when(regAddress1 = 4) else
-                       reg_nvmeWrite when((regAddress1 >= 16) and (regAddress1 < 32)) else
-                       reg_nvmeRead when((regAddress1 >= 32) and (regAddress1 < 48)) else
-                       x"FFFFFFFF";
-
        regDataOut <= zeros(31) & reset_local_active when(reset_local_active = '1') else regDataOut0;
        nvmeWrite_write <= regWrite1 when((regAddress1 >= 16) and (regAddress1 < 32)) else '0';
        nvmeRead_write <= regWrite1 when((regAddress1 >= 32) and (regAddress1 < 48)) else '0';
@@ -607,7 +605,30 @@ begin
                if(rising_edge(nvme_user_clk)) then
                        if(nvme_user_reset = '1') then
                                reg_control     <= (others => '0');
+                               regReadActive   <= '0';
                        else
+                               if((regRead1 = '1') and (regReadActive = '0')) then
+                                       -- Register read
+                                       if(regAddress1 = 0) then
+                                               regDataOut1 <= reg_id;
+                                       elsif(regAddress1 = 1) then
+                                               regDataOut1 <= reg_control;
+                                       elsif(regAddress1 = 2) then
+                                               regDataOut1 <= reg_status;
+                                       elsif(regAddress1 = 3) then
+                                               regDataOut1 <= reg_totalBlocks;
+                                       elsif(regAddress1 = 4) then
+                                               regDataOut1 <= reg_blocksLost;
+                                       elsif((regAddress1 >= 16) and (regAddress1 < 32)) then
+                                               regDataOut1 <= reg_nvmeWrite;
+                                       elsif((regAddress1 >= 32) and (regAddress1 < 48)) then
+                                               regDataOut1 <= reg_nvmeRead;
+                                       else
+                                               regDataOut1 <= x"FFFFFFFF";
+                                       end if;
+                               end if;
+                               regReadActive <= regRead1;
+                               
                                if(regWrite1 = '1') then
                                        if(regAddress1 = 1) then
                                                reg_control <= regDataIn1;
index 2d5f401813f43830d2538e612bd3000c3bded93b..12eca6afabad9189d3a577b4f1376a59655a73b7 100644 (file)
@@ -50,6 +50,7 @@ port (
        reset1          : in std_logic;                         --! The active high reset line
        
        regWrite1       : in std_logic;                         --! Enable write to register
+       regRead1        : in std_logic;                         --! Enable read from register
        regAddress1     : in unsigned(5 downto 0);              --! Register to read/write
        regDataIn1      : in std_logic_vector(31 downto 0);     --! Register write data
        regDataOut1     : out std_logic_vector(31 downto 0);    --! Register contents
@@ -58,6 +59,7 @@ port (
        reset2          : in std_logic;                         --! The active high reset line
 
        regWrite2       : out std_logic;                        --! Enable write to register
+       regRead2        : out std_logic;                                --! Enable read from register
        regAddress2     : out unsigned(5 downto 0);             --! Register to read/write
        regDataIn2      : out std_logic_vector(31 downto 0);    --! Register write data
        regDataOut2     : in std_logic_vector(31 downto 0)      --! Register contents
@@ -67,7 +69,7 @@ end;
 architecture Behavioral of RegAccessClockConvertor is
 
 constant TCQ           : time := 1 ns;
-constant SigSendWidth  : integer := 1 + regAddress1'length + regDataIn1'length;
+constant SigSendWidth  : integer := 2 + regAddress1'length + regDataIn1'length;
 constant SigRecvWidth  : integer := 32;
 
 subtype SigSendType    is std_logic_vector(SigSendWidth-1 downto 0);
@@ -96,7 +98,8 @@ attribute async_reg   of recvCdcReg2 : signal is "true";
 
 begin
        --! The send process
-       regWrite2       <= sendCdcReg2(38);
+       regWrite2       <= sendCdcReg2(39);
+       regRead2        <= sendCdcReg2(38);
        regAddress2     <= unsigned(sendCdcReg2(37 downto 32));
        regDataIn2      <= sendCdcReg2(31 downto 0);
 
@@ -109,7 +112,7 @@ begin
                                recvCdcReg0     <= (others => '0');
                        else
                                sendCdcReg2     <= sendCdcReg1;
-                               sendCdcReg1     <= regWrite1 & to_stl(regAddress1) & regDataIn1;
+                               sendCdcReg1     <= regWrite1 & regRead1 & to_stl(regAddress1) & regDataIn1;
                                
                                recvCdcReg0     <= regDataOut2;
                        end if;