некорректный case в active-hdl

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Аватара пользователя
van_de_luxe
Встал на лапы
Сообщения: 103
Зарегистрирован: Вс окт 31, 2010 16:46:10
Откуда: Оттуда

некорректный case в active-hdl

Сообщение van_de_luxe »

использую следующий код

Код: Выделить всё

Generic (   
		N : positive := 8;                                             -- 32bit serial word length is default
		CPOL : std_logic := '0';                                        -- SPI mode selection (mode 0 default)
		CPHA : std_logic := '0';                                        -- CPOL = clock polarity, CPHA = clock phase.
		PREFETCH : positive := 2;                                       -- prefetch lookahead cycles
		SPI_2X_CLK_DIV : positive := 5); 

Код: Выделить всё

case (state_reg) is
			
			when (N+1) =>                                          		-- ýòî ñîñòîÿíèå âêëþ÷àåò SSEL ïðåðåä SCK	this state is to enable SSEL before SCK
				spi_mosi_o <= sh_reg(N-1);                              -- shift out tx bit from the MSb
				ssel_ena_next <= '1';                                   -- tx in progress: will assert SSEL
				sck_ena_next <= '1';                                    -- enable SCK on next cycle (stays off on first SSEL clock cycle)
				di_req_next <= '0';                                     -- prefetch data request: deassert when shifting data
				wr_ack_next <= '0';                                     -- remove write acknowledge for all but the load stages
				state_next <= state_reg - 1;                            -- îáíîâëåíèå ñëåäóþùåãî ñîñòîÿíèÿ êàæäûé èìïóëüñ sck
			
			when (N) =>                                                 -- deassert 'di_rdy' and stretch do_valid
				spi_mosi_o <= sh_reg(N-1);                              -- shift out tx bit from the MSb
				di_req_next <= '0';                                     -- prefetch data request: deassert when shifting data
				sh_next(N-1 downto 1) <= sh_reg(N-2 downto 0);          -- shift inner bits
				sh_next(0) <= rx_bit_reg;                               -- shift in rx bit into LSb
				wr_ack_next <= '0';                                     -- remove write acknowledge for all but the load stages
				state_next <= state_reg - 1;                            -- îáíîâëåíèå ñëåäóþùåãî ñîñòîÿíèÿ êàæäûé èìïóëüñ sck
			
			when (N-1) downto (PREFETCH+3) =>                           -- remove 'do_transfer' and shift bits
			        spi_mosi_o <= sh_reg(N-1);                              -- shift out tx bit from the MSb
				di_req_next <= '0';                                     -- prefetch data request: deassert when shifting data
				do_transfer_next <= '0';                                -- reset 'do_valid' transfer signal
				sh_next(N-1 downto 1) <= sh_reg(N-2 downto 0);          -- shift inner bits
				sh_next(0) <= rx_bit_reg;                               -- shift in rx bit into LSb
				wr_ack_next <= '0';                                     -- remove write acknowledge for all but the load stages
				state_next <= state_reg - 1;                            -- îáíîâëåíèå ñëåäóþùåãî ñîñòîÿíèÿ êàæäûé èìïóëüñ sck
				
				
			when (PREFETCH+2) downto 2 =>                               -- raise prefetch 'di_req_o' signal
				spi_mosi_o <= sh_reg(N-1);                              -- shift out tx bit from the MSb
				di_req_next <= '1';                                     -- request data in advance to allow for pipeline delays
				sh_next(N-1 downto 1) <= sh_reg(N-2 downto 0);          -- shift inner bits
				sh_next(0) <= rx_bit_reg;                               -- shift in rx bit into LSb
				wr_ack_next <= '0';                                     -- remove write acknowledge for all but the load stages
				state_next <= state_reg - 1;                            -- îáíîâëåíèå ñëåäóþùåãî ñîñòîÿíèÿ êàæäûé èìïóëüñ sck
			
			when 1 =>                                                   -- transfer rx data to do_buffer and restart if new data is written
				spi_mosi_o <= sh_reg(N-1);                              -- shift out tx bit from the MSb
				di_req_next <= '1';                                     -- request data in advance to allow for pipeline delays
				do_buffer_next(N-1 downto 1) <= sh_reg(N-2 downto 0);   -- shift rx data directly into rx buffer
				do_buffer_next(0) <= rx_bit_reg;                        -- shift last rx bit into rx buffer
				do_transfer_next <= '1';                                -- signal transfer to do_buffer
				if wren = '1' then                                      -- load tx register if valid data present at di_i
					state_next <= N;                                  	-- next state is top bit of new data
					sh_next <= di_reg;                                  -- load parallel data from di_reg into shifter
					sck_ena_next <= '1';                                -- SCK enabled
					wr_ack_next <= '1';                                 -- acknowledge data in transfer
				else
					sck_ena_next <= '0';                                -- SCK disabled: tx empty, no data to send
					wr_ack_next <= '0';                                 -- remove write acknowledge for all but the load stages
					state_next <= state_reg - 1;                        -- îáíîâëåíèå ñëåäóþùåãî ñîñòîÿíèÿ êàæäûé èìïóëüñ sck
				end if;
			
			when 0 =>                                                   -- idle state: start and end of transmission
				di_req_next <= '1';                                     -- will request data if shifter empty
				sck_ena_next <= '0';                                    -- SCK disabled: tx empty, no data to send
				if wren = '1' then                                      -- load tx register if valid data present at di_i
					spi_mosi_o <= di_reg(N-1);                          -- special case: shift out first tx bit from the MSb (look ahead)
					ssel_ena_next <= '1';                               -- enable interface SSEL
					state_next <= N+1;                                  -- start from idle: let one cycle for SSEL settling
					sh_next <= di_reg;                                  -- load bits from di_reg into shifter
					wr_ack_next <= '1';                                 -- acknowledge data in transfer
				else
					spi_mosi_o <= sh_reg(N-1);                          -- shift out tx bit from the MSb
					ssel_ena_next <= '0';                               -- deassert SSEL: interface is idle
					wr_ack_next <= '0';                                 -- remove write acknowledge for all but the load stages
					state_next <= 0;                                    -- when idle, keep this state
				end if;
			
			when others =>
			state_next <= 0;                                        -- state 0 is safe state
			end case; 
(это ядро SPI с сайта opencores.ogr)

автомат не определяет состояния 6, 7
т.е. state_reg = 7, выполнился соответствующий код и state_reg стал = 6
и второй раз в этот случай автомат не заходит, а кидается в when others. (он думает, что 6 не находится в диапазоне (N-1) downto (PREFETCH+3) )

если изменить
when (N-1) downto (PREFETCH+3)
на
when 7 downto 5
то работает как должен

почему так происходит?
и как бороться?

как бороться в принципе понятно - можно if сделать, но хотелось бы не трогать готовый код, может косяк в Active-Hdl?
Реклама
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»