moduletop_module(input[2:0]in,output[1:0]out);// This is a function of 3 inputs. One method is to use a 8-entry truth table:// in[2:0] out[1:0]// 000 00// 001 01// 010 01// 011 10// 100 01// 101 10// 110 10// 111 11assignout[0]=(~in[2]&~in[1]&in[0])|(~in[2]&in[1]&~in[0])|(in[2]&~in[1]&~in[0])|(in[2]&in[1]&in[0]);assignout[1]=(in[1]&in[0])|(in[2]&in[0])|(in[2]&in[1]);// Using the addition operator works too:assignout=in[0]+in[1]+in[2];// Yet another method uses behavioural code inside a procedure (combinational always block)// to directly implement the truth table:always@(*)begincase(in)3'd0:out=2'd0;3'd1:out=2'd1;3'd2:out=2'd1;3'd3:out=2'd2;3'd4:out=2'd1;3'd5:out=2'd2;3'd6:out=2'd2;3'd7:out=2'd3;endcaseendendmodule
You are given a four-bit input vector in[3:0]. We want to know some relationships between each bit and its neighbour:
out_both: Each bit of this output vector should indicate whether both the corresponding input bit and its neighbour to the left (higher index) are '1'. For example, out_both[2] should indicate if in[2] and in[3] are both 1. Since in[3] has no neighbour to the left, the answer is obvious so we don't need to know out_both[3].
out_any: Each bit of this output vector should indicate whether any of the corresponding input bit and its neighbour to the right are '1'. For example, out_any[2] should indicate if either in[2] or in[1] are 1. Since in[0] has no neighbour to the right, the answer is obvious so we don't need to know out_any[0].
out_different: Each bit of this output vector should indicate whether the corresponding input bit is different from its neighbour to the left. For example, out_different[2] should indicate if in[2] is different from in[3]. For this part, treat the vector as wrapping around, so in[3]'s neighbour to the left is in[0].
Verilog
1 2 3 4 5 6 7 8 910111213141516171819202122232425
moduletop_module(input[3:0]in,output[2:0]out_both,output[3:1]out_any,output[3:0]out_different);// Use bitwise operators and part-select to do the entire calculation in one line of code// in[3:1] is this vector: in[3] in[2] in[1]// in[2:0] is this vector: in[2] in[1] in[0]// Bitwise-OR produces a 3 bit vector. | | |// Assign this 3-bit result to out_any[3:1]: o_a[3] o_a[2] o_a[1]// Thus, each output bit is the OR of the input bit and its neighbour to the right:// e.g., out_any[1] = in[1] | in[0]; // Notice how this works even for long vectors.assignout_any=in[3:1]|in[2:0];assignout_both=in[2:0]&in[3:1];// XOR 'in' with a vector that is 'in' rotated to the right by 1 position: {in[0], in[3:1]}// The rotation is accomplished by using part selects[] and the concatenation operator{}.assignout_different=in^{in[0],in[3:1]};endmodule
Create a 4-bit wide, 256-to-1 multiplexer. The 256 4-bit inputs are all packed into a single 1024-bit input vector. sel=0 should select bits in[3:0], sel=1 selects bits in[7:4], sel=2 selects bits in[11:8], etc.
Hints:
- With this many options, a case statement isn't so useful.
- Vector indices can be variable, as long as the synthesizer can figure out that the width of the bits being selected is constant. It's not always good at this. An error saying "... is not a constant" means it couldn't prove that the select width is constant. In particular, in[ sel4+3 : sel4 ] does not work.
- Bit slicing ("Indexed vector part select", since Verilog-2001) has an even more compact syntax.
Verilog
1 2 3 4 5 6 7 8 910111213141516
moduletop_module(input[1023:0]in,input[7:0]sel,output[3:0]out);// We can't part-select multiple bits without an error, but we can select one bit at a time,// four times, then concatenate them together.assignout={in[sel*4+3],in[sel*4+2],in[sel*4+1],in[sel*4+0]};// Alternatively, "indexed vector part select" works better, but has an unfamiliar syntax:assignout=in[sel*4+:4];// Select starting at index "sel*4", then select a total width of 4 bits with increasing (+:) index number.assignout=in[sel*4+3-:4];// Select starting at index "sel*4+3", then select a total width of 4 bits with decreasing (-:) index number.// Note: The width (4 in this case) must be constant.endmodule