Clean up block address bit width (and add more code).
authorMalte S. Stretz <mss@apache.org>
Wed, 24 Jun 2009 22:55:35 +0000 (00:55 +0200)
committerMalte S. Stretz <mss@apache.org>
Wed, 24 Jun 2009 22:55:35 +0000 (00:55 +0200)
bos2k9.vhd
bos2k9_globals.vhd
fhw_sd/sd_globals.vhd
fhw_sd/sd_host.vhd
fhw_sd/sd_io_e.vhd
fhw_sd/sd_manager_e.vhd

index ee91008..326550d 100644 (file)
@@ -24,7 +24,7 @@ entity bos2k9 is
     LEDG : out std_logic_vector(8 downto 0);
     
     SD_DAT  : in  std_logic;
-    SD_DAT3 : out std_logic; --CS
+    SD_DAT3 : out std_logic;
     SD_CMD  : out std_logic;
     SD_CLK  : out std_logic);
 end bos2k9;
@@ -35,9 +35,8 @@ architecture board of bos2k9 is
 
   component sd_host is
     generic(
-      clock_interval      : time     := clock_interval_c;
-      clock_divider       : positive := sd_clock_div_c;
-      block_address_width : positive := sd_block_address_width_c);
+      clock_interval : time     := clock_interval_c;
+      clock_divider  : positive := sd_clock_div_c);
     port(
       clk : in  std_logic;
       rst : in  std_logic;
@@ -146,8 +145,8 @@ begin
     
     sd_start_s <= start_btn_s;
   
-    sd_address_s <= byte_sw1_s(sd_block_address_width_c - 1 downto 0);
-    bl_address_s <= '0' & byte_sw2_s;
+    sd_address_s <= zero_block_address_c or byte_sw1_s;
+    bl_address_s <= zero_byte_address_c  or byte_sw2_s;
   
     sd_io : sd_host port map(
       clk => clock_s,
index f14ad1d..3e7658d 100644 (file)
@@ -1,14 +1,19 @@
 library ieee;
 use ieee.std_logic_1164.all;
 
+library fhw_sd;
+use fhw_sd.sd_globals.all;
+
 package bos2k9_globals is
 
   constant clock_interval_c : time   := 20 us;
   constant sd_clock_div_c : positive := 128; -- 390.625 kHz (max 400 kHz); exakt: 125
   
-  constant sd_block_address_width_c : positive := 2;
-  subtype  std_logic_block_address_t is std_logic_vector(sd_block_address_width_c - 1 downto 0);
+  subtype  std_logic_block_address_t is std_logic_block_address_t;
+  constant zero_block_address_c : std_logic_block_address_t := (others => '0');
   
-  subtype  std_logic_byte_address_t is std_logic_vector(8 downto 0);
+  constant byte_address_width_c : positive := 9; -- 512 bytes per block
+  subtype  std_logic_byte_address_t is std_logic_vector(byte_address_width_c - 1 downto 0);
+  constant zero_byte_address_c : std_logic_byte_address_t := (others => '0');
 
 end bos2k9_globals;
index 9fa55a2..6075e59 100644 (file)
@@ -14,7 +14,9 @@ use ieee.numeric_std.all;
 
 package sd_globals is
 
-  subtype  block_address_width_t is integer range 1 to 12;
+  constant block_address_width_c : positive := 23; -- max 4 GiB of 512 B blocks
+  subtype  block_address_width_t is integer range 1 to block_address_width_c;
+  subtype  std_logic_block_address_t is std_logic_vector(block_address_width_c - 1 downto 0);
 
   subtype  std_logic_cmd_t is std_logic_vector(5 downto 0);
   subtype  std_logic_arg_t is std_logic_vector(31 downto 0);
@@ -31,20 +33,22 @@ package sd_globals is
     cmd : std_logic_cmd_t;
     arg : std_logic_arg_t) return std_logic_frame_t;
   
+  constant arg_null_c : std_logic_arg_t := (others => '0');
+  
   constant cmd_do_reset_c : std_logic_cmd_t := to_cmd(63);
   constant arg_do_reset_c : std_logic_arg_t := to_arg(50); -- 1+ ms: 8 SCK (1 byte) @ 400 kHz = 2.5 us * 8 = 20 us
   
-  constant cmd_do_idle_c : std_logic_cmd_t := to_cmd(62);
-  constant arg_do_idle_c : std_logic_arg_t := to_arg(10); -- 75+ SCKs (10 byte)
+  constant cmd_do_start_c : std_logic_cmd_t := to_cmd(62);
+  constant arg_do_start_c : std_logic_arg_t := to_arg(10); -- 75+ SCKs (10 byte)
   
   constant cmd_go_idle_state_c : std_logic_cmd_t := to_cmd(0);
-  constant arg_go_idle_state_c : std_logic_arg_t := to_arg(0);
+  constant arg_go_idle_state_c : std_logic_arg_t := arg_null_c;
   
   constant cmd_set_blocklen_c : std_logic_cmd_t := to_cmd(16);
   constant arg_set_blocklen_c : std_logic_arg_t := to_arg(512);
   
   constant cmd_read_single_block_c : std_logic_cmd_t := to_cmd(17);
-  constant pad_read_single_block_c : std_logic_vector(8 downto 0) := (others => '0');
+  constant pad_read_single_block_c : std_logic_vector(31 - block_address_width_c downto 0) := (others => '0');
   
   constant crc_c : std_logic_crc7_t := "1001010";
 
@@ -61,12 +65,12 @@ package body sd_globals is
   function to_arg(
     number : integer range 0 to 65535) return std_logic_arg_t is
   begin
-    return std_logic_vector(to_unsigned(number, 32));
+    return std_logic_vector(to_unsigned(number, std_logic_arg_t'length));
   end to_arg;
   
   function create_frame(
     cmd : std_logic_cmd_t;
-    arg : std_logic_arg_t) return std_logic_cmd_t is
+    arg : std_logic_arg_t) return std_logic_frame_t is
   begin
     return cmd(std_logic_cmd_t'high) & '1' & cmd & arg & crc_c & '1';
   end create_frame;
index e1e671f..b2ff57e 100644 (file)
@@ -22,9 +22,8 @@ use ieee.numeric_std.all;
 
 entity sd_host is
   generic(
-    clock_interval      : time;
-    clock_divider       : positive; -- TODO: calculate this based on clock_interval
-    block_address_width : block_address_width_t := 12); -- No SDHC, so max is 4096 blocks a 512 byte
+    clock_interval : time;
+    clock_divider  : positive); -- TODO: calculate this based on clock_interval
   port(
     clk : in  std_logic;
     rst : in  std_logic;
@@ -33,7 +32,7 @@ entity sd_host is
     busy  : out std_logic;
     error : out std_logic;
     
-    address : in  std_logic_vector(block_address_width - 1 downto 0);
+    address : in  std_logic_block_address_t;
     start   : in  std_logic;
     rxd     : out std_logic_byte_t;
     shd     : out std_logic;
@@ -49,13 +48,11 @@ entity sd_host is
 architecture rtl of sd_host is
   
   component sd_manager_e is
-    generic(
-      block_address_width : block_address_width_t := block_address_width);
     port(
       clock : in std_logic;
       reset : in std_logic;
     
-      address : in std_logic_vector(block_address_width - 1 downto 0);
+      address : in std_logic_block_address_t;
       start   : in std_logic;
       
       ready : out std_logic;
index b123e3c..8b94248 100644 (file)
@@ -41,21 +41,31 @@ end sd_io_e;
 -----------------------------------------------------------------------
 
 architecture rtl of sd_io_e is
+  signal frame_s : std_logic_frame_t;
+
+  --signal counter_s : 
 begin
   process(clock, reset)
   begin
-    spi_start <= '0';
     if reset = '1' then
+      spi_start <= '0';
+      frame_s   <= (others => '0');
     elsif rising_edge(clock) then
+    
+      spi_start <= '0';
+      
+      frame_s <= create_frame(command, argument);
+    
       case command is
         when cmd_do_reset_c =>
           spi_txd <= (others => '1');
-        when cmd_do_idle_c =>
+          
+        when cmd_do_start_c =>
           null;
         when cmd_set_blocklen_c =>
           null;
         when cmd_read_single_block_c =>
-          null;
+          
         when others =>
           null;
       end case;
index 2d70d65..219d9d9 100644 (file)
@@ -20,13 +20,11 @@ use ieee.std_logic_1164.all;
 use ieee.numeric_std.all;
 
 entity sd_manager_e is
-  generic(
-    block_address_width : block_address_width_t);
   port(
     clock : in std_logic;
     reset : in std_logic;
     
-    address : in std_logic_vector(block_address_width - 1 downto 0);
+    address : in std_logic_block_address_t;
     start   : in std_logic;
     
     ready : out std_logic;
@@ -35,8 +33,9 @@ entity sd_manager_e is
     
     command  : out std_logic_cmd_t;
     argument : out std_logic_arg_t;
-    response : in  std_logic_rsp_t;
-    shifting : in  std_logic);
+    --trigger  : out std_logic;
+    shifting : in  std_logic;
+    response : in  std_logic_rsp_t);
 end sd_manager_e;
 
 -----------------------------------------------------------------------
@@ -61,28 +60,50 @@ architecture rtl of sd_manager_e is
 
 begin
   
-  output : process(curr_state_s, address)
+  sequence : process(clock, reset)
   begin
-    prev_state_s <= curr_state_s;
-    case curr_state_s is
-      when rset_state_c =>
-        command  <= cmd_do_reset_c;
-        argument <= arg_do_reset_c;
-      when strt_state_c =>
-        command  <= cmd_do_idle_c;
-        argument <= arg_do_idle_c;
-      when init_state_c =>
-        command  <= cmd_go_idle_state_c;
-        argument <= arg_go_idle_state_c;
-      when bsiz_state_c =>
-        command  <= cmd_set_blocklen_c;
-        argument <= arg_set_blocklen_c;
-      when read_state_c =>
-        command  <= cmd_read_single_block_c;
-        argument <= to_arg(to_integer(unsigned(address & pad_read_single_block_c)));
-      when others =>
-        prev_state_s <= prev_state_s;
-    end case;
+    if reset = '1' then
+      curr_state_s <= rset_state_c;
+    elsif rising_edge(clock) then
+      case curr_state_s is
+        when rset_state_c => curr_state_s <= strt_state_c;
+        when strt_state_c => curr_state_s <= send_state_c;
+        when init_state_c => curr_state_s <= send_state_c;
+        when bsiz_state_c => curr_state_s <= send_state_c;
+        when read_state_c => curr_state_s <= send_state_c;
+        when send_state_c => curr_state_s <= shft_state_c;
+        when shft_state_c => curr_state_s <= next_state_s;
+        when vrfy_state_c => curr_state_s <= next_state_s;
+        when idle_state_c => curr_state_s <= next_state_s;
+      end case;
+    end if;
+  end process;
+  
+  output : process(clock, reset)
+    variable address_v : std_logic_arg_t;
+  begin
+    if rising_edge(clock) then
+      prev_state_s <= curr_state_s;
+      case curr_state_s is
+        when rset_state_c =>
+          command  <= cmd_do_reset_c;
+          argument <= arg_do_reset_c;
+        when strt_state_c =>
+          command  <= cmd_do_start_c;
+          argument <= arg_do_start_c;
+        when init_state_c =>
+          command  <= cmd_go_idle_state_c;
+          argument <= arg_go_idle_state_c;
+        when bsiz_state_c =>
+          command  <= cmd_set_blocklen_c;
+          argument <= arg_set_blocklen_c;
+        when read_state_c =>
+          command  <= cmd_read_single_block_c;
+          argument <= address & pad_read_single_block_c;
+        when others =>
+          prev_state_s <= prev_state_s;
+      end case;
+    end if;
   end process;
   
   -- verify : process(clock, reset, curr_state_s)
@@ -103,24 +124,7 @@ begin
     -- end if;
   -- end;
   
-  sequence : process(clock, reset, next_state_s)
-  begin
-    if reset = '1' then
-      curr_state_s <= rset_state_c;
-    elsif rising_edge(clock) then
-      case curr_state_s is
-        when rset_state_c => curr_state_s <= strt_state_c;
-        when strt_state_c => curr_state_s <= send_state_c;
-        when init_state_c => curr_state_s <= send_state_c;
-        when bsiz_state_c => curr_state_s <= send_state_c;
-        when read_state_c => curr_state_s <= send_state_c;
-        when send_state_c => curr_state_s <= shft_state_c;
-        when shft_state_c => curr_state_s <= next_state_s;
-        when vrfy_state_c => curr_state_s <= next_state_s;
-        when idle_state_c => curr_state_s <= next_state_s;
-      end case;
-    end if;
-  end process;
+  
   
   -- sequence : process(clock, reset, curr_s, next_s)
   -- begin