Queue declaration SystemVerilog compiling error - queue

Hi I have the next lines of code inside a testbench module in a SystemVerilog file using Intel Quartus Prime :
`timescale 1ns/1ps
module fo;
parameter retardo_reset = 150;
parameter repetir = 2;
reg clock;
reg reset;
reg clear;
reg rden;
reg wren;
reg [7:0] data_in;
reg [7:0] data_out;
reg [7:0] queue [$:31];
reg [7:0] random_number;
wire aempty;
wire afull;
wire empty;
wire full;
// There is more code there ...
But the compiler says that in the line declaring the queue reg [7:0] queue [$:31]; there is the next error:
Error (10170): Verilog HDL syntax error at fo.sv(15) near text: "$"; expecting an operand. Check for and fix any syntax errors that appear immediately before or at the specified keyword. The Intel FPGA Knowledge Database contains many articles with specific details on how to resolve this error. Visit the Knowledge Database at https://www.altera.com/support/support-resources/knowledge-base/search.html and search for this specific error message number.
Do you know what I'm doing wrong? Because that's the correct way to declare a limited queue in SystemVerilog.

According to the Quartus manual, it does not currently support synthesis of the queue data type, even when bounded.

Related

Why is the wired or signal type (wor) disallowed for typedefs in SystemVerilog

In SystemVerilog I CAN do
typedef logic [15:0] bus16;
typedef reg [15:0] reg16;
interface myif;
bus16 mybus;
wor [15:0] myotherbus;
endinterface
But I CAN'T do
typedef wor [15:0] wor16;
interface myif;
wor16 myotherbus;
endinterface
I get "unknown variable declaration type"
It seems, at least in my Synplicity version, typedefs of 'wor' is not permitted.
Is this a limitation defined in the IEEE1800 spec or is it perhaps a bug?
SystemVerilog separates the concepts of network/net types (which are like resolved signals in VHDL) and variables (unresolved) from data types. The net types wire, wand, wor, etc. have built-in resolution functions with a default data type of logic. The following net declarations are equivalent:
wor [15:0] w;
wor logic [15:0] w;
typedef logic [15:0] bus16;
wor bus16 w;
Similarly the following variable declarations are equivalent:
logic [15:0] v;
var logic [15:0] v;
typedef logic [15:0] bus16;
var bus16 v;
bus16 v;
In most places, the var keyword is implicit when declaring variables.
There is a nettype declaration that binds a data type with a user-defined resolution function. Unfortunately there no way to define a nettype with one of the built-in resolution functions, so you would have to write your own or function.
It is disallowed because System Verilog Standard does not allow using nets in typedefs. Sorry, no other explanation.
You can look at the syntax in paragraph 6.18. Follow data_type definition. It is based on system verilog vars but does not include nets (6.8).
You can define a new net type using the nettype construct, but it still does no allow you to use other net types. However, you can create them with a custom resolution behavior (check 6.6.7). It is a special syntax and does not fit for simple renaming. BTW, neither wor nor this are synthesizable.
So, your best bet is to use macros: `define wor16 wor[15:0]

I can't compile a .sv file (SystemVerilog)

I'm learning SystemVerilog for the university. I installed the extensions in Visual Studio Code for syntax highlighting: SystemVerilog, Verilog-HDL/SystemVerilog/Bluespec SystemVerilog (Names of extensions).
I installed the compiler Icarus Verilog and inserted the address in the environment variables (PATH).
So I copied this code:
module adder
(s, b, c_in, sum, c_out);
input logic [7:0] a;
input logic [7:0] b;
input logic c_in;
output logic [7:0] sum;
output logic c_out;
logic [8:0] result;
assign result = a + b + c_in;
assign sum = result [7:0];
assign c_out = result[8];
endmodule: adder
And tried to run it, but it gave me this error:
Module end labels require SystemVerilog.
I even tried to compile from the cmd with the same result.
A thing that I noticed is that when I do the same thing with a .v file (Verilog), it works.
I get a compile error in your port list. Change:
(s, b, c_in, sum, c_out);
to:
(a, b, c_in, sum, c_out);
You didn't declare a in the list, and you use a in the code. s is not in the code.
After that change, your code is legal SystemVerilog syntax, and it compiles without errors on multiple simulators on edaplayground.
I did get different compile errors from yours with Icarus Verilog 0.10.0 on edaplayground. Perhaps you are compiling with a different version. Keep in mind that iverilog does not support all SV features yet.
If the module label is still causing problems for you, you can simply remove it because it is optional. Change:
endmodule: adder
to:
endmodule
Regarding the file extensions (.v and .sv), some compilers will automatically enable SV features when you use .sv; perhaps some even require .sv. Since your code uses an SV keyword (logic), you must have SV features enabled to compile.
Here is a version of your code that does not rely on SV features:
module adder
(a, b, c_in, sum, c_out);
input [7:0] a;
input [7:0] b;
input c_in;
output [7:0] sum;
output c_out;
wire [8:0] result;
assign result = a + b + c_in;
assign sum = result [7:0];
assign c_out = result[8];
endmodule
Using logic in the port declarations is optional, and you can declare result as a wire.

Multidriven nets: Synthesis ok, Simulation fails

