Difficulty with reading a quad encoder


Recommended Posts

I'm very new to FPGAs and VHDL and have been having some difficulty reading an encoder off of a Papilio 500k. I slightly modified the code ivanjh's that I found here to try to get it to communicate using the more recent changes to the wishbone bus (using the arrays in/out instead of the 10 individual signals) but I am still not confident that it will work as intended.


After the modifications I have this:

library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.numeric_std.all;library board;use board.zpu_config.all;use board.zpupkg.all;use board.zpuinopkg.all;entity zpuino_quadcounter_modified is		generic ( 			COUNTER_BIT_WIDTH : integer := wordSize;			COUNTER_INVALID_BIT_WIDTH : integer := wordSize;			CHANNELS : integer := 1			);		port (					wishbone_in : in std_logic_vector(61 downto 0);			wishbone_out : out std_logic_vector(33 downto 0);	 			-- Counter Input			A, B       : in  std_logic_vector(CHANNELS-1 downto 0)	);end zpuino_quadcounter_modified;     architecture behave of zpuino_quadcounter_modified is--Wishbone signals - Don't touch.  signal  wb_clk_i:    std_logic;                     -- Wishbone clock  signal  wb_rst_i:    std_logic;                     -- Wishbone reset (synchronous)  signal  wb_dat_i:    std_logic_vector(wordSize-1 downto 0); -- Wishbone data input  (32 bits)  signal  wb_adr_i:    std_logic_vector(maxIObit downto minIObit); -- Wishbone address input  (32 bits)  signal  wb_we_i:     std_logic;                     -- Wishbone write enable signal  signal  wb_cyc_i:    std_logic;                     -- Wishbone cycle signal  signal  wb_stb_i:    std_logic;                     -- Wishbone strobe signal    signal  wb_dat_o:    std_logic_vector(wordSize-1 downto 0); -- Wishbone data output (32 bits)  signal  wb_ack_o:    std_logic;                      -- Wishbone acknowledge out signal  signal  wb_inta_o:   std_logic;			type tCounterArray is array (CHANNELS-1 downto 0) of std_logic_vector(COUNTER_BIT_WIDTH-1 downto 0);	type tCounterInvalidArray is array (CHANNELS-1 downto 0) of std_logic_vector(COUNTER_INVALID_BIT_WIDTH-1 downto 0);	signal counter_Int : tCounterArray; --Internal counters	signal counterInvalid_Int: tCounterInvalidArray; --Internal invalid counters	--signal wb_dat_o_Int  : std_logic_vector(wb_dat_o'range);		signal up,down : std_logic_vector(CHANNELS-1 downto 0);	COMPONENT quad_decoder	PORT(		clk : IN std_logic;		reset : IN std_logic;		A : IN std_logic;		B : IN std_logic;          		up : OUT std_logic;		down : OUT std_logic		);	END COMPONENT;	begin-- Unpack the wishbone array into signals so the modules code is not confusing.  wb_clk_i <= wishbone_in(61);  wb_rst_i <= wishbone_in(60);  wb_dat_i <= wishbone_in(59 downto 28);  wb_adr_i <= wishbone_in(27 downto 3);  wb_we_i <= wishbone_in(2);  wb_cyc_i <= wishbone_in(1);  wb_stb_i <= wishbone_in(0);     wishbone_out(33 downto 2) <= wb_dat_o;  wishbone_out(1) <= wb_ack_o;  wishbone_out(0) <= wb_inta_o;-- End unpacking Wishbone signals	wb_ack_o <= wb_cyc_i and wb_stb_i; --Acknowledge any read	channel_inst : for i in 0 to CHANNELS-1 generate		quad_decoder_inst: quad_decoder			port map (				clk   => wb_clk_i,				reset   => wb_rst_i,				A=> A(i),				B => B(i),				up => up(i),				down => down(i)			);		CountProcess: process (wb_clk_i, wb_rst_i)		begin			if wb_rst_i = '1' then				counter_Int(i) <= (others => '0'); 	--			counterInvalid_Int <= (others => '0'); 			elsif rising_edge(wb_clk_i)  then --Clock				if (up(i)='1')  then -- Count Up					counter_Int(i) <= counter_Int(i) + '1';				elsif (down(i)='1') then -- Count Down					counter_Int(i) <= counter_Int(i) - '1';				end if;			end if;		end process;	  	end generate;	LoadToDataOutBus:process(wb_adr_i, counter_Int) --wb_clk_i, wb_rst_i, 	begin		wb_dat_o <= (others=>'0');		for i in 0 to CHANNELS-1 loop			if (wb_adr_i(15 downto 2) = std_logic_vector(to_unsigned(i, wb_adr_i'length)) ) then				wb_dat_o <= counter_Int( i );			end if;		end loop;	end process;end behave;

To test it I hooked up the encoder I'm trying to use to the Papilio and tried using the following sketch on zpuino to read the values from the encoder.

#define input (IO_SLOT (5))void setup() {Serial.begin(9600);}void loop() {Serial.print("Encoder value: ");Serial.println(input);delay(500);}

The serial monitor showed this as constantly returning "Encoder value: 176160768". I know I'm doing something wrong right now but have no idea what I'm doing wrong or how to go about fixing it. Does anyone have any experience with similar problems?



Link to comment
Share on other sites



We talked in the chat room and my recommendation was to narrow down where the problem lies. Is it a problem with the wishbone connection or with reading the hardware. I would hard code a value into the decoder so it is not actually reading the hardware and just make sure you can consistently read that value back. If that works then we can move on to looking at the hardware.



Link to comment
Share on other sites

This is an example of interacting with the wishbone component:

//This is what wishbone slot you are using#define MYBASE IO_SLOT(5)#define MYREG(x) REGISTER(MYBASE,x) void setup() {  // put your setup code here, to run once:  Serial.begin(9600);  //Set our Wishbone registers to a value  MYREG(0) = 0xDEADBEEF;  MYREG(1) = 0xFFFFFFFF;  MYREG(2) = 0xEE;       //8-bit register}void loop() {  // put your main code here, to run repeatedly:     //Read and printout our Wishbone registers  Serial.print("Register0: ");  Serial.println(MYREG(0),HEX);  Serial.print("Register1: ");  Serial.println(MYREG(1),HEX);  Serial.print("Register2: ");  Serial.println(MYREG(2),HEX);  Serial.println("");    delay(3000);}
Link to comment
Share on other sites


This topic is now archived and is closed to further replies.