Unable to compile Micron's DDR3 memory model in Modelsim - verilog

I downloaded the memory model for the DDR3 bank that I'd be testing in simulation using Modelsim (2019.2) from Micron's website (link).
I followed the instructions from the README file to compile it but I run into syntax errors! I don't think Micron would make bug-gy code public and available to developers.
Modelsim command:
vlog +define+sg25 C:/Micro_projects/FPGA/hdl/micron/ddr3/ddr3.v
ERRORS
# ** Error: (vlog-13069) C:/Micro_projects/FPGA/hdl/micron/ddr3/ddr3.v(421): near ";": syntax error, unexpected ';', expecting '('.
# ** Error: C:/Micro_projects/FPGA/hdl/micron/ddr3/ddr3.v(424): Illegal declaration after the statement near line '421'. Declarations must precede statements. Look for stray semicolons.
# ** Error: (vlog-13069) C:/Micro_projects/FPGA/hdl/micron/ddr3/ddr3.v(433): near "integer": syntax error, unexpected integer, expecting IDENTIFIER or genvar.
# ** Error: C:/Micro_projects/FPGA/hdl/micron/ddr3/ddr3.v(433): (vlog-13205) Syntax error found in the scope following 'i'. Is there a missing '::'?
initial
begin : file_io_open
reg [BA_BITS - 1 : 0] bank;
reg [ROW_BITS - 1 : 0] row;
reg [COL_BITS - 1 : 0] col;
reg [BA_BITS + ROW_BITS + COL_BITS - 1 : 0] addr;
reg [BL_MAX * DQ_BITS - 1 : 0] data;
string _char; //LINE 421
integer in, fio_status;
if (!$value$plusargs("model_data+%s", tmp_model_dir))
begin
tmp_model_dir = "/tmp";
$display(
"%m: at time %t WARNING: no +model_data option specified, using /tmp.",
$time
);
end
for (integer i = 0; i < `BANKS; i = i + 1)
memfd[i] = open_bank_file(i);
I hope someone can suggest me how to proceed with it. I have contacted Micron but haven't heard from them yet (it has been a few days). I am stuck and any comments are appreciated!
Thank you,
Surabhi

The error is from the line which includes string, which is a SystemVerilog keyword.
You need to enable SystemVerilog syntax using the modelsim -sv option.

Related

Unexpected ";" , expecting ")" near class handle

So, I created my first system Verilog testbench by modifying the tutorial from https://verificationguide.com/systemverilog-examples/systemverilog-testbench-example-01/ ( In this tutorial a memory block is tested, I modified it for a simple AND gate).
There are seven files excluding the DUT file,
environment.sv
interface.sv
transactions.sv
generator.sv
testbench.sv ( topLevel testbench)
driver.sv
test.sv
I used Intel modelsim to compile these files.
While compiling, I got these errors in driver.sv and generator.sv
** Error: (vlog-13069) D:/Altera/Projects/AndGate/testbench/driver.sv(28): near ";": syntax error, unexpected ';', expecting '('.
** Error: (vlog-13069) D:/Altera/Projects/AndGate/testbench/generator.sv(4): near "trans": syntax error, unexpected IDENTIFIER, expecting ';' or ','.
Below are the corresponding files,
driver.sv
`define DRIV_IF mem_vif.DRIVER.driver_cb
class driver;
int num_trans;
virtual mem_intf mem_vif;
mailbox gen2driv;
function new(virtual mem_intf mem_vif, mailbox gen2driv);
this.mem_vif = mem_vif;
this.gen2driv = gen2driv;
endfunction
task reset();
wait(mem_vif.reset);
$display("--------- [DRIVER] Reset Started ---------");
`DRIV_IF.A <= 0;
`DRIV_IF.B <= 0;
`DRIV_IF.C <= 0;
wait(!mem_vif.reset);
$display("--------- [DRIVER] Reset Ended ---------");
endtask
task drive();
transaction trans;
gen2driv.get(trans);
$display("Num transactions : %0d", num_trans);
#(posedge mem_vif.DRIVER.clk);
`DRIV_IF.A <= trans.A;
`DRIV_IF.B <= trans.B;
trans.C = `DRIV_IF.C;
$display("\tA = %0h \tB = %0h \tC = %0h", trans.A, trans.B, `DRIV_IF.C);
num_trans++;
endtask
endclass
generator.sv
class generator;
var rand transaction trans;
mailbox gen2driv;
int repeat_count;
event ended;
function new(mailbox gen2driv, event ended);
this.gen2driv = gen2driv;
this.ended = ended;
endfunction
task main();
repeat(repeat_count) begin
trans = new();
if(!trans.randomize())$fatal("Random Generation failed");
gen2driv.put(trans);
end
-> ended;
endtask
endclass
Please, help me with this...
For future reference, it would really help to point to the line 28 and 4 in the respective files where the error is occurring as well as give the command line used to compile the code. But since I've seen this exact error before, I know it is because you put all of these files separately on your command line and not compiled together as a package.
Modelsim/Questa compiles every SystemVerilog file on the command line as a separate compilation unit. Identifiers declared in one compilation unit cannot be seen by other compilation units. When the generator and driver classes get compiled, it has no idea what transaction means and you get a syntax error. Modules and interfaces names exist in a separate namespace and the syntax where they are referenced allows them to used before their declarations have been compiled.
To remedy this, you could `include all you class files in testbench module, or the normal practice is putting them all in a package and importing the package. There is also a compilation mode where everything on the command line in one compilation unit, but that option is not scaleable as your designer get larger.
I also suggest reading these two posts I wrote:
https://blogs.sw.siemens.com/verificationhorizons/2010/07/13/package-import-versus-include/
https://blogs.sw.siemens.com/verificationhorizons/2009/05/07/programblocks/

keep getting these error messages..compile error

This is my code. But when I compile this, I got error messages.
What's wrong with my code?
// seg7dec.v
module seg7dec (
input [3:0] val,
output reg [6:0] seg // from MSB A, B, C, D, E, F, G
);
always #(*)
begin
case (val[3:0])
4'h0: seg[6:0] = 7'b111_1110;
4'h1: seg[6:0] = 7'b011_0000;
4'h2: seg[6;0] = 7'b110_1101;
4'h3: seg[6;0] = 7'b111_1001;
4'h4: seg[6;0] = 7'b011_0011;
4'h5: seg[6;0] = 7'b101_1011;
4'h6: seg[6;0] = 7'b101_1111;
4'h7: seg[6;0] = 7'b111_0000;
4'h8: seg[6;0] = 7'b111_1111;
4'h9: seg[6;0] = 7'b111_1011;
4'ha: seg[6;0] = 7'b111_1101;
4'hb: seg[6;0] = 7'b001_1111;
4'hc: seg[6;0] = 7'b100_1110;
4'hd: seg[6;0] = 7'b100_1111;
4'hg: seg[6;0] = 7'b111_1011;
default: seg[6:0] = 7'b100_0111 ; // 4'hF
endcase
end
endmodule
These are the error messages:
;'.
** Error: (vlog-13069) C:/Intel/seg7dec.v(14): near ";": syntax error, unexpected ';'.
** Error: (vlog-13069) C:/Intel/seg7dec.v(15): near ";": syntax error, unexpected ';'.
** Error: (vlog-13069) C:/Intel/seg7dec.v(16): near ";": syntax error, unexpected ';'.
** Error: (vlog-13069) C:/Intel/seg7dec.v(17): near ";": syntax error, unexpected ';'.
** Error: (vlog-13069) C:/Intel/seg7dec.v(18): near ";": syntax error, unexpected ';'.
** Error: (vlog-13069) C:/Intel/seg7dec.v(19): near ";": syntax error, unexpected ';'.
** Error: (vlog-13069) C:/Intel/seg7dec.v(20): near ";": syntax error, unexpected ';'.
** Error: (vlog-13069) C:/Intel/seg7dec.v(21): near ";": syntax error, unexpected ';'.
** Error: (vlog-13069) C:/Intel/seg7dec.v(22): near ";": syntax error, unexpected ';'.
** Error: (vlog-13057) C:/Intel/seg7dec.v(23): Expecting numeric digits.
** Error: (vlog-13069) C:/Intel/seg7dec.v(23): near "g": syntax error, unexpected IDENTIFIER, expecting ':'.
From the line
4'h2: seg[6;0] = 7'b110_1101;
You have added ; instead of : between 6 and 0.
When using partial select, the format should be [MSB:LSB].
So you need to change seg[6;0] to seg[6:0].
Or, since seg is declared as 7-bit wide, it's not necessary to add [6:0] to seg.
The last 4'hg should be 4'he.

verilog ; can't use "string" type in $display

I'm using a recent master branch build of icarus verilog.
Should I expect the following to run?
module string_display ();
//reg [10:0][7:0] x = "initial";
string x = "initial";
always #* begin
$display ("x = %s",x);
end
initial begin
// Assign new string
x = "aaaaa";
#1
// Assign new string
x = "bbbb";
#1
#1 $finish;
end
endmodule
The above gives
internal error: 18vvp_fun_anyedge_sa: recv_string(initial) not implemented
vvp: vvp_net.cc:2972: virtual void vvp_net_fun_t::recv_string(vvp_net_ptr_t, const string&, vvp_context_t): Assertion `0' failed.
However, if I define 'x' as a reg by uncommenting the line above then it works as expected ...
x = aaaaa
x = bbbb
The error message tells you exactly what's wrong: "not implemented". That means it recognizes what you want to do, but it has not been implemented yet.
No, you should not expect Icarus Verilog to support the string keyword, which was introduced in the IEEE Std 1800 for SystemVerilog.
According to the Icarus website:
The compiler proper is intended to parse and elaborate design
descriptions written to the IEEE standard IEEE Std 1364-2005. This is
a fairly large and complex standard, so it will take some time to fill
all the dark alleys of the standard, but that's the goal.
There is no mention of IEEE Std 1800.
You can look at the extensions.txt file from the github site, which states:
Icarus Verilog supports certain extensions to the baseline IEEE1364
standard. Some of these are picked from extended variants of the
language, such as SystemVerilog, ...
But, there is no mention of string there.
I tried your code with the -g2012 option on edaplayground, but I get the same error. You could try it on your version.
I just tried something similar, and it worked for me:
module testit;
integer code;
string str;
string word_0;
string word_1;
string word_2;
string word_3;
string word_4;
integer file;
initial begin
//file = $fopenr(" ../../testcase/testcase_4x4.txt");
str = "this is a test... 1, 2, 3";
code = $sscanf(str, "%s %s %s %s %s",
word_0, word_1, word_2, word_3, word_4);
$display("Number of words: %0d", code);
$display("words[0]:(%-0s)", word_0);
$display("words[1]:(%-0s)", word_1);
$display("words[2]:(%-0s)", word_2);
$display("words[3]:(%-0s)", word_3);
$display("words[4]:(%-0s)", word_4);
end
endmodule
Icarus Verilog Run Command:
iverilog -g2012 .\testit.sv
vvp -i a.out
Output:
Number of words: 5
words[0]:(this)
words[1]:(is)
words[2]:(a)
words[3]:(test...)
words[4]:(1,)
Icarus Verilog Version:
PS> iverilog -v
Icarus Verilog version 11.0 (devel) (s20150603-612-ga9388a89)

verilog testbench - submodule array writing in a file

I need to write an array in a file in verilog test bench. the array is declared as below in the module stage1.v (hierarchy picture attached)
wire [WIDTH-1:0] s1_res1_arr[0:LENGTH-1];
it is filled with certain values.
in my testbench i am writing like this
write_file = $fopen("stage1.txt");
for ( i = 0 ; i <= 255 ; i = i+1 )
$fwrite(write_file,"%b \n",FFT_top/stage1/s1_res1_arr[i]);
modelsim is giving the following error
Failed to find 'FFT_top' in hierarchical name '/FFT_top'.
Failed to find 'stage1' in hierarchical name '/stage1'.
Failed to find 's1_res1_arr' in hierarchical name '/s1_res1_arr'.
Okay, I found it myself. It will be done as:
$fwrite(write_file1,"%b \n",uut.FFT_top.stage_1.s1_res1_arr[i]);

Sign of expression in Verilog

Here is a small bit of Verilog code. I would expect it to return three identical results, all 8-bit representations of -1.
module trivial;
reg we;
reg [7:0] c;
initial
begin
c = 8'd3;
we = 1'b1;
$display ("res(we) = %d", (we ? (-$signed(c)) / 8'sd2 : 8'd0));
$display ("res(1) = %d", (1'b1 ? (-$signed(c)) / 8'sd2 : 8'd0));
$display ("res = %d", (-$signed(c)) / 8'sd2);
end
endmodule
Briefly, the version of the standard I have (1364-2001) says in section 4.1.5 that division rounds towards zero, so -3/2=-1. It also says in section 4.5 that operator sign only depends on the operands (edit: but only for "self determined expressions"; turns out it's necessary to read the part of the standard on signs together with the part on widths). So the sub-expression with the division should presumably be unaffected by the context it is used in, and similarly for the sub-expression involving $signed. So the results should all be the same?
Three different simulators disagree with me. And only two of them agree with each other. The apparent cause is that unsigned division is used instead of the signed division that I would expect. (-3=253, and 253/2=126.5)
Can someone please tell me if any of the simulators are right and why? (see below) I clearly must be missing something, but what please? Many thanks. edit: see above for what I was missing. I now think there is a bug in Icarus and the other two simulators are right
NB: the unused value in the ternary choice does not seem to make any difference, whether signed or unsigned. edit: this is incorrect, perhaps I forgot to save the modified test before retrying with signed numbers
Altera edition of Modelsim:
$ vsim work.trivial -do 'run -all'
Reading C:/altera/12.1/modelsim_ase/tcl/vsim/pref.tcl
# 10.1b
# vsim -do {run -all} work.trivial
# Loading work.trivial
# run -all
# res(we) = 126
# res(1) = 126
# res = -1
GPL Cver
GPLCVER_2.12a of 05/16/07 (Cygwin32).
Copyright (c) 1991-2007 Pragmatic C Software Corp.
All Rights reserved. Licensed under the GNU General Public License (GPL).
See the 'COPYING' file for details. NO WARRANTY provided.
Today is Mon Jan 21 18:49:05 2013.
Compiling source file "trivial.v"
Highest level modules:
trivial
res(we) = 126
res(1) = 126
res = -1
Icarus Verilog 0.9.6
$ iverilog.exe trivial.v && vvp a.out
res(we) = 126
res(1) = -1
res = -1
NCSIM gives:
res(we) = 126
res(1) = 126
res = -1
But if all inputs to the mux are signed I get:
$display ("res(we) = %d", (we ? (-$signed(c)) / 8'sd2 : 8'sd0)); //last argument now signed
$display ("res(1) = %d", (1'b1 ? (-$signed(c)) / 8'sd2 : 8'sd0));
$display ("res = %d", (-$signed(c)) / 8'sd2);
res(we) = -1
res(1) = -1
res = -1
Remembering if we do any arithmetic with an unsigned number the arithmetic is done as unsigned, the same happens when using bit selects:
reg signed [7:0] c;
c = c[7:0] + 7'sd1; //<-- this is unsigned
In the example the mux is part of a single line expression, I assume this is logically flattened for optimisation and therefore the signed/unsigned of all arguments is taken into consideration.

Resources