Forum Discussion
22 Replies
- Altera_Forum
Honored Contributor
Sorry to be brusk about this, but you need to study the material on the Avalon bus and how to interface to it with QSYS. You need to write code that implements the timing diagrams shown in the Avalon bus spec. Make use of the simulator and Avalon bus modules for help.
- Altera_Forum
Honored Contributor
--- Quote Start --- Hello rromano001; well i want to use a simple adder that i give it 2 numbers nd it calculates the sum; but i wanna use it in a Qsys system for example i will not send this calculus to the processor but i will send it to this adder nd it gives me directly the result that the processor can use it iam new learner in that reason iam facing this difficulties --- Quote End --- don't worry about, I am also a quite beginner on QSYS, I learn't how to produce modules and interface but a lot has to be grasped about for parametrization, give it time and patience and you arrive wherever. For a simple adder it is not a problem to guide you but all is necessary is to understand what is your goal. This case you need register to load operand, output of adder don't require a register due it is static computed from input. Is not better to have a readable and writeable register on how you can do first QSYS module then customize using adder? How much are you proficient in VHDL? Have you experience on processor buses? On Avalon, did you understand how Memory mapped master and slave work? signal are presented on QSYS when you build the interface and some also have explanation. Was of some help the guide I proposed? On all question just add detail and on my free time I try guide/help on topic. try google this "altera qsys reg32 component" select "Making Qsys Components Tutorial" try follow instruction on how to create register, then when you are ready and you are able to read write register just extend using two address bit, register this case was using byte selector signals to select which byte to write, leave this and add more than one register, write read on decoded addresses 0, 1, then feed data to adder and insert another address to read adder result. Try suggested material after that ask more help. Generate a module is not a complex task, inserting parameter is a scripting question but just start from basic module then extend it. Actually I ported about 30 of my library module to Qsys streaming, pure conduit and memory mapped master slave devices, it is quite simple and save tedious task of writing glue top level VHDL interface connecting them. - Altera_Forum
Honored Contributor
--- Quote Start --- this is the code iam trying to use architecture behavioral of ADDER is -- define a temparary signal to store the result signal result: std_logic_vector(n downto 0); begin process begin -- the 9th bit should be carry WAIT UNTIL clock'EVENT AND clock = '1'; if resetn = '0'THEN result <= "000000000"; else result <= ('0' & A)+('0' & B ); end if; end process; sum <= result(n-1 downto 0); carry <= result(n); end behavioral; yhanks for advance --- Quote End --- Hi, you are quite close to solution but you need understand this is devoted to a microprocessor bus and operand A and B cannot be on bus at same time if not encoded on same mode for example in a word (deprecated without a very strong reason to do that), if you decide bus width of your device can be 8 bit then you have to declare on QSYS module and module is only able to do byte transaction. You need two addressable register to store operand then read result from adder, adder can be just conbinatorial full adder written from xor and logic if you use std logic or inferred from arithmetic. Your code instead make result from two parallel operand then store to a register on clock transition. How can you write two operand on a bus where operand are written one at time? Also you just have output from adder registered on rising edge. So inspire on example as suggested, store the two operand then read result. Try one more then post again your code or better ask again about what can be unclear. result <= ('0' & A)+('0' & B ); this expression compile error free? + is an arhitmetic operator and vector are std logic not signed or unsigned. another deprecated solution can be to have both A and B input from two conduit if you are collecting from somewhere then just read result from Avalon Again you are probably at first step on VHDL too, tell us what you wish to do with, or if this an exercise the term of it. Patience application and reading of material, documentation of quartus VHDL and QSYS too are not short so you need more and more exercise and application, just never give up. - Altera_Forum
Honored Contributor
--- Quote Start --- this is the code iam trying to use BEGIN to_adder <= writedata; --WITH (chipselect AND write) SELECT adder_instance: adder PORT MAP (clock, resetn, to_adder, from_adder); readdata <= from_adder; --- Quote End --- Any progress on this part? Avalon read write data on rising edge of clock, also reset_n is better if implemented on, other signals: readdata, writedata tell logic about data direction, cs tell your module it is selected and address in yor case select one of four register. You need also test byteselect vector too. Did you learnt something from 32 bit register example? Regards - Altera_Forum
Honored Contributor
Hi,
I don't see the use of such a Qsys component, but anyway, below is a proposed VHDL component for the implementation. It has three slave registers, two for the input operands (readable and writable) and one for the result (only readable). I haven't tested the code, so it may contain syntax or other errors, but it should give you the idea. Bye, Philipp EDIT: Sorry, I missed the second page of the thread. I'll still leave my post here for reference, maybe it is of use anyway.library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; --! This entity is a Qsys core for a simple adder. --! Register map (word addresses): --! 0x0: Operand A (RW) --! 0x1: Operand B (RW) --! 0x2: Result (RO) --! 0x3: Unused entity udc_dac is generic ( --! Width of the Avalon data bus. DATA_W : positive := 32; --! Width of the Avalon address bus. Every address corresponds to --! one 32-bit word (so the address space in bytes is actually --! 4 times larger). ADDR_W : positive := 2 ); port ( -- System signals. --! Master clock input, all logic is contained in this clock domain. clk : in std_logic; --! Asynchronous reset input, resets the internal logic. reset : in std_logic; -- Avalon slave interface signals. --! Avalon read request. Reads are performed with a single waitstate --! (wait 1). read_ava : in std_logic; --! Avalon write request. write_ava : in std_logic; --! Avalon address input. address_ava : in std_logic_vector(ADDR_W-1 downto 0); --! Avalon data input. writedata_ava : in std_logic_vector(DATA_W-1 downto 0); --! Avalon data output. readdata_ava : out std_logic_vector(DATA_W-1 downto 0) ); end entity; architecture behav of udc_dac is -- Operand registers. signal op_a, op_b : unsigned(DATA_W-1 downto 0) := (others => '0'); -- Result register. signal result : unsigned(DATA_W-1 downto 0) := (others => '0'); begin -- Avalon read transaction handler. avard : process(clk, reset) is variable addr : natural range 0 to 3; begin if reset = '1' then readdata_ava <= (others => '0'); elsif rising_edge(clk) then if read_ava = '1' then addr := to_integer(unsigned(address_ava)); case addr is when 0 => readdata_ava <= std_logic_vector(op_a); when 1 => readdata_ava <= std_logic_vector(op_b); when 2 => readdata_ava <= std_logic_vector(result); when others => readdata_ava <= (others => '0'); end case; end if; end if; end process; -- Avalon write transaction handler. avawr : process(clk, reset) is variable addr : natural range 0 to 3; begin if reset = '1' then dac_value <= (others => (others => '0')); elsif rising_edge(clk) then if write_ava = '1' then addr := to_integer(unsigned(address_ava)); case addr is when 0 => op_a <= unsigned(writedata_ava); when 1 => op_b <= unsigned(writedata_ava); when others => -- Ignored. end case; end if; end if; end process; -- Calculation. calc: process(clk, reset) is begin if reset = '1' then result <= (others => '0'); elsif rising_edge(clk) then result <= op_a + op_b; end if; end process; end architecture; - Altera_Forum
Honored Contributor
Hi Phlibi, I read over your code, it can help understand how to interface avalon Bus but at first glance it has some flaws:
Registers are 32 bit wide- No byte addressing is provided on No status register is provided to check for overflow On avalon write part: if reset = '1' then dac_value <= (others => (others => '0')); elsif rising_edge(clk) then this code reset an undeclared dac_value, I don't see declared on your code post, others is used two times as if op_a was an aggregate so I think about syntax error, IMHO it has to reset op_a and op _b so must look as it follow --- : this version generate an asyncronous reset and probably a latch. if rising_edge(clk) then if reset = '1' then op_a <= (others => '0'); op_b <= (others => '0'); else Process calc is active forever, it is required just when you write one of operand, this save a lot of power. Regards - Altera_Forum
Honored Contributor
--- Quote Start --- Hi Phlibi, I read over your code, it can help understand how to interface avalon Bus but at first glance it has some flaws: Registers are 32 bit wide- No byte addressing is provided on No status register is provided to check for overflow --- Quote End --- This is left as an exercise for the reader ;) In fact, this component does not serve any real purpose anyways, so I've just omitted additional features. Byte addressing would need additional consideration anyways, as this would basically lead to kind of vector processing by packing four independent additions into one word or something similar. --- Quote Start --- On avalon write part: if reset = '1' then dac_value <= (others => (others => '0')); elsif rising_edge(clk) then this code reset an undeclared dac_value, I don't see declared on your code post, others is used two times as if op_a was an aggregate so I think about syntax error, IMHO it has to reset op_a and op _b so must look as it follow --- : --- Quote End --- Yeah, dac_value is a relict from where I copied the code from. This was some other component from one of my designs and I just overlooked the line when hacking in the modifications. As I said, I haven't tested it. --- Quote Start --- this version generate an asyncronous reset and probably a latch. if rising_edge(clk) then if reset = '1' then op_a <= (others => '0'); op_b <= (others => '0'); else --- Quote End --- Yes, this would be the proper reset code. --- Quote Start --- Process calc is active forever, it is required just when you write one of operand, this save a lot of power. --- Quote End --- This is an FPGA, not a microcontroller where you can just "skip" an operation when it's not used. The adder is needed anyways, so it will always draw static power. As long as the input data doesn't change, there is no additional dynamic power. The only thing which is always clocked is the result register, but adding additional logic to enable it only when something changed will most likely increase consumption. I doubt that any of these would actually be measurable, though. Bye, Philipp - Altera_Forum
Honored Contributor
--- Quote Start --- This is left as an exercise for the reader ;) In fact, this component does not serve any real purpose anyways, so I've just omitted additional features. Byte addressing would need additional consideration anyways, as this would basically lead to kind of vector processing by packing four independent additions into one word or something similar. --- Quote End --- Hi Philipp, sorry for but I disagree that, our poster is just a beginner and wrong coding can confuse a lot, yes your code has type conversion and can work, I seen no declaration just during check for operand type, addition on code from poster cannot be done using std_logic_vector. VHDL is strong typed and far from be a simple language we are using here the HDL part so during learning need have hint and example to grasp how to implement right way without inferencing latch and or other trap of. Also programming and simulation part are far from other languages I feel few people can know in its entirety. So guide and hint to help get right direction on huge amount of user manual and handbook. --- Quote Start --- This is an FPGA, not a microcontroller where you can just "skip" an operation when it's not used. The adder is needed anyways, so it will always draw static power. As long as the input data doesn't change, there is no additional dynamic power. The only thing which is always clocked is the result register, but adding additional logic to enable it only when something changed will most likely increase consumption. I doubt that any of these would actually be measurable, though. Bye, Philipp --- Quote End --- From early time of cmos I remember this: everything is clocked and is a cmos device has near zero power draw when f=0 but power raise with square of frequency, this at time of TTL and STTL, HC HCT crossed the power of old standard just near 1MHz, at that time FPLA PAL PLD CPLD where power hungry and leaving something active was driving die very hot. Maybe nowadays tools move process on register change and/or provide clock enable or simple feedback logic, so old school was to optimize for power too, I just do some check to see power planner. I am now using operator than old logic equation to generate logic so TOOLS are more smarter and last 15/20 year of development changed mode of thinking too and last but not least languages. This time I am quite busy, I try see some different approach with large registers and check power draw. regards Roberto - Altera_Forum
Honored Contributor
--- Quote Start --- You use different address values to access your module. For example: address 0 => input 0, address 1 => input 1, address 2 => output. Your code needs to look at the address lines to decide what is being accessed. Read the material I mentioned on Qsys. It's explained there. --- Quote End --- For PIO connected to Lightweight AXI, for example, if you want to read or write an address with the same offset ,the adress you need to pass to the function is the same, the only change is the function (read or write) - Altera_Forum
Honored Contributor
--- Quote Start --- don't worry about, I am also a quite beginner on QSYS, I learn't how to produce modules and interface but a lot has to be grasped about for parametrization, give it time and patience and you arrive wherever. For a simple adder it is not a problem to guide you but all is necessary is to understand what is your goal. This case you need register to load operand, output of adder don't require a register due it is static computed from input. Is not better to have a readable and writeable register on how you can do first QSYS module then customize using adder? How much are you proficient in VHDL? Have you experience on processor buses? On Avalon, did you understand how Memory mapped master and slave work? signal are presented on QSYS when you build the interface and some also have explanation. Was of some help the guide I proposed? On all question just add detail and on my free time I try guide/help on topic. try google this "altera qsys reg32 component" select "Making Qsys Components Tutorial" try follow instruction on how to create register, then when you are ready and you are able to read write register just extend using two address bit, register this case was using byte selector signals to select which byte to write, leave this and add more than one register, write read on decoded addresses 0, 1, then feed data to adder and insert another address to read adder result. Try suggested material after that ask more help. Generate a module is not a complex task, inserting parameter is a scripting question but just start from basic module then extend it. Actually I ported about 30 of my library module to Qsys streaming, pure conduit and memory mapped master slave devices, it is quite simple and save tedious task of writing glue top level VHDL interface connecting them. --- Quote End --- Hello rromano001; for your first question: How much are you proficient in VHDL?; my answer is : not very well; for the second question: Have you experience on processor buses?; mmmm a little bit yes On Avalon, did you understand how Memory mapped master and slave work?; yes i did i sow the example of the register and i understand it very well i will follow your steps and i will see the results thank you so much and hope that you guide me more