I'm using readmemh like:
reg [11:0] rom [0:121];
initial $readmemh("x.data", rom);
My x.data file looks like:
line 1: 1
line 2: 10
.
.
.
line 118: 1110101
line 119: 1110110
line 120: 1110111
When I try to use rom[20] during the simulation, I see XXX value. Also, I have checked all rom data values during the simulation, and I saw XXX,XXX,..,XXX
I'm not sure that I used $readmemh in proper way.
When I use your code to read the file, I get warning messages with 2 different simulators. In both cases, the simulator fails to read the file and load the data into the rom variable. If I add the following code:
integer i;
initial for (i=0; i<=121; i=i+1) $displayb(rom[i]);
I see x for all locations in rom. You declared rom as a reg type, and reg types default to x.
The problem is that Line 1:, Line 2:, etc., are incorrect syntax. You need to remove them from the x.data file. Your file should look something like this:
1
10
1110101
1110110
1110111
However, I still get simulator warnings because the simulator interprets 1110101 as a hexadecimal value. Since this value is too large for the 12-bit variable, the simulator does not load it into rom, leaving the value as the default x.
My guess is that your data is really binary format instead of hex. In that case, use $readmemb instead of $readmemh:
initial $readmemb("x.data", rom);
When I make that change, I no longer see x.
Refer to IEEE Std 1800-2017, section 21.4 Loading memory array data from a file for detailed syntax.
Try using the full path to your file. Likely your simulator is not in the same directory as your file.
Related
I am having a problem with the following code which should simply throw an error at compilation
if my number of inputs is not divisible by my number of outputs.
module multiplexer #(parameter N_INPUTS, parameter N_OUTPUTS) (in, out, select);
generate
if (N_INPUTS % N_OUTPUTS != 0) begin
$error("%m ** Illegal Parameter ** NUMBER OF INPUTS(%d) does not divide into NUMBER OF OUTPUTS(%d)", N_INPUTS, N_OUTPUTS);
end
endgenerate
input wire [N_INPUTS-1:0] in;
input wire [$clog2(N_INPUTS/N_OUTPUTS) - 1:0] select;
output wire [N_OUTPUTS-1:0] out;
always # (select, in) begin
out = in[(select + 1) * N_OUTPUTS - 1:(select + 1) * N_OUTPUTS - N_OUTPUTS];
end
endmodule
But Quartus keep throwing me this error when I proceed to an Analysis:
Error (10170): Verilog HDL syntax error at multiplexer.v(5) near text: "$error"; expecting "end". 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.
I am beginning to wonder wether or not the compiler of Quartus supports the $error command (it's my first time using it).
I would greatly appreciate any help on the subject since I am still a beginner in the domain :)
Close your Quartus project and in the .qsf file, change the line pointing to your multiplexer module verilog file from:
set_global_assignment -name VERILOG_FILE multiplexer.v
To:
set_global_assignment -name SYSTEMVERILOG_FILE multiplexer.v
Edit:
Also set:
set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2009
Edit 2:
It's a SystemVerilog 2009 feature and Quartus Prime Standard and Quartus Prime Lite don't support VHDL 2008 or SystemVerilog 2009.
Quartus Prime Pro 19.4:
Quartus Prime Standard 19.1:
I found the problem...money...
If you look at the following image you'll notice that if you are poor you can't use
the latest version of SystemVerilog in the Lite and Standard version of Quartus Prime.
Well that explains it all.
If anyone as another solution to throw error at compile time that looks better than this please tell me:
generate
if (CONDITION > MAX_ALLOWED /* your condition check */ ) begin
illegal_parameter_condition_triggered_will_instantiate_an non_existing_module();
end
endgenerate
Note: this was taken from https://electronics.stackexchange.com/a/71226
I see other errors:
you are driving wire out from a procedural block (your always
block). You cannot do that, you can only drive a variable. ie out
must be a variable.
your code inside the square brackets is illegal. You will need to use
one of the +: or -: operators. See this answer here.
I am working on project in which I have to read 5 bits binary values from text file. I have to read each 5 bit binary number and then assign them to 5 different 1 bit registers one by one. Moreover i can't use 'memreadb' because my text file is so huge almost 2mb and I think 'memreadb' can't deal with such a huge file because its not working in my case. so can anyone please tell me how to use 'fopen' and 'fread' function to solve my problem because i have not work on file handling in Verilog till now. And can anyone provide me an example similar to my problem?
Thanks,
Sami
You can use $fscanf to read your file one line at a time.
integer status, fd;
reg [4:0] value;
initial begin
fd = $fopen("data_file.dat", "r");
if (!fd) $error("could not read file");
while (!$feof(fd)) begin
status = $fscanf(fd,"%b",value);
// check status, then do what you need to do with value
end
end
I searched on SO, and on web, no where found the ans.
I have following code, where It success fully parsed `define and generate expected results, but if number of times calling of macro is large then, Can we using Looping Construct?.
`define myreg(name) \
addr_``name
`define para(i) \
parameter `myreg(i) = i
module register;
`para(1);
`para(2);
`para(3);
`para(4);
initial
begin
$display("ADDR1 = %d, ADDR2 = %d", addr_1, addr_2);
$display("ADDR3 = %d, ADDR4 = %d", addr_3, addr_4);
#100 $finish;
end
endmodule
Simulation Result:
// # Loading work.register(fast)
// # run -all
// # ADDR1 = 1, ADDR2 = 2
// # ADDR3 = 3, ADDR4 = 4
// # ** Note: $finish : reg.v(18)
Now, when I use for loop, like in below code,
`define myreg(name) \
addr_``name
`define para(i) \
parameter `myreg(i) = i
module register;
genvar i;
generate
for (i = 1; i<=4; i=i+1)
begin
`para(i);
end
endgenerate
initial
begin
$display("ADDR1 = %d, ADDR2 = %d", addr_1, addr_2);
$display("ADDR3 = %d, ADDR4 = %d", addr_3, addr_4);
#100 $finish;
end
endmodule
In that case, It shows an error while displaying or using it,
Simulation Result:
// # vsim -lib work register -c -do "run -all; quit -f" -appendlog -l qverilog.log -vopt
// # ** Note: (vsim-3813) Design is being optimized due to module recompilation...
// # ** Error (suppressible): (vopt-7063) reg.v(24): Failed to find 'addr_1' in hierarchical name '/addr_1'.
// # ** Error (suppressible): (vopt-7063) reg.v(24): Failed to find 'addr_2' in hierarchical name '/addr_2'.
// # ** Error (suppressible): (vopt-7063) reg.v(25): Failed to find 'addr_3' in hierarchical name '/addr_3'.
// # ** Error (suppressible): (vopt-7063) reg.v(25): Failed to find 'addr_4' in hierarchical name '/addr_4'.
// # Optimization failed
// # Error loading design
It is asked more times but proper solution is not given by any one, any help appreciated a lot.
For any simulation, following sequence of events takes place:
Compilation Phase ==> Elaboration Phase ==> Run Phase (Simulation Phase)
At compile time, the syntax error checking and macros text substitution is performed. Memory for all the variables is calculated and an executable is build. During compile time, which a program's source code is being translated into executable code.
At elaboration time, the instances and connection between instances is formed. By connectivity, I mean checking port widths and ports existence etc. Since, the actual instances are created, parameters are also evaluated at elaboration time.
At run time, of course, the actual simulation starts running from zero time on wards.
Macros are evaluated at compile time (hence known as compiler directives), while generate block evaluates at elaboration time.
Referring to IEEE 1800-2012, Section 27.3:
Generate schemes are evaluated during elaboration of the design.
...
They are evaluated at elaboration time, and the result is determined before simulation begins. Therefore, all expressions in generate schemes shall be constant expressions, deterministic at elaboration time.
The first example runs because everything is done at compile time. All the variables are declared at compile time itself. Hence the code works fine.
In the second example, you are trying to declare variables at elaboration time which is not allowed. No more memory to variables is allocated at elaboration time.
Refer IEEE 1800-2012 section 3.12 for more information on compilation and elaboration time.
The problem is actually much simpler than as sharvil111 explains.
The directives `defines, `ifdefs and `includes all get handled by a preprocessor that produces a stream of text and is fed into a compiler. The preprocessor does not know anything about Verilog syntax and the compiler does not see any of those directives because they have been processed away.
You can actually see this intermediate stream of text by adding the vlog -E <filename> option which writes the output of the preprocessor to
There is no looping directive in Verilog/SystemVerilog. Some options for you are:
write the macros out by hand. Perhaps you can find some function in your text editor to help you do this
use some other macro preprocessor to generate your code. This can make debugging difficult as you have to manage two sets of source code files.
Restructure your code to use an array instead of having separately named parameters
I'm trying to write a top-level module in Verilog that will open a water valve whenever a sensor reads values below a certain number.
Here is my code:
module ProjectDSD(alteraClock, sensorInput, openValve);
input sensorInput, alteraClock;
output openValve;
always #(sensorInput)
begin
if(sensorInput < 100) //sensor value to irrigate at
begin
openValve <= 1; //here
end
else
begin
openValve <= 0; //here
end
end
endmodule
Im getting an error saying:
Object "openValve" on left-hand side of assignment must have a variable data type
What am I missing? Also, which pins can I use on an Altera DE2-155 board to output a digital signal of only 1's and 0's for the the valve to open/close?
s/output openValve/output reg openValve/
Outputs default to wire; you need a reg. See also this question.
openValve is currently inferred as a wire. Add reg openValve; below output openValve; and your code will work.
Suggestions: It looks like you are following the IEEE1364-1995 non-ANSI coding style. Will still legal, you might want to change to the ANSI coding style, supported in IEEE1364-2001 and above.
Non-ANSI:
module ProjectDSD(alteraClock, sensorInput, openValve);
input sensorInput, alteraClock;
output openValve;
reg openValve;
ANSI:
module ProjectDSD(
input alteraClock, sensorInput,
output reg openValve);
For combinational blocks, it is recommended to use always #* (or the synonymous always #(*)) instead of always #(sensorInput). #* is an auto sensitivity list also added in IEEE1364-2001
Try output reg openValve;.
For the second half of your question (which should really be a separate question) import this QSF file into your project. Any of the GPIO can be configured as outputs, and are accessible by the 40-pin header on the side.
Before I begin, I must preface by stating that I am a novice when it comes to FORTRAN. I am maintaining a legacy piece of code from 1978. It's purpose is to read in some data values from a file, process the values, and then output the processed values to another text file.
Given the following FORTRAN code:
INTEGER NM,STUBS,I,J,K
PARAMETER (NM=67,STUBS=43)
INTEGER*4 MDS(STUBS,NM)
CALL OPEN$A(A$RDWR,'/home/test/data.txt', MAXPATHLEN,1)
CALL OPEN$A(A$WRIT,'out',11,2)
DO 90 I=1,2
READ(1,82) STUB
!-- data processing --!
WRITE(2,80) STUB,(MDS(I,J),J=1,24)
90 CONTINUE
80 FORMAT(/1X,A24,25I5)
82 FORMAT(1X,A24,25F5,1)
My question is in regards to the WRITE() statement.
I understand that (2,80) refers to the file output stream opened and pointing to the file 'out' and referenced by the numeral 2. I understand that 80 refers to the format statement referenced by label 80.
STUB is used to store the values read from file input 1. These values are what is processed, and saved into MDS(I,J) in the !-- data processing --! section that I have omitted.
Am I correct in assuming that (MDS(I,J),J=1,24) will write 24 integer values to the output file? In other words, looping from 1 to 24?
Yes, you are correct. The syntax (MDS(I,J), J=1,24) is an "implied DO-loop" and is commonly used in situations like this.