I wrote a verilog code for a 4 by 9 bit register:
module reg_file(input rst,
input clk,
input wr_en,
input rd_en,
input [1:0]rd0_addr,
input [1:0]rd1_addr,
input [1:0]wr_addr,
input [8:0]wr_data,
output reg [8:0]rd0_data,
output reg [8:0]rd1_data);
reg [8:0]mem[3:0];
integer i;
always @(posedge rst or negedge clk)
begin
if (rst) begin
for (i=0; i<4; i=i+1)
mem[i]=0;
end
else if (wr_en) begin
mem[wr_addr]=wr_data;
end
else (rd_en) begin
assign rd0_data = mem[rd0_addr];
assign rd1_data = mem[rd1_addr];
end
end
endmodule
but using iverilog to check if there are any issues, it says:
26: syntax error
27: Syntax in assignment statement l-value.
30: syntax error
I can't seem to figure out why I'm getting these errors, can anyone help?
I also need to find test vectors to test every possible outcome of the register file, does anyone have any suggestions on the best way to do that?
2 Answers 2
Those numbers at the front of the error messages are line numbers. Open your verilog file in a text editor that displays line numbers, and figure out where they are.
One problem I noticed was on the line:
else (rd_en) begin
You can't have a condition after else
without another if
keyword.
else if (rd_en) begin
-
\$\begingroup\$ When I do that I get the error "Assertion failed: (number_is_immediate(rword_idx, IMM_WID, 0)), function force_link_rval, file vvp_process.c, line 1256. sh: line 1: 14947 Done /opt/local/lib/ivl/ivlpp -L -F"/tmp/ivrlg2ef8b647" -f"/tmp/ivrlgef8b647" -p"/tmp/ivrlief8b647" 14948 Abort trap: 6 | /opt/local/lib/ivl/ivl -C"/tmp/ivrlhef8b647" -C"/opt/local/lib/ivl/vvp.conf" -- - tmp/cZpPzn/a.out:61: syntax error" \$\endgroup\$dms94– dms942016年02月15日 21:03:43 +00:00Commented Feb 15, 2016 at 21:03
-
\$\begingroup\$ Doesn't mean much to me except that there is still a syntax error (perhaps in a generated file?). You could try removing almost all of the code in your file and adding it incrementally to see if the failure is related to a specific part of your code. \$\endgroup\$Justin– Justin2016年02月15日 21:07:16 +00:00Commented Feb 15, 2016 at 21:07
-
\$\begingroup\$ I did that and it was an issue with the assign statements, I took them out and it worked \$\endgroup\$dms94– dms942016年02月15日 21:13:56 +00:00Commented Feb 15, 2016 at 21:13
-
\$\begingroup\$ Do you have any suggestions on how I would make test vectors for this? \$\endgroup\$dms94– dms942016年02月15日 21:18:54 +00:00Commented Feb 15, 2016 at 21:18
-
\$\begingroup\$ Sorry, I don't really have a good answer. Please ask it as a new question to get more people looking at it. We usually try to have one real question per question so that they can be handled/answered separately. That being said, you need to add some detail about what your requirements are for the test vectors. Did your instructor just say "make some test vectors", and if so, what has he/she taught you about test vectors in class? Just some thoughts about what needs to be in a new question. \$\endgroup\$Justin– Justin2016年02月15日 21:38:47 +00:00Commented Feb 15, 2016 at 21:38
Afaics there are three problems with that verilog code.
there is a missing
if
before(rd_en)
, as @Justin pointed out.the
assign
statements within the always blocks are bogus. (There is something called procedural continuous assignments and the syntax you are using here is such a procedural continuous assignment, but it is pretty sure that you did not mean that.)you are using blocking assignments in a clocked always block, which means that this code will experience race conditions in simulation. See e.g. this paper for details. In this case assignments to the same variable are exclusive anyways, so simply changing
=
to<=
fixes this issue:module reg_file(input rst, input clk, input wr_en, input rd_en, input [1:0] rd0_addr, input [1:0] rd1_addr, input [1:0] wr_addr, input [8:0] wr_data, output reg [8:0] rd0_data, output reg [8:0] rd1_data); reg [8:0] mem [3:0]; integer i; always @(posedge rst or negedge clk) begin if (rst) begin for (i=0; i<4; i=i+1) mem[i] <= 0; end else if (wr_en) begin mem[wr_addr] <= wr_data; end else if (rd_en) begin rd0_data <= mem[rd0_addr]; rd1_data <= mem[rd1_addr]; end end endmodule
PS: Not a real issue for memories that are only 4 words deep, but for most FPGA architectures resetting of memories will inhibit instantiation of dedicated memory resources and yield a much larger synthesis result.
PPS: posedge rst or negedge clk
is very unusual (but it is still valid Verilog of course). Are you sure you don't mean posedge clk or negedge rst
?