Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

bit counter not counting correctly

Status
Not open for further replies.

Kgonz

Newbie level 5
Newbie level 5
Joined
Mar 9, 2023
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
221
Hello all I am a new firmware engineer trying to get an spi transaction to occur for this module that i found by Digi key however my bit counter signal although its supposed to start at 1 or (0000000000000001) it starts at 2 (0000000000000010) I've been trying to figure out why it starts at 2 instead of 1 and never continues counting past 2 but am not having much luck. I've posted my code below and my waveforms. any help is appreciated thanks

[LIST=1] [*]-------------------------------------------------------------------------------- [*]-- [*]-- FileName: spi_slave.vhd [*]-- Dependencies: none [*]-- Design Software: Quartus Prime Version 17.0.0 Build 595 SJ Lite Edition [*]-- [*]-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY [*]-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT [*]-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A [*]-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY [*]-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL [*]-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF [*]-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS [*]-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), [*]-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. [*]-- [*]-- Version History [*]-- Version 1.0 7/5/2012 Scott Larson [*]-- Initial Public Release [*]-- Version 1.1 11/27/2012 Scott Larson [*]-- Added an asynchronous active low reset [*]-- Version 1.2 5/7/2019 Scott Larson [*]-- Modified architecture slightly to make it synthesizable with more tools [*]-- [*]-------------------------------------------------------------------------------- [*] [*]LIBRARY ieee; [*]USE ieee.std_logic_1164.all; [*]USE ieee.std_logic_arith.all; [*] [*]ENTITY spi_slave IS [*] GENERIC( [*] cpol : STD_LOGIC := '0'; --spi clock polarity mode [*] cpha : STD_LOGIC := '0'; --spi clock phase mode [*] d_width : INTEGER := 8); --data width in bits [*] PORT( [*] sclk : IN STD_LOGIC; --spi clk from master [*] reset_n : IN STD_LOGIC; --active low reset [*] ss_n : IN STD_LOGIC; --active low slave select [*] mosi : IN STD_LOGIC; --master out, slave in [*] rx_req : IN STD_LOGIC; --'1' while busy = '0' moves data to the rx_data output [*] st_load_en : IN STD_LOGIC; --asynchronous load enable [*] st_load_trdy : IN STD_LOGIC; --asynchronous trdy load input [*] st_load_rrdy : IN STD_LOGIC; --asynchronous rrdy load input [*] st_load_roe : IN STD_LOGIC; --asynchronous roe load input [*] tx_load_en : IN STD_LOGIC; --asynchronous transmit buffer load enable [*] tx_load_data : IN STD_LOGIC_VECTOR(d_width-1 DOWNTO 0); --asynchronous tx data to load [*] trdy : BUFFER STD_LOGIC := '0'; --transmit ready bit [*] rrdy : BUFFER STD_LOGIC := '0'; --receive ready bit [*] roe : BUFFER STD_LOGIC := '0'; --receive overrun error bit [*] rx_data : OUT STD_LOGIC_VECTOR(d_width-1 DOWNTO 0) := (OTHERS => '0'); --receive register output to logic [*] busy : OUT STD_LOGIC := '0'; --busy signal to logic ('1' during transaction) [*] miso : OUT STD_LOGIC := 'Z'); --master in, slave out [*]END spi_slave; [*] [*]ARCHITECTURE logic OF spi_slave IS [*] SIGNAL mode : STD_LOGIC; --groups modes by clock polarity relation to data [*] SIGNAL clk : STD_LOGIC; --clock [*] SIGNAL bit_cnt : STD_LOGIC_VECTOR(d_width+8 DOWNTO 0); --'1' for active transaction bit [*] SIGNAL wr_add : STD_LOGIC; --address of register to write ('0' = receive, '1' = status) [*] SIGNAL rd_add : STD_LOGIC; --address of register to read ('0' = transmit, '1' = status) [*] SIGNAL rx_buf : STD_LOGIC_VECTOR(d_width-1 DOWNTO 0) := (OTHERS => '0'); --receiver buffer [*] SIGNAL tx_buf : STD_LOGIC_VECTOR(d_width-1 DOWNTO 0) := (OTHERS => '0'); --transmit buffer [*]BEGIN [*] busy <= NOT ss_n; --high during transactions [*] [*] --adjust clock so writes are on rising edge and reads on falling edge [*] mode <= cpol XOR cpha; --'1' for modes that write on rising edge [*] WITH mode SELECT [*] clk <= sclk WHEN '1', [*] NOT sclk WHEN OTHERS; [*] [*] --keep track of miso/mosi bit counts for data alignmnet [*] PROCESS(ss_n, clk) [*] BEGIN [*] IF(ss_n = '1' OR reset_n = '0') THEN --this slave is not selected or being reset [*] bit_cnt <= (conv_integer(NOT cpha) => '1', OTHERS => '0'); --reset miso/mosi bit count [*] ELSE --this slave is selected [*] IF(rising_edge(clk)) THEN --new bit on miso/mosi [*] bit_cnt <= bit_cnt(d_width+8-1 DOWNTO 0) & '0'; --shift active bit indicator [*] END IF; [*] END IF; [*] END PROCESS; [*] [*] PROCESS(ss_n, clk, st_load_en, tx_load_en, rx_req) [*] BEGIN [*] [*] --write address register ('0' for receive, '1' for status) [*] IF(bit_cnt(1) = '1' AND falling_edge(clk)) THEN [*] wr_add <= mosi; [*] END IF; [*] [*] --read address register ('0' for transmit, '1' for status) [*] IF(bit_cnt(2) = '1' AND falling_edge(clk)) THEN [*] rd_add <= mosi; [*] END IF; [*] [*] --trdy register [*] IF((ss_n = '1' AND st_load_en = '1' AND st_load_trdy = '0') OR reset_n = '0') THEN [*] trdy <= '0'; --cleared by user logic or reset [*] ELSIF(ss_n = '1' AND ((st_load_en = '1' AND st_load_trdy = '1') OR tx_load_en = '1')) THEN [*] trdy <= '1'; --set when tx buffer written or set by user logic [*] ELSIF(falling_edge(clk)) THEN [*] IF(wr_add = '1' AND bit_cnt(9) = '1') THEN [*] trdy <= mosi; --new value written over spi bus [*] ELSIF(rd_add = '0' AND bit_cnt(d_width+8) = '1') THEN [*] trdy <= '0'; --clear when transmit buffer read [*] END IF; [*] END IF; [*] [*] --rrdy register [*] IF((ss_n = '1' AND ((st_load_en = '1' AND st_load_rrdy = '0') OR rx_req = '1')) OR reset_n = '0') THEN [*] rrdy <= '0'; --cleared by user logic or rx_data has been requested or reset [*] ELSIF(ss_n = '1' AND st_load_en = '1' AND st_load_rrdy = '1') THEN [*] rrdy <= '1'; --set when set by user logic [*] ELSIF(falling_edge(clk)) THEN [*] IF(wr_add = '1' AND bit_cnt(10) = '1') THEN [*] rrdy <= mosi; --new value written over spi bus [*] ELSIF(wr_add = '0' AND bit_cnt(d_width+8) = '1') THEN [*] rrdy <= '1'; --set when new data received [*] END IF; [*] END IF; [*] [*] --roe register [*] IF((ss_n = '1' AND st_load_en = '1' AND st_load_roe = '0') OR reset_n = '0') THEN [*] roe <= '0'; --cleared by user logic or reset [*] ELSIF(ss_n = '1' AND st_load_en = '1' AND st_load_roe = '1') THEN [*] roe <= '1'; --set by user logic [*] ELSIF(falling_edge(clk)) THEN [*] IF(rrdy = '1' AND wr_add = '0' AND bit_cnt(d_width+8) = '1') THEN [*] roe <= '1'; --set by actual overrun [*] ELSIF(wr_add = '1' AND bit_cnt(11) = '1') THEN [*] roe <= mosi; --new value written by spi bus [*] END IF; [*] END IF; [*] [*] --receive registers [*] --write to the receive register from master [*] IF(reset_n = '0') THEN [*] rx_buf <= (OTHERS => '0'); [*] ELSE [*] FOR i IN 0 TO d_width-1 LOOP [*] IF(wr_add = '0' AND bit_cnt(i+9) = '1' AND falling_edge(clk)) THEN [*] rx_buf(d_width-1-i) <= mosi; [*] END IF; [*] END LOOP; [*] END IF; [*] --fulfill user logic request for receive data [*] IF(reset_n = '0') THEN [*] rx_data <= (OTHERS => '0'); [*] ELSIF(ss_n = '1' AND rx_req = '1') THEN [*] rx_data <= rx_buf; [*] END IF; [*] [*] --transmit registers [*] IF(reset_n = '0') THEN [*] tx_buf <= (OTHERS => '0'); [*] ELSIF(ss_n = '1' AND tx_load_en = '1') THEN --load transmit register from user logic [*] tx_buf <= tx_load_data; [*] ELSIF(rd_add = '0' AND bit_cnt(7 DOWNTO 0) = "00000000" AND bit_cnt(d_width+8) = '0' AND rising_edge(clk)) THEN [*] tx_buf(d_width-1 DOWNTO 0) <= tx_buf(d_width-2 DOWNTO 0) & tx_buf(d_width-1); --shift through tx data [*] END IF; [*] [*] --miso output register [*] IF(ss_n = '1' OR reset_n = '0') THEN --no transaction occuring or reset [*] miso <= 'Z'; [*] ELSIF(rising_edge(clk)) THEN [*] IF(rd_add = '1') THEN --write status register to master [*] CASE bit_cnt(10 DOWNTO 8) IS [*] WHEN "001" => miso <= trdy; [*] WHEN "010" => miso <= rrdy; [*] WHEN "100" => miso <= roe; [*] WHEN OTHERS => NULL; [*] END CASE; [*] ELSIF(rd_add = '0' AND bit_cnt(7 DOWNTO 0) = "00000000" AND bit_cnt(d_width+8) = '0') THEN [*] miso <= tx_buf(d_width-1); --send transmit register data to master [*] END IF; [*] END IF; [*] [*] END PROCESS; [*]END logic; [/LIST]


Waveforms
 

Attachments

  • Screenshot 2023-04-19 140216.png
    Screenshot 2023-04-19 140216.png
    271.9 KB · Views: 125

1) You don't assign anything to "cpha", but use it in a statement
2) You don't even SHOW cpha in your simulation
 

How about posting regular formatted VHDL code as every Edaboard user does?
 

1) You don't assign anything to "cpha", but use it in a statement
2) You don't even SHOW cpha in your simulation
cpha is listed in the genrics and is assigned to 0 and i can show you my simuluation waveforms with cpha and cpol
--- Updated ---

How about posting regular formatted VHDL code as every Edaboard user does?
sorry i will fix it for future posts seems like i cant really edit it now
 

Attachments

  • Screenshot 2023-04-20 070649.png
    Screenshot 2023-04-20 070649.png
    244.9 KB · Views: 118

bit_cnt <= (conv_integer(NOT cpha) => '1', OTHERS => '0');
with cpha:='0', this sets bit_cnt(1) to '1', respectively bit_cnt numeric value = 2, as seen on your simulation.
Apparently the expression is written so confusing that you don't expect this result.

I don't know what's the meaning of the latest post waveform dump in relation to post #1. In any case, you should fix these many 'U' values.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top