How to do complement for one bit in verilog - verilog

I want to ask about switching one bit for example x[3] in bit vector x[0:3] to one if it's zero or to zero if it's one in verilog.So if x=0101 it will become x=0100 .I have tried concatination with not but it's error in verilog .Can you help me to do that?
My code is here :http://www.edaplayground.com/x/JAc
where x:input and y:x after mutate one bit
Thanks in advance.

To alter one bit as part of a bus:
module bit_mangle(
input [3:0] x,
output [3:0] y
);
always #* begin
y = {x[3:1], ~x[0]} ;
end
endmodule
I have updated a copy of your code on EDA playground, and fixed a few issues in the testharness.
Working simulation on EDA Playground.
It is more common to define buses from [SIZE-1:0]. Your old Mutation code was trying to drive the input in two places rather than letting the level above drive the value.

always_comb begin
x = 4'b0101 ;
x[3] = ~x[3] ; //overwrite x[3] with its complement
end
or
always_comb begin
x = 4'b0101 ;
x[3] = x[3] ^ 1'b1 ; //XOR x[3] with 1
end

Related

how to implement verilog code with small modules

(Verilog) The following is a 32-bit Arithmetic Logic Unit (ALU) [see slides]. It has two 2-1 and one 3-1 MUX, a 32-bit Adder, a 32-bit subtractor, and a 16-bit multiplier. The function table shows different functions this ALU performs for different values of F (a 3-bit control signal). Notice the interconnect among different modules inside the ALU.
Please describe this ALU using Verilog. Your implementation should start with the smaller blocks showing in the ALU, and then using those smaller blocks to build the whole ALU. In other words, your implementation should promote reusability of smaller modules (i.e., modular). Optimize your implementation if possible.
function table in the image
module adding(r,a,b);
input[31:0] a;
input[31:0] b;
output[31:0] r;
assign r=a+b;
endmodule
module ALU(F,A,B,R);
input[2:0] F;
input[31:0] A;
input[31:0] B;
output[31:0] R;
reg R;
always #(F)
begin
if ( F == 3'b000 ) adding ad(R,A,B);
else if ( F == 3'b001 ) R = A+1;
else if ( F == 3'b010 ) R = A-B;
else if ( F == 3'b011 ) R = A-1;
else if ( F == 3'b10x ) R = A*B;
end
endmodule
this what I did so far but I got errors!! I will continue with the other statement as I know how to make the first small module
Notice some basic verilog syntax issues.
bit width mismatch in declaration of R.
sensitivity list not complete for the always block.
module instantiation is not allowed under a structural if.
I don't know if the undefined branches for F is intended, it is leading to behavior perhaps your don't want.
Since you are mainly working on module partition, it's related to the point 3. You will need to instantiate the basic (reusable) modules separately, and then select the outputs via F.
wire [31:0] adder_b;
wire [31:0] adder_result;
assign adder_b = F[0] ? 32'h1 : B; // select input outside 'adding'
adding ad (adder_result, A, ader_b);
always#(*)begin
if(F2:1] == 2'b00) R = adder_result;
...
end
There are many ways to write simple code in verilog.it depends on requirement some time here I presented different ways to write this code.
first by assign keyword and the second by case statements.
assign result = (opcode==3'b000) ? A+B :
((opcode==3'b001)? A+1 :
((opcode==3'b010)? A-B :
((opcode==3'b011)? A-1 : A*B)));
always #(*) begin
casex(opcode)
3'b000: result=A+B;
3'b001: result=A+1;
3'b010: result=A-B;
3'b011: result=A-1;
3'b1xx: result=A*B;
endcase
end

Why is computing two's compliment in a single Verilog statement (i.e. ~x + 1'b1) producing the wrong answer?

I realized that doing the 2's compliment in a single verilog statement (as seen for the '' below) is giving the wrong answer. But I don't understand why. Can someone help explain this? Operator precedence doesn't seem to explain the issue.
module test();
logic [7:0] x;
logic [7:0] x_1s;
logic [3:0] x_2_0_2s_compl_type1;
logic [3:0] x_2_0_2s_compl_type2;
assign x = '0;
assign x_2_0_2s_compl_type1 = ~x[2:0] + 1'b1; // gives the wrong answer
assign x_1s = ~x;
assign x_2_0_2s_compl_type2 = x_1s[2:0] +1'b1; // gives correct answer
always #* begin
$display("x = %b",x);
$display("x_2_0_2s_compl_type1 = %b",x_2_0_2s_compl_type1);
$display("x_1s = %b",x_1s);
$display("x_2_0_2s_compl_type2 = %b",x_2_0_2s_compl_type2);
end
endmodule
Simulation results:
x = 00000000
x_2_0_2s_compl_type1 = 0000
x_1s = 11111111
x_2_0_2s_compl_type2 = 1000
Section 11.8.2 Steps for evaluating an expression in the 1800-2017 LRM explains this. Basically, the operands in a context-determined expression get extended to match the size of the target assignment before applying any operators. So ~x[2:0] becomes ~(4'b000)
To do what you want in one expression you can write
assign x_2_0_2s_compl_type1 = {~x}[2:0] + 1'b1;
or
assign x_2_0_2s_compl_type1 = 3'(~x) + 1'b1;

Bit by bit comparison between two variables in Verilog

Currently, I am beginning to write the firmware by Verilog for one idea. It is comparing bit by bit between two variables and then using one binary counter to count the number of different bits.
For example:
I have two variables in verilog
A : 8'b00100001;
B : 8'b01000000;
Then I give the condition to compare bit by bit between two variables. If there is difference between 1 bit of A and 1 bit of B at same bit position, binary counter will count.
This is my verilog code:
module BERT_test(
input CLK,
input RST,
input [7:0] SIG_IN,
input [7:0] SIG_OUT,
output [7:0] NUM_ERR
);
integer i;
reg[7:0] sign_in;
reg[7:0] sign_out;
always #(posedge CLK) begin
sign_in[7:0] <= SIG_IN[7:0];
sign_out[7:0] <= SIG_OUT[7:0];
end
reg [15:0] bit_err;
// Combinational Logic
always #* begin
bit_err = 8'b0;
for (i=0;i<8;i=i+1) begin
if (sign_in[i] == sign_out[i]) begin
bit_err = bit_err + 8'b0;
end else begin
bit_err = bit_err + 8'b1;
end
end
assign NUM_ERR = bit_err;
end
endmodule
Then I had a mistake
Reference to vector wire 'NUM_ERR' is not a legal reg or variable lvalue
I do not know how to solve this problem. Are there any solutions for this problem or how I need to modify my firmware, please suggest me.
You are driving NUM_ERR (a net) from an always block. It is not permitted to drive nets from always blocks (or initial blocks). You need to move this line:
assign NUM_ERR = bit_err;
outside the always block.
You should not use an assign statement inside an always block. This is legal but is deprecated and means something weird. If you have included this line inside the always block by mistake, then indenting you code properly would have shown it up.
You have an assign WITHIN an always block. Move it outside.
Adding zero to bit error if the bits are the same is superfluous.
if (sign_in[i] != sign_out[i])
bit_err = bit_err + 8'b1;
Also bit error is 16 bits so it is not wrong to add 8'b1 but misleading.

Verilog Register to output

I am working with an Altera DE2 development board and I want to read an input in on the switches. This is stored in registers. Based on a counter these registers are incremented. The registers are then supposed to be output to the Seven Segment Displays thought a B2D converter. But I can not pass a register to a function.
wire [26:0] Q,Q2,Q3,Q4;
wire [3:0] one,two,three,four;
reg SecInc,MinInc,HrInc;
reg [3:0] M1,M2,H1,H2;
assign one = SW[3:0];
assign two = SW[7:4];
assign three = SW[11:8];
assign four = SW[15:12];
always begin
M1 = SW[3:0];
M2 = SW[7:4];
H1 = SW[11:8];
H2 = SW[15:12];
end
This is how I get and store the inputs. They come from the switches which we use as a binary representation on Hours and Minutes.
Based on a counter we increment a minute or an hour register.
//increment seconds from 0 to 60
counter seconds (SecInc,KEY[0],Q2);
defparam seconds.n = 8;
defparam seconds.mod = 60;
always # (negedge CLOCK_50) begin
if (Q2 >= 60) begin
MinInc = 1;
M1 <= M1 + 1'b1;
if(M1 >= 9) begin
M1 <= 0;
M2 <= M2 + 1'b1;
end
end else begin
MinInc = 0;
end
end
We want to display the result on the SSD's.
hex(M1,HEX4);
hex(M2,HEX5);
hex(H1,HEX6);
hex(H2,HEX7);
Here in lies the problem. This is not allowed in verilog. I need a way to send my registers to a function which displays numbers from 0 to 9 using some B2D conversion.
I will say I have never had a formal intro to verilog before and I have tried all I can think to do. I even tried to make a new module in which I would pass one,two,three,four and have the module increment them, like it does with Q2 for the counter I have shown. Any suggestions or help is greatly appreciated!
As requested here is the hex module:
module hex(BIN, SSD);
input [15:0] BIN;
output reg [0:6] SSD;
always begin
case(BIN)
0:SSD=7'b0000001;
1:SSD=7'b1001111;
2:SSD=7'b0010010;
3:SSD=7'b0000110;
4:SSD=7'b1001100;
5:SSD=7'b0100100;
6:SSD=7'b0100000;
7:SSD=7'b0001111;
8:SSD=7'b0000000;
9:SSD=7'b0001100;
endcase
end
endmodule
Thank you in advance!
Your hex module is not a function, it is a module and therefore must be instantiated with an instance name like this:
hex digit0(.BIN(M1), .SSD(HEX4));
hex digit1(.BIN(M2), .SSD(HEX5));
hex digit2(.BIN(H1), .SSD(HEX6));
hex digit3(.BIN(H2), .SSD(HEX7));
In addition to nguthrie being correct, that you need to instantiate your hex converter as a module, you drive M1 from a race condition in your always block. Non-blocking assignments will evaluate simultaneously within a block (or essentially simultaneously). This is not a program, where things happen in order. What might work better is:
always # (negedge CLOCK_50) begin
if (Q2 >= 60) begin
MinInc = 1;
if (M1 < 9) begin
M1 <= M1 + 1'b1;
end else begin
M1 <= 0;
M2 <= M2 + 1'b1;
end
end else begin
MinInc = 0;
end
end
You will also potentially get unexpected results from your blocking assignments to MinInc, but since I don't see where this is read it's hard to know what will happen.
Read up on blocking (=) vs non-blocking (<=) assignments in Verilog. It's one of the trickiest concepts of the language, and misuse of the two operations is the cause of 90% of the most dastardly bugs I've ever seen.
EDIT: In re-reading your question, it seems that you're trying to drive M1-4 from at least three places. You really can't have a continuous always begin block and a clocked (always # (negedge clock) begin) driving the same register. This will send your compiler into a tantrum.

How do I convert a number to two's complement in verilog?

I am trying to design a 4-bit adder subtracter in verilog. This is only the second thing I have ever written in verilog, and I don't know all the correct syntax yet. This is the module I have so far:
module Question3(carryin, X, Y, Z, S, carryout, overflow);
parameter n = 4;
input carryin, Z;
input [n-1:0]X, Y;
output reg [n-1:0]S;
output reg carryout, overflow;
if(Z==0)
begin
Y = not(y) + 4'b0001;
end
always #(X, Y, carryin)
begin
{carryout, S} = X + Y + carryin;
overflow = carryout ^ X[n-1]^Y[n-1]^S[n-1];
end
endmodule
My compiler (xilinx 10.1), keeps saying "Syntax error near if." I have tried many different ways of doing the conversion, including just using a Case that takes Y as an argument, then checks all the possible 4-bit combinations, and converts them to two's complement.
Z is what determines if the adder does subtraction or addition. If it's 0, it means subtraction, and I want to convert y to two's complement, then just do regular addition. I'm sure the rest of the adder is correct, I just do not know what is wrong with the part where I'm trying to convert.
reg [n-1:0] Y_compl;
always #( Z, Y, X, carryin ) begin
Y_ = ( ~Y + 4'b0001 );
if ( Z == 1'b0 ) begin
{carryout, S} = X + Y_compl + carryin;
overflow = carryout ^ X[n-1] ^ Y_compl[n-1] ^ S[n-1];
end
else begin
{carryout, S} = X + Y + carryin;
overflow = carryout ^ X[n-1] ^ Y[n-1] ^ S[n-1];
end
end
A couple of important points.
Put the if statement inside the always block. Do not use two always blocks, you'll create a race condition in the simulator.
I created a new variable, Y_ because using Y, which is an input, remember, on the left hand side of an assignment will probably infer latches or do something else nasty when you synthesize.
I suggest using the bitwise inversion operator '~' to invert Y instead if the 'not'
primitive. The synthesis tool has more freedom to optimize your code this way.
Double check for correct results, it's been awhile since I built an adder.
You are using a lower case "y" in "Y = not(y) + 4'b0001;"
Also, you're using more additions than you need to. X-Y is the same thing as NOT(NOT(X)+Y).
put the if statement within an initial block
http://www.asic-world.com/verilog/vbehave1.html

Resources