this is my first posting here and third day with PSOC Creator, so thank you in advance for being forgiving if the questions are trivial.
I want to build an 8-bit output-only parallel port which takes a byte from memory using DMA and sends it to a peripheral port. In the attachment there is my current state of affairs. I would like to ask the following.
1. Power_Data_Output is the intended destination for the DMA transfers. Currently I attached it to a constant, but how exactly should I tell Creator that it will be driven by DMA, so it should stay unconnected? If I just do tht, the compiler says "No input on Instance "Power_Data_Output", terminal "y_7[7:0]".
2. I want to be sure that the Power_SHCP strobe pin is driven sufficiently past the actual Power_Data_Output setup in order to avoid race conditions and I also want to extend it in time to a single 4MHz clock pulse (BUS_CLK is 64MHz). Is the solution with the RS flip-flop sound?
3. In a broader context it may be useful to pass the 8-bit data chunk through the UDB's datapath, which would imply sending the byte to the associated FIFO and generating all the strobes in the datapath program. But what then with the byte? Is there a way to latch it somehow in the datapath's output/the second FIFO and route directly to the peripheral port, without engaging another DMA and sparing the programmable logic macrocells for other purposes? My ambition is to do everything described here and on the diagram within a single UDB, just for the purpose of learning it.
4. How do I actually know how many UDBs have been consummed? The tool informs me about RAM usage etc., but I don't see anything about the UDBs.
Welcome in the forum and in the fascinating world of PSoCs.
To help you in depth, best is always to post your complete project, so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.
For the pins is a configuration option "Hardware connection" which you should uncheck to control the pin by software.
Where does your strobe signal come from? If it is of async nature you ought to sync it to a system clock, there are components for that.
PSoC 5 hardware and code are very efficient to debug using the debugger and a logic analyzer. Verilog programmed UDBs are quite difficult to get debugged. I would suggest you to learn about PSoCs in depth before you walk that stony way programming UDBs yourself.
3. Answ: your UDB can be configured to provide an output bus which can be connected to your port. This will consume more resources than a simple dma to the port pins including the strobe signal generation.
At the very right hand side of the Creator window is a "Resource Meter" tab which shows (after a build) the resource consumption.
Thank you, Bob, I haven't noticed the "Resource monitor" tab -- it was exactly what I was looking for. As for "hardware connection", it also did the job, but I think it is a proper time to make a user experience note that the yellow comment attached to it is a bit misleading: I thought that a "hardware connected" pin is a pin which is attached to one of the packge pins. IMVHO it should have been "hardware controlled" in Creator. Then a question arises: what is the best practice to introduce virtual pins on the diagram? For example, on the attached diagram you can see two PWM outputs. One of them should be connected to a package pin as "Power_PWM_nB", but the other is logically not a true external signal on its own, as it is connected to a package pin "Power_nOE". I merely want to indicate that "Power_PWM_nA" is logically there too, but its physical routing to "Power_nOE" is a matter of an implementation detail. What would you do in such a case, a named wire?
Going back to my question about UDB: no, I don't dare to think about direct Verilog programming, at least not yet. 🙂 I am considering usage of the UDB builder tool, but only at the GUI level, without any Verilog mix-ins.
You also asked about the DMA strobe synchronization: finally the transfer will be requested by an NCO clocked from BUS_CLK, now it is just a mockup 410kHz clock component. So, at dreq level it will always be synchronized to BUS_CLK. The problem is(?) the strobe for the external circuitry derived from nreq, which will instruct it to latch the byte transferred by DMA to a GPIO port. The documentation says that nreq is asserted for 2 BUS_CLK cycles after the transfer. At 64MHz it would mean 1/32e6
, which is way too narrow a pulse. What the documentation doesn't say (or I missed it) is exactly when the nreq signal is asserted. During the same cycle as the actual transfer? 5 cycles later? How can I be sure that the GPIO state is stable? And that's the intended purpose of the RS latch: extend the 1/32MHz pulse to 1/4MHz (both synchronous with respect to BUS_CLK) and delay it a bit in order to make sure the data setup time requirements are met. The DMA firing rate is 410kHz and the channel will have the highest priority, so there is no risk that 2 DMA transactions will happen during the same (or even several consecutive) 4MHz external interface cycles. Is it the way you do it in the PSOC world? 🙂
Thank you very much for your help!
There is a Pulse Converter component (Digital -> Utility) that you can use to catch the sync and delay it for at least a clock period, see datasheet.
Thank you for your comments and examples, this has boosted my learning process enormously. Now I have the most basic DMA transfers working, it's time to model the real thing.
The FSM will be quite complex, so I decided it's a good time to learn how to interact with datapaths. For the purpose of learning I make it excessively complex; the next stage to be designed (PLL + filtering + NCO) seems to require the hidden datapath features like the carry circuitry, not available from the basic datapath configurator, so I added a new component to the library (PowerBusController) and switched to Datapath Configuration Tool. The attached project shows the general idea (please do not analyze the datapath FSM, it's mostly nonsense, I just wanted to check if the steering FSM works -- it does). There is a datapath and an instance of Counter7. Problems and questions:
1. The counter does not start. If I use the GUI editor and place such a counter there, it does not start either. So the behavior is consistent. In the latter case I need to explicitly use the relevant generated API and then the PWM sequencer operates flawlessly. It seems obvious that I need to do the same with the Verilog instance, but how? The Cypress-provided components somehow generate the headers addressing the UDB the component is is referring to. How do I get this information in the case of Verilog-based components?
2. Can I write a byte from A0 to a FIFO in one datapath cycle and load it to D0 in the next? I want to extend the number of available 'registers' and it seems the natural way to do so.
3. Say a time-multiplexed datapath generates 2 bytes in consecutive cycles. How do I feed it to another datapath? Is the Parallel In/Parallel Out circuitry provided for that purpose? If not, what should I do instead?
I'm not quite fit in UDB programming, but I know of some more docs. Enter "cheat" into the keyword search field at top of this page.
I have no problems with Verilog programming, would even say it is my preferred way. I have some experience with FPGA. The factory-provided components are fine for simple needs, but if something is non-standard (not necessarily complex, even something as simple as a carry chain in a time-multiplexed datapath), I quickly find myself working against the tool, not with the tool. Very discouraging, but I am used to it. I I just don't know how to integrate my Verilog with Creator. Say I already have a UDB Verilog file, with three datapaths and five Count7 instances, then what? Where exactly are the registers and how to access it from C? I'll need to read the component author guide, thanks!
The PLL will be running at 50Hz, hard (or unnecessarily complex) to do in analog. And I have the DFB, which should allow me to implement a zero phase shift filter, very helpful in a noisy environment.
For everyone who can have the same kind of problems: the UDB resource mapping for all the instantiations is in the auto-generated file cyfitter.h.