??? 10/22/07 18:45 Read: times |
#146017 - one way vs the other way Responding to: ???'s previous message |
Russ said:
One way puts all the logic into a single always block, with a bunch of ifs inside it to sort out what to do when. The other way seems to break up the logic into little chunks and puts each chunk into its own always block. Here are a couple of do-nothing examples that show generally what I am talking about ... Tread carefully ... Russ said:
Question 1: Are these two modules equivalent? In other words, is the difference between these two styles only a matter of style, or is there some subtle difference between them that actually makes a difference in how they simulate and/or synthesize? Are the modules equivalent? Sorta. Kinda. Yes, if the code in each if block (rd, wr, reset) is independent. In other words, as long as you don't assign to a signal in more than one of the three cases. Remember the rule about never assigning to a reg in more than one always block. (A style note: I never put register write logic and the register read logic in the same always block.) Note that there's a gotcha, and it's the reset case. Be careful and make sure that you write your synchronous reset properly. For example, if you wish to write to registers, you should do always @(posedge clk) begin : regwrite if (reset) begin this <= 8'b00000000; that <= 8'b00000000; end else begin if (wr) begin this <= foo; that <= bar; end // if (wr) end // if else reset end // process regwriteIf you were to make the following mistake: always @(posedge clk) begin : badregwrite if (reset) begin this <= 8'b00000000; that <= 8'b00000000; end // if (reset) if (wr) begin this <= foo; that <= bar; end // if (wr) end // process badregwritethen you've got an issue and the tools may not create a proper sync reset. Sync reset should have precedence over register write. What happens in the instance when both reset and wr are asserted? Anyways, there is a school of thought that says that all synchronous assignments in a module should be done in one big always block. I don't agree with that, as it makes maintenance difficult. Russ said:
In the second example, what's with the labels (write, read, and misc) on the always statements? They don't seem to be referenced anywhere, so I'm wondering if they actually do anything that a simple comment wouldn't. Named blocks have several uses. One, it's a documentation convenience. More important, naming a block (which does not have to be an always or initial block, it can be anything with begin/end) creates a local scope in which you can create local variables. You can also disable a named block (useful in simulation, not available in synthesis), which causes execution of the block to terminate. This is really useful for fork/join blocks (which don't have an equivalent in VHDL). FWIW, I always (pardon the pun) give my always and initial blocks labels as I think that a useful block label makes for good documentation. It's also useful to label a sub-block within an always block, again for documentation reasons (like in your example). -a |