I am attempting to use the IP packaging tools in Xilinx Vivado to create a co-processor with an AXI-Lite interface and utilize it in a Zynq SoC design for my Digital Systems Engineering class. The co-processor is a GCD calculator that we have already developed as part of a previous assignment. I followed the instructor's directions to create an IP out of the GCD calculator, and we loosely followed Tutorial 4A from the PDF located here to create the AXI interface (the I/O declarations are obviously modified to accomodate the GCD calculator). I have a data bus called 'data' running from the AXI IP and the GCD IP to send values to the calculator. However, when I attempt to Synthesize the design, I get an the following error:
[Synth 8-685] variable 'data' should not be used in output port connection'
The error directs to the line of my AXI bus interface instantiation where my data port is defined.
I've been searching online for a solution to this error for hours, but not even the Xilinx website, nor the Xilinx documents that have been made available to us, have any information regarding this error, and I have not been able to find any accounts from anyone experiencing the same error.
I emailed the professor to see if he has any ideas, but he probably won't be awake for another six hours and the assignment is due today (tomorrow?).
Has anyone heard of this error, or have any idea of how to correct it?
Here's a portion of code that contains the error's source:
// Instantiation of Axi Buss Interface S00_AXI
myip_v1.0_0_S00_AVI # (
.C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH),
.C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH)
) myip_v1_0_S00_AXI_inst (
.done_async(done_async),
.go(go),
.data(data), // The error points to this line
.S_AXI_ACLK(s00_axi_aclk),
... // all remaining ports were generated by the IP tools
);
Thanks,
-Andrew
It looks to me like you are trying to drive a variable from the output of an instantiated module. In Verilog you cannot drive a variable from an instantiated module. This is illegal in Verilog (though it is not in SystemVerilog):
reg OP; -- this is a variable
SOME_MODULE MODULE_INST (.IP(IP), .OP(OP));
whereas this is not illegal:
wire OP; -- this is a net
SOME_MODULE MODULE_INST (.IP(IP), .OP(OP));
Related
I am able to build the code in modelsim but, when simulation getting below error:
addr_x, driven via port connection, is multiply driven (44) Line :49
addr_f, driven via port connection, is multiply driven (46) Line :49
s_ready_x, driven via port connection, is multiply driven (44) Line :49
s_ready_f, driven via port connection, is multiply driven (46) Line :49
How can I resolve this? (system verilog)
There is no simple* fix: You have to change your design. You might even have to go "back to the drawing board" and fundamentally change your design.
In each of the ctrlpath.., modules you output an address. Thus you drive the same net from different outputs. You somehow have to distinguish which of those you are really going to need. Thus you need to add a multiplexer which 'knows' which on to pick.
The "multiple driven" error is a recurring question appearing on Stack Overflow and Electrical engineering. What you have done is connecting multiple output ports together. In electrical engineering we call this 'shorting outputs together'. The term shorting is important as it is effectively a short circuit. This is the equivalent circuit:
Some outputs will be high and others are low. The ones which are high will try to drive the output high opening a current path from the VCC to the output pin. The ones which are low will try to drive the output low. They open a current path from the output to ground. Together they form a short circuit between your VCC and ground.
*Do not think you can easily solve this with tri-state drivers. Theoretical it may seem possible, practically you really, really don't want that.
Here is one of the messages from VCS compilation:
Error-[ICSD] Illegal combination of drivers
design.sv, 38
Illegal combination of structural drivers.
Variable "s_ready_x" is driven by multiple structural drivers.
This variable is declared at
"design.sv", 38: logic s_ready_x;
The first driver is at "design.sv", 50: ctrlpatho c( .clk (clk), .reset
(reset), .wr_done_f (wr_done_f), .wr_done_x (wr_done_x), .addr_x
(addr_x), .addr_f (addr_f), .m_valid_y (m_valid_y), .c ...
The second driver is at "design.sv", 45: ctrlpathx x( .clk (clk), .reset
(reset), .s_ready_x (s_ready_x), .addr_x (addr_x), .wr_done_x
(wr_done_x), .wr_en_x (wr_en_x), .s_valid_x (s_valid_x));
it just propagates the issue to the top-level module, but gives correct locations of the drivers.
The problem is, that both ctrlpathf and ctrlpatho drive the same signal with output ports. The rule of thumb is:
you cannot drive the same variable with multiple drivers.
System verilog just adds this requirement to the standard and it gets checked for the specific system verilog blocks.
To fix it
you need to review your program, in case you just made a mistake.
verilog allows you to multiply drive net types and defines rules for the results. If you really want to have multiple drivers, you would need to declare those ports as wires or similar and change the code to reflect it. They can be multiply driven with the assign statements.
I work with Zedboard and vivado v2017.3.
I have a custom IP in the PL part of zynq generating 32 bit values and stores them in one of the registers, say slv_reg0 (address : 0x43c00000).
In the PS part I read this register and I can print it in the gtkterm (simple one).
I now want to transmit these values over ethernet to to the PC.
Any suggestion on how to carry out this?
Thanks,
Upasana.
Xilinx supplies sample programs, one of these is an echo server. It should be quite simple to change it so that it serves the data you generate instead of just echo-ing the received message, and you can learn out of it how to use the lwip library in case you want a more suitable solution.
I am trying to write a verilog code for FPGA which will output sound from the embedded "line out" pin. I use Quartus II and Altera DE1.
I am new to hardware programming, therefore it just takes too much time for me to catch up with basics. Apparently I need to initialize the wolfson chip and need to write something to communicate with it, as discussed here:
http://www.alteraforum.com/forum/showthread.php?t=6005
It uses wolfson WM8731 codec, manual is in here:
http://www.rockbox.org/wiki/pub/Main/DataSheets/WM8731_8731L.pdf
and an example I found but couldnt figured out how to use it is in here:
https://code.google.com/p/vector06cc/wiki/SoundCodec
I have found bunch of examples about how to generate sounds using GPIO pins, but barely anything about the usage of WM8731. I would really appreciate any guidance or experience you might share.
Assuming you're using Nios II and either SOPC Builder or Qsys, the Altera University Program offers an IP core to control the Audio CODEC on the DE-Series boards.
If you don't already have it, you can download it here (at the bottom of the page, listed as University Program Installer): https://www.altera.com/support/training/university/materials-ip-cores.html
Once you install it, check the <altera-directory>/University_Program\NiosII_Computer_Systems\DE1\DE1_Media_Computer directory. app_software and app_software_HAL both give example methods to write to the audio output (using C code running on the Nios II), and the verilog or vhdl folder show example systems on connecting the core to a NIOS II using your preferred HDL.
The core itself can be found in <altera-directory>\ip\University_Program\Audio_Video. See also ftp://ftp.altera.com/up/pub/Altera_Material/14.1/University_Program_IP_Cores/Audio_Video/Audio.pdf for some (potentially) helpful reading/reference.
Addendum:
All of the FPGA inputs and outputs use the "Digital Audio Interface" of the WM8731 chip. The pins available on the FPGA are as follows:
PIN_A6 : AUD_ADCLRCK
PIN_B6 : AUD_ADCDAT
PIN_A5 : AUD_DACLRCK
PIN_B5 : AUD_DACDAT
PIN_A4 : AUD_BCLK
PIN_B4 : AUD_XCK (MCLK on WM8731)
Output is sent to the CODEC on the AUD_DACDAT pin.
The chip is configured using the I2C_SDAT and I2C_SCLK pins on I2C address 0x34 for read, and 0x35 for write.
No other pins are available to the FPGA - some are used for external connections (like the mike or line-in), or are not connected at all.
For a full list of pin assignments for the DE1 (which can be directly imported to Quartus) see: ftp://ftp.altera.com/up/pub/Altera_Material/12.1/Boards/DE1/DE1.qsf
Referring to my earlier question here, I've been utilizing tri-states to work with a common bus. I still appear to have some implementation issues.
The tri-states use this type of code:
assign io [width-1:0] = (re)?rd_out [width-1:0]:{width{1'bz}};
Synthesis and translation goes well. No warnings or errors I wasn't expecting (I was expecting some since this is only a trial run and most of the components don't do anything and will hence be left unconnected). But when I actually try to implement it, all busses (there are three) output a 1111111111111111, or a -1, as converted by my binary to BCD converter. I checked if it really the case by instructing the control matrix to halt if the instruction received on the bus is -1, and it did halt.
The warning I receive for the tri-state being converted to logic is:
Xst:2040 - Unit Neptune_I: 16 multi-source signals are replaced by logic (pull-up yes)
Xst:2042 - Unit alu: 16 internal tristates are replaced by logic (pull-up yes):
And so on. Neptune_I is the top module, and I believe the multi-source signals it's referring to are the busses.
I have a doubt whether the pull-up yes is the root of this problem. Is it simply pulling everything up, causing it to be -1 all the time? But this does not make sense to me, because when the tri-state is activated, the signal should be controlled by whatever entity it is supposed to be controlled by.
I would like to take the time to replace the code with logic instead of the tri-states, but I'm unsure how to proceed.
Any help would be appreciated.
Are these signals going off-chip? Or are they internal to your FPGA? If the answer is the latter, you need to change your code. Modern FPGAs (like Spartan 6) no longer support internal tri-state buffers. They only exist for off-chip signals.
You need to write all of you internal code to avoid tri-state buffers. Create dedicated paths between components, no bidirectional interfaces.
I've been coding a 16-bit RISC microprocessor in Verilog, and I've hit yet another hurdle. After the code writing task was over, I tried to synthesize it. Found a couple of accidental mistakes and I fixed them. Then boom, massive error.
The design comprises of four 16-bit common buses. For some reason, I'm getting a multiple driver error for these buses from the synthesis tool.
The architecture of the computer is inspired by and is almost exactly the same as the Magic-1 by Bill Buzzbee, excluding the Page Table mechanism. Here's Bill's schematics PDF: Click Here. Scroll down to page 7 for the architecture.
The control matrix is responsible for handling when the buses and driven, and I am absolutely sure that there is only one driver for each bus at any given instance. I was wondering whether this could be the problem, since the synthesis tool probably doesn't know this.
Tri-state statements enable writing to a bus, for example:
assign io [width-1:0] = (re)?rd_out [width-1:0]:0; // Assign IO Port the value of memory at address add if re is true.
EDIT: I forgot to mention, the io port is bidirectional (inout) and is simply connected to the bus. This piece of code is from the RAM, single port. All other registers other than the RAM have separate input and output ports.
The control matrix updates a 30-bit state every negative edge, for example:
state [29:0] <= 30'b100000000010000000000000100000; // Initiate RAM Read, Read ALU, Write PC, Update Instruction Register (ins_reg).
The control matrix is rather small, since I only coded one instruction to test out the design before I spent time on coding the rest.
Unfortunately, it's illogical to copy-paste the entire code over here.
I've been pondering over this for quite a few days now, and pointing me over to the right direction would be much appreciated.
When re is low, the assign statement should be floating (driving Zs).
// enable ? driving : floating
assign io [width-1:0] = (re) ? rd_out [width-1:0] : {width{1'bz}};
If it is driving any other value then the synthesizer will treat is as a mux and not a tri-state. This is where the conflicting driver message come from.