I have a fundamental understanding problem with System Verilog. I am working on a processor design, where some bus systems should be shared between several processing units (System Verilog modules). With an arbiter only one module at a time should be active, driving the bus, while all other are high impedance.
I got rid of the multidriven nets warnings in Vivado during synthesis and there are not anymore any bus conflicts, but the simulator gives a warning, that the bus signals 'might' be multidriven. I made a tiny example code and I would expect to get for 'data' '11', when 'select' is '10'?
While simulation stops at all in Vivado, it works with Cadence simulator, but with wrong results - screenshot simulation
testbench.sv
`timescale 1ns / 1ps
module testbench_top();
logic [1:0] select;
logic [1:0] data;
top top_inst(.*);
initial
begin
select = 0;
#2 select = 1;
#2 select = 2;
#2 select = 0;;
end
initial
begin
$monitor("t=%3d s=%b,d=%b\n",$time,select,data);
end
endmodule
design.sv
`timescale 1ns / 1ps
module top
(
input logic [1:0] select,
output logic [1:0] data
);
driver_1 driver_1_inst(.*);
driver_2 driver_2_inst(.*);
endmodule
module driver_1
(
input logic [1:0] select,
output logic [1:0] data
);
always_comb
begin
if (select == 2'b10)
data = 2'b11;
else
data = 'z;
end
endmodule
module driver_2
(
input logic [1:0] select,
output logic [1:0] data
);
always_comb
begin
if (select == 2'b01)
data = 2'b01;
else
data = 'z;
end
endmodule
I'm assuming you expect the value of data signal the top module, which is driven by the two outputs of your driver modules, to be resolved (e.g. when one drive 'z, the other gets the bus.
This will happen if you declare the top.data signal as output wire logic [1:0] data.
Section 23.2.2.3 Rules for determining port kind, data type, and direction of the IEEE 1800-2012 standard states that
For output ports, the default port kind depends on how the data type
is specified: — If the data type is omitted or declared with the
implicit_data_type syntax, the port kind shall default to a net of
default net type. — If the data type is declared with the explicit
data_type syntax, the port kind shall default to variable.
In your case, the second clause applies, since you declared data as output logic[1:0], meaning that it was interpreted as a variable and not a net. Multiple values on variables aren't resolved (and in some tools are also illegal).

How do I sign extend in SystemVerilog?

Below is the code I have for my module:
module sext(input in[3:0], output out[7:0]);
always_comb
begin
if(in[3]==1'b0)
assign out = {4'b0000,in};
else
assign out = {4'b1111,in};
end
endmodule
For some reason this is not working. Instead of sign extending it is zero extending. Any ideas to why this might be the case?
I'm going to assume you meant (input [3:0] in, output [7:0] out). If that is true, then all you needed to write is
module sext(input signed [3:0] in, output signed [7:0] out);
assign out = in;
endmodule
You could also write
module sext(input [3:0] in, output [7:0] out);
assign out = 8'(signed'(in));
endmodule
And perhaps you don't even need to write this as a separate module.
Few things you need to take care is,
you haven't declared a data type for in and out, so by default they are wire and wire can't be used at LHS inside procedural block. Refer Section 6.5 Nets and variables (SV LRM 1800-2012). So either use a continuous assignment or declare it as a variable (i.e. reg/logic etc.).
The assignment of unpacked array is illegal in your example, so either use packed array or follow the instructions given in Section 10.10 Unpacked array concatenation (SV LRM 1800-2012)
It is not illegal syntax but assign used inside an always block probably does not do what you think it does. Use assign for wires and do not use it inside initial or always.
You have defined your port ranges after the name, this results in 4 and 8 1-bit arrays rather than a 4 and 8 bit value.
You have used {} for concatination, but they can also be used for replication ie {4{1'b1}}.
module sext(
input [3:0] in,
output reg [7:0] out ); //ranged defined before name
//No assign in always
//concatenation with replication
always_comb begin
out = { {4{in[3]}}, in};
end
endmodule
Or :
module sext(
input [3:0] in,
output [7:0] out ); //out left as wire
assign out = { {4{in[3]}}, in};
endmodule
I have seen your code.
There are some mistake in your code that you have to take care whiling writing the code.
You have use unpacked array so your targeted elements and actual elements are not match.
ERROR : Number of elements in target expression does not match the number of
elements in source expression.
This error can solve by using packed array.So, your targeted elements and actual elements are matched.
Here is link from where you will get better understanding regarding packed and unpacked array.
LINK : [http://www.testbench.in/SV_09_ARRAYS.html][1]
2.Another thing that you have to take care is you are storing some value in out signal(variable) like assign out = {4'b0000,in};
So you have to use reg data type to sore the value.
ERROR : Non reg type is not valid on the left hand side of this assignment
When you use reg data type then you can store value in out data type.
So, your problem is solved.
Here I also provide code which will run fine.
module sext(input [3:0]in, output reg [7:0]out);
always_comb
begin
if(in[3]==1'b0)
assign out = {4'b0000,in};
else
assign out = {4'b1111,in};
end
endmodule

Synchronous Counter

I'm trying to create a 32-bit synchronous counter using J-K flip-flops. I have a functional module for individual J-K flip-flops...
jkff(J, K, CLK, Q) where the first three are wire inputs and the last is a reg output.
I then have another functional module for the counter...
thirty_two(J, K, CLK, OUT[31:0]) where the first three are inputs and the last is output
In the thirty_two module, I instantiate many jkff modules, but I seem to be restricted to using wires as my output. Thus, OUT[31:0] is a wire instead of the desired reg I want.
Any suggestions?
A common mistake when starting out with verilog is thinking that wire & reg types have to match across hierarchy, they do not. A modules inputs are always wires and outputs can be regs or wires. Connectivity between modules are wires. The difference between usage of the two is purely down to how values are assigned or driven.
For example module thirty_two can use reg type to drive its output:
module thirty_two(
output reg [31:0] OUT
);
always #* begin
OUT = 32'bx;
end
endmodule
When instantiating thirty_two, outputs must drive wires. This make sense as the level that instantiates it can not directly change a sub modules output.
module top_level();
wire [31:0] thirty_two_out;
thirty_two thirty_two_i0 (
.OUT( thirty_two_out )
);
endmodule