Can someone please tell me what is the meaning of "= |" in these Verilog lines:
wire result;
wire [NUM_BITS-1:0] pterms;
assign result = | pterms;
If it means assign result = result | pterms, then does this mean that it does an OR operation between the result wire and pterms[0]?
No, in your code, | is the reduction-OR operator which does a bitwise OR of all the bits of pterms and assigns the 1-bit result to the result wire. Refer to IEEE Std 1800-2017, section 11.4.9 Reduction operators.
If pterms is 4 bits, then the assignment is the same as:
assign result = pterms[3] | pterms[2] | pterms[1] | pterms[0];
Here is a running example:
module tb;
parameter NUM_BITS = 4;
wire result;
logic [NUM_BITS-1:0] pterms;
assign result = | pterms;
initial begin
for (int i=0; i<16; i++) begin
#1 pterms = i;
#1 $displayb(pterms,,result);
end
end
endmodule
Displays:
0000 0
0001 1
0010 1
0011 1
0100 1
0101 1
0110 1
0111 1
1000 1
1001 1
1010 1
1011 1
1100 1
1101 1
1110 1
1111 1
Related
I have a design module (a partially implemented seven segment display) with a case statement as shown below. However, it looks as if, if a case statement is not catered for a bcd value the previously assigned segment value is returned as the segment value for the bcd value which is not catered for in the switch statement.
Why is it behaving that way? Assuming I don't want to use a default statement.
I printed out the values of the bcd, segment and the expectedOutput and I observed what I just wrote above.
module seven_segment_display(output logic[6:0] segment, input logic[3:0] bcd);
always#(*)
begin
case (bcd)
4'b0011 : begin segment = 7'b1011011; end
4'b1000 : begin segment = 7'b1111011; end
4'b1010 : begin segment = 7'b0000000; end
4'b0000 : begin segment = 7'b1111110; end
endcase
end
endmodule
bcd segment expectedOutput
0000 1111110 1111110
0001 1111110 0110000
0010 1111110 1101101
0011 1011011 1111001
0100 1011011 0110011
0101 1011011 1011011
0110 1011011 1011111
0111 1011011 1110000
1000 1111011 1111111
1001 1111011 1111011
1010 0000000 0000000
1011 0000000 0000000
1100 0000000 0000000
1101 0000000 0000000
1110 0000000 0000000
1111 0000000 0000000
segment is a variable. Like in any other (software) language, variables remember their value until you overwrite their value with some other value.
Your first input (bcd) is 4'b0000. There is a branch of the case statement that matches that value and so the value of 7'b1111110 is assigned to the variable segment. Then you change the value of bcd to 4'b0001. There is no branch that matches that value, so no new value is assigned to the variable segment. So, it retains it's old value.
I am a bit lost on understanding the implementation of a specific command.
In this example, there is a command passed 0x00c6ba23 which is 0000 0000 1100 0110 1011 1010 0010 0011 in binary
I am attempting to find the ALU control unit’s inputs for this instruction.
From this I can see
opcode = 0100011
imm[4:0] = 10100
funct3 = 011 (incorrect...)
rs1 = 01101
rs2 = 01100
imm[11:5] = 0000000
I am using this image to decode it
My question is how do I get the ALU control bits and ALUOp control bits for this function? And why is the function SD, even though the funct 3 is showing 011 instead of 111?
... why is the function SD, even though the funct 3 is showing 011 instead of 111?
011 is correct. The funct3 bits must be 011 in order for this to be an SD instruction. According to page 105 of https://content.riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf the SD instruction has the format:
| imm[11:5] | rs2 | rs1 | 011 | imm[4:0] | 0100011 |
If the funct3 bits were 111 then this instruction would not be SD.
... how do I get the ALU control bits and ALUOp control bits for this function?
Since this is an SD instruction, you can read those bits straight out of the SD line of the lower table in the diagram that you referenced in your question.
I wrote the following test for my code:
module HalfAdder_Test;
wire sum;
wire carry;
reg a = 0;
reg b = 0;
initial begin
$dumpfile("test.vcd");
$dumpvars(0, HalfAdder_Test);
# 10 a = 0;
# 10 b = 0;
# 30 a = 1;
# 30 b = 0;
# 50 a = 0;
# 50 b = 1;
# 70 a = 1;
# 70 b = 1;
# 90 $stop;
end
HalfAdder ha (a, b, sum, carry);
endmodule
I then compile it and open it in GTKWave using the following commands:
iverilog -o HalfAdder -c files.txt
vvp HalfAdder -lxt2
gtkwave output.vcd
When I do that, I get the following output though:
The problem is that my signals aren't going high even when they do in the simulation. What could be causing my simulation to not output?
When I open my .vcd file, I get the following output:
1380 0001 4000 0000 0800 0000 9a00 0000
1400 0000 4400 0000 3800 0000 2300 1f8b
0800 0000 0000 020b 6360 f048 cc49 734c
4949 2d8a 0f49 2d2e d14b 6460 e04f 02e2
e4c4 a2a2 4a20 5d5c 9a0b 2433 12f5 1c19
1884 9c80 d819 8883 1900 93ef 3630 3800
0000 1f8b 0800 0000 0000 020b 6360 a02a
e000 6246 343e 131a 9f19 990f 003c 2732
3f80 0000 0000 0000 6a00 0000 5800 0000
0000 0000 0000 0000 0000 0000 fa1f 8b08
0000 0000 0000 0b62 6065 4005 4650 ba09
4a6f 81d2 bf00 0000 00ff ff62 6460 6462
6604 0000 00ff ff62 6062 6262 0043 2000
0000 00ff ff62 0400 0000 ffff 83ca 8943
694e 282d 08a5 e5a1 3408 b000 003e bbb2
446a 0000 0000 0000 2900 0000 3f00 0000
0000 0001 9a00 0000 0000 0001 9a1f 8b08
0000 0000 0000 0b62 6064 0003 c659 0000
0000 ffff 0233 1801 0000 00ff ff02 0206
0000 0000 ffff 6204 0000 00ff ff83 08c1
6930 1b00 c899 14b8 2900 0000
module tb_top
(
top_clk,
top_rst
);
input top_clk;
input top_rst;
reg thirty;
reg twenty;
reg [31:0]SHOW_CLK;
always #( posedge top_clk or negedge top_rst)
begin
if (top_rst==1'b0)
begin
SHOW_CLK <= 32'h0;
twenty <= 1'h0;
thirty <= 1'h0;
end
else
begin
SHOW_CLK <= (SHOW_CLK+32'h1);
twenty <= 1'h0;
thirty <= 1'h0;
if ((SHOW_CLK==32'h14))
begin
twenty <= 1'h1;
end
if ((SHOW_CLK==32'h1e))
begin
thirty <= 1'h1;
end
end
end
endmodule
this is what a vcd file looks like, they vary by tool as to what the shortcut name is (D is SHOW_CLK in this case)
$scope module tb_top0 $end
$var wire 32 D SHOW_CLK $end
$var wire 1 B thirty $end
$var wire 1 E top_rst $end
$var wire 1 C twenty $end
$enddefinitions $end
#0
b00000000000000000000000000000000 D
0B
0E
0C
#20
b00000000000000000000000000000001 D
1E
#22
b00000000000000000000000000000010 D
#24
b00000000000000000000000000000011 D
#26
b00000000000000000000000000000100 D
#28
b00000000000000000000000000000101 D
#30
b00000000000000000000000000000110 D
#32
b00000000000000000000000000000111 D
#34
b00000000000000000000000000001000 D
#36
b00000000000000000000000000001001 D
#38
b00000000000000000000000000001010 D
#40
b00000000000000000000000000001011 D
#42
b00000000000000000000000000001100 D
#44
b00000000000000000000000000001101 D
#46
b00000000000000000000000000001110 D
#48
b00000000000000000000000000001111 D
#50
b00000000000000000000000000010000 D
#52
b00000000000000000000000000010001 D
#54
b00000000000000000000000000010010 D
#56
b00000000000000000000000000010011 D
#58
b00000000000000000000000000010100 D
#60
b00000000000000000000000000010101 D
1C
#62
b00000000000000000000000000010110 D
0C
#64
b00000000000000000000000000010111 D
#66
b00000000000000000000000000011000 D
#68
b00000000000000000000000000011001 D
#70
b00000000000000000000000000011010 D
#72
b00000000000000000000000000011011 D
#74
b00000000000000000000000000011100 D
#76
b00000000000000000000000000011101 D
#78
b00000000000000000000000000011110 D
#80
b00000000000000000000000000011111 D
1B
#82
b00000000000000000000000000100000 D
0B
#84
b00000000000000000000000000100001 D
#86
b00000000000000000000000000100010 D
#88
b00000000000000000000000000100011 D
#90
b00000000000000000000000000100100 D
#92
b00000000000000000000000000100101 D
#94
b00000000000000000000000000100110 D
#96
b00000000000000000000000000100111 D
#98
b00000000000000000000000000101000 D
If you get to the end of definitions and maybe a #0 but no clocked data that could mean that your design didnt actually change state for any of the selected signals (which could be because of your design or because you didnt run the sim long enough).
VCD is an ascii file format so independent of your recent success you should try to figure out how to fiew text files (same text editor you use
to edit your verilog for example).
The problem was with the time scale in viewing the simulation.
I want to design an ALU to perform some operations on two 8bits register ( A , B ) and in order to detect carry_out, I defined a 9bits register as temp and put the results of operation on A,b in that register.
The MSb of that temp register is used as carry out.
Here is a part of my code:
module ALU(input signed [7:0] A, input [7:0] B, input carry_in, input [2:0] acode, output reg [7:0] R, output zero, output reg carry_out);
reg [8:0] temp;
reg [15:0] temp2;
always #(A, B, acode) begin
case(is_shift)
1'b0: begin
case(acode)
3'b000: temp = A + B;
3'b010: temp = A - B;
endcase
R = temp[7:0];
carry_out = temp[8];
Given A = 11100101 and B = 11000111, here is the log:
//addition
A: 11100101 , B: 11000111
acode: 000
R: 10101100
zero: 0, carry_out: 1
//subtraction
A: 11100101 , B: 11000111
acode: 010
R: 00011110
zero: 0, carry_out: 0
In both cases, the 9th bit of temp should be 1 and it's right in the addition case but in the subtraction case, the subtraction is right but the 9th bit of temp is not set to 1.
what is the problem here?
By the way: The effect of declaration of a register as signed is only in shifting and extending, yes? So this problem is not because of A being signed and B being unsigned , right?
The effect of declaration of a register as signed is only in shifting and extending
No, it effects all arithmetic. Although usually if you combine any unsigned or part select bus then it will default back to unsigned arithmetic.
You can not really have one input signed and one not, twos complement arithmetic will simply not work. You at least have to sign extend the signed value and insert a 0 MSB on to the unsigned, making sure it will be evaluated as positive.
Your first example is:
1110 0101 // -27
1100 0111 // -57
1 1010 1100 // -84 (-27 -57)
Second example (subtraction)
1110 0101 // -27
0011 1001 // +57
1 0001 1110 // 30 (ignoring MSB) -226 Including MSB
But note that the output is 1 bit wider, RTL does not give you access to the carry, but rather an extra sum, therefore the inputs are sign extended.
1 1110 0101 // -27
1 1100 0111 // -57
1 1010 1100 // -84
1 1110 0101 // -27
0 0011 1001 // +57
0 0001 1110 // 30
Note in the correctly sign extended subtraction the MSB is 0
But for your addition with the second value unsigned you need a 0 to show it is a positive number, and you will have bit growth of 1 bit:
1 1 1110 0101 // -27
0 0 1100 0111 // 199
0 0 1010 1100 // 172 (-27+199)
Here the extended bit (not a carry) is 0. not 1 as you predicted.
I am Trying to understand this bit of Verilog code..
reg [2:0] SYNC;
always #(posedge clk) SYNC <= {SYNC[1:0], ASYNC};
wire SYNC_risingedge = (SYNC[2:1] == 2'b01);
wire SYNC_fallingedge = (SYNC[2:1] == 2'b10);
wire SYNC_on = ~SYNC[1];
From what i understand.
A 3 bit reg is made (sync)
When the clock rises, sync is equal to the combination of bits 1 and 0 with the current value of (async).
The SYNC_risingedge is equal to (sync) bits 2 and 1 and the value of binary '01'
The SYNC_fallingedge is equal to (sync) bits 2 and 1 and the value of binary '10'
The SYNC_on is equal to the inverse of sync.
My questions are next to the lines in quotes.
reg [2:0] SYNC;
always #(posedge clk) SYNC <= {SYNC[1:0], ASYNC}; *"does this mean that it concentrates the state of ASYNC with only bits 1 and 0?"*
wire SYNC_risingedge = (SYNC[2:1] == 2'b01); *"is the binary number 01 placed only in bits 2 and 1? if so, how does it affect the previous line?"*
wire SYNC_fallingedge = (SYNC[2:1] == 2'b10); *"same question as previous line"*
wire SYNC_on = ~SYNC[1]; *"What does the [1] mean in ~SYNC[1]?"*
I've scoured the web, looking for Verilog syntax to understand this bit of code, but have come up short.
Any assistance would be appreciated.
Question 1
always #(posedge clk) SYNC <= {SYNC[1:0], ASYNC};
does this mean that it concentrates the state of ASYNC with only bits 1 and 0?
I think you mean "concatenates", and you're about right, yes. This statement essentially left-shifts SYNC by 1 and then puts the value of ASYNC in bit 0. This shifting operation takes place on each rising clock edge.
Complete table:
SYNC | ASYNC | New SYNC Setting
---------+-----------|--------------------
000 | 0 | 000
001 | 0 | 010
010 | 0 | 100
011 | 0 | 110
100 | 0 | 000
101 | 0 | 010
110 | 0 | 100
111 | 0 | 110
000 | 1 | 001
001 | 1 | 011
010 | 1 | 101
011 | 1 | 111
100 | 1 | 001
101 | 1 | 011
110 | 1 | 101
111 | 1 | 111
Question 2
wire SYNC_risingedge = (SYNC[2:1] == 2'b01);
is the binary number 01 placed only in bits 2 and 1? if so, how does it affect the previous line?
No, the == is a test, not an assignment. If those two bits of SYNC match 2b'01, then the SYNC_risingedge wire will be high. Otherwise it will be low.
Note: the "assignment" to SYNC_risingedge is asynchronous - it's just combinational logic.
Question 3
wire SYNC_fallingedge = (SYNC[2:1] == 2'b10);
same question as previous line
Same answer, too.
Question 4
wire SYNC_on = ~SYNC[1];
What does the [1] mean in ~SYNC[1]?
It's just referring to bit 1 of SYNC. SYNC_on is high whenever SYNC[1] is low, and vice versa.