1
\$\begingroup\$

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?

asked Feb 15, 2016 at 20:55
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

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
answered Feb 15, 2016 at 21:01
\$\endgroup\$
5
  • \$\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\$ Commented 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\$ Commented 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\$ Commented Feb 15, 2016 at 21:13
  • \$\begingroup\$ Do you have any suggestions on how I would make test vectors for this? \$\endgroup\$ Commented 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\$ Commented Feb 15, 2016 at 21:38
1
\$\begingroup\$

Afaics there are three problems with that verilog code.

  1. there is a missing if before (rd_en), as @Justin pointed out.

  2. 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.)

  3. 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?

answered Feb 16, 2016 at 7:22
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.