ELEC3500 Sample Problems II
Short Answer
Take a high level description and convert it into a gate level description which is typically implemented in an FPGA or custom chip (ASIC).
Allows you to (a) textually describe circuits at a number of different levels (b) easily simulate parallel components and circuit timing.
Standard programming languages normally do not have all the build in hooks to handle hardware operating in parallel and the associated timing properties of hardware (i.e. it is much more difficult than using Verilog or VHDL)
A C compiler targets a single hardware configuration (i.e. the processor your running the code on) and is therefore typically very efficient. A synthesizer has to target a possibly infinite number of hardware configurations (i.e. the number of registers, ALUs, counters, etc. is only constrained by the amount of hardware you have available).
A module/subroutine can be called by another module/subroute and can pass signals/variables and form a hierarchical program structure. Unlike a subroutine, different versions of a module (instances) can exist and run at the same time.
It is the highest level module and is normally not synthesized (i.e. converted into hardware). It generates all signals and timing to feed into the circuits and controls the simulation of the circuits.
The highest level module is the test bench which controls the overall simulation of the circuit (it is not synthesized into hardware). Below the test bench is the top circuit module which contains all the I/Os of the circuit and usually collects all the lower level modules (e.g. the top circuit module for a microprocessor might collect modules like ALU, instruction_ram, data_ram, interrupt controller, etc.). Below the top modules are the other modules which may have their own hierarchy (e.g. an ALU module might have submodules register, adder, incrementer, etc. and adder might have a submodule one_bit_adder).
wire - synthesize into a wire (i.e. a simple connection in the circuit)
reg - may synthesize into a latch, flip-flip, or wire
integer - normally does not get synthesized
(27 && 3) ans: 1
5'b11001 ^ 5'b01101 ans: 5'b10100
& 3'b101 ans: 0
Main advantage - easier to code (i.e. don't have to worry about lower level gates can use stagements like if-then-else, case, etc.)
Main disadvantage - More difficult to synthesize. May use more hardware then necessary and harware is expensive.
Yes. This is one of the strengths of a hardware description languate like Verilog. It allows you to combine easily written procedural code with hardware efficient structural code which can all be simulated in parrallel and synthesized. It's like a C compiler that allows embedded assembly code modules.
always @(x)
begin
Q=4'b0000;
If (clk) Q[x] = 1;
end
This would synthesize into combinations logic. All Q[i]'s are calculated in one entry (i.e. three are set to 0 and the forth (active one selected by x) is set to 1 every time there is a change in x). There is no need to remember the Q's therefore not latches or flip-flops.
delay , edge-triggered event, and wait.
A delay if of the form # <delay> <event> . The simulator will wait <delay> time units before a scheduled event takes place (e.g. q = #5 x&y waits 5 time units before any change on q).
Initial procedure starts operating at time t=0 and continues until told to stop (i.e. last event occurs).
Always procedure runs all the time. When it finishes it starts again.
It makes it easier to code. Once the timing is defined it doesn't have to change. We can modify the functionality (e.g. case statement) without affecting the timing.
They normally use flip-flops. Latches would allow the state variable to cycle right through the FSM when in transparent mode (i.e. the FSM wouldn't work).
always @(posedge clk or negedge reset_N);
begin
if(!reset_N) state = s0;
else
state = nxt_st;
end
reg [3:0] q;
always @(posedge clk or negedge reset_N);
begin
if (!reset_N) q = 0;
else
q = q << 1;
q[0] = q[3];
end
This is a four bit shift register that feeds it's output back to it's input. The problem is that it uses feedback and blocking assignment operators. q[0] will be set to the new value of q[3] not the old value and therefore the shift register will not operate correctly.
always @ (state or a or b or c);
begin
a = b | (c & d);
b = d | c;
end
The problem is that d is not in the trigger list. The value of d could change and you would not see a change in the outputs until a, b, or c changed.
A second problem is that a variable on the left side of the equal sign (a, b) cannot appear in the trigger list. The machine may go into a infinite zero-delay loop.
module infer(q,d,c);
input d,c;
output q;
always @(c or d);
if (c == 1) q <= d;
endmodule
This would infer a latch. If c or d changes and the value of c is 0 the q output has to remember the old value (i.e. it needs a storage element). Since the trigger is level sensitive (i.e. no posedge or negedge) the storage element will be a latch.
Make sure all possible cases are defined or include a default case.
always @(posedge clk or negedge reset_N);
begin
if (!reset_N) q <= 0;
else
q <= d;
end
It is asynchrouous because if reset changes from high to low (negedge) it will trigger the always proceedure and reset the flip-flop irrespective of the value of clock (i.e. it doesn't need a change on the clock signal to reset the flip-flop).
reg [2:0] onereg, tworeg;
always @(posedge clk or negedge reset_N);
begin
if (!reset_N) onereg <= 0;
else
begin
onereg <= ounreg + 1;
tworeg <= & onereg;
end
end
It can be rewritten to eliminate the flip-flops in tworeg since then can be directly generated from onereg and some combinational logic.
reg [2:0] onereg, tworeg;
always @(posedge clk or negedge reset_N);
begin
if (!reset_N) onereg <= 0;
else
begin
onereg <= ounreg + 1;
end
end
assign tworeg = & onereg;
note: even though tworeg is defined as a Verilog register it with be synthesized into combinational logic as it doesn't have to remember it value (i.e. its value is continually updated using the assign statement).
Multiple assignments mean that we have two outputs connected together (e.g. two separate procedures set the value of the same register). This will not function correctly as the synthesizer will not allow two outputs to be connect (would destory your chip). Even if the outputs never have the situation that they are driving opposite signal levels the compiler will not be smart enough to realize this.
Verilog registers are always treated as non-negative integers.
The casex statement is like a regular case statement with the additional feature of being able to handle unknown or don't care values. The advantage is that it allows you to write more compact code. Case 8'b1xxxxxxx specifies 128 of the 256 possible states.