Simple assignment of wire to output led in verilog doesn't synthesis with yosis - verilog

The following code will not build exiting with Error Code -6
module and_gate (
input [1:0] io_button,
output [2:0] io_led
);
wire wire1;
assign wire1 = io_button[0];
assign io_led[0] = wire1;
endmodule
But making this small change builds properly. Can you not just assign a wire to an output without modifying it in some way?
module and_gate (
input [1:0] io_button,
output [2:0] io_led
);
wire wire1;
assign wire1 = io_button[0];
assign io_led[0] = ~wire1;
endmodule

I've seen this before. Some synthesis tools don't handle well the case of there being zero gates in the design, as that means there's zero die area needed before routing. I'm guessing the tool is hitting some internal divide-by-0.
So yes, you can simply connect a wire to an output. That by itself is perfectly valid. And you can even connect an input directly to an output. As long as you have any other gates in the design, even unrelated/unconnected to the ports/nets in your example, the synthesizer would be happy, as there'd be non-zero die area.
So I bet this would work fine:
module and_gate (
input [1:0] io_button,
output [2:0] io_led
);
wire wire1;
assign wire1 = io_button[0];
assign io_led[0] = wire1;
assign io_led[1] = ~io_button[1]; // added line, just to infer a gate somewhere
endmodule

Related

How to use regs to modify wires?

I am kind of new to Verilog and was wondering how I can modify wires. I know that you cannot modify wires inside always blocks.
I've seen something like this where you can declare some regs and assign the wire to those regs (which you can then modify the reg to modify the wire?)
module something
#(parameter D_W = 8)
(
input wire clk,
input wire rst,
output wire valid,
output wire [D_W-1:0] data,
);
reg valid_rg = 0;
reg [D_W-1:0] data_rg = 0;
assign valid = valid_rg;
assign data = data_rg;
I was wondering how to do something like that for a wire like:
wire [7:0] wire_a [7:0];
Initially my guess would be to have something like this
reg [7:0] wire_a_rg [7:0];
assign wire_a[7:0] = wire_a_rg[7:0];
But I have a feeling it might be wrong. How could I approach this?
There's no need to use wires in SystemVerilog unless you need to model bi-directional buses, or any kind of circuitry with multiple drivers. You can write
module something
#(parameter D_W = 8)
(
input logic clk,
input logic rst,
output logic valid,
output logic [D_W-1:0] data,
);
And then you can make procedural assigmemnts to valid/data in an always block, or a continuous assign statement (but not both).
BTW, SystemVerilog prefers the use of logic keyword over synonym reg.
You should read my post about the difference between nets and variables.

How do I fix Error: adder_out is an unknown type

I need an Add operation in my circuit.
I tried designing a simple adder as below:
`timescale 1ns / 1ps
module adder(
input [7:0] adder_in1,
input [7:0] adder_in2,
output reg [7:0] adder_out
);
adder_out = adder_in1 + adder_in2;
endmodule
But, this code is giving me an error as below. I am really not sure how to correct this code. Please help.
One way to fix the error is to drop the reg declaration, and use the assign keyword:
module adder(
input [7:0] adder_in1,
input [7:0] adder_in2,
output [7:0] adder_out
);
assign adder_out = adder_in1 + adder_in2;
endmodule
When you make assignments to signals, you either have to be continuous assignments using the assign keyword as shown, or they need to be procedural assignments using always, initial, etc. In your case, it is simpler to use a continuous assignment.

How to switch modules in verilog?

I want to use SW[15] to switch between module A_7seg and B_7seg but it does not work. (2 modules work separately)
module mix(input CLOCK,input [15:0]SW,output reg [15:0] led,output [3:0] an,output reg[7:0] seg);
generate
case(SW[15])
1'b0:A_7seg (.CLOCK(CLOCK),.an(an),.seg(seg));
1'b1:B_7seg (.CLOCK(CLOCK),.SW(SW),.led(led),.an(an),.seg(seg));
endcase
endgenerate
endmodule
Since '2 modules work separately', the simple way is to use SW[15] to select between 2 modules' outputs.
module mix(
input CLOCK,
input [15:0] SW,
output reg [15:0] led,
output reg [3:0] an,
output reg [7:0] seg
);
wire [15:0] B_led;
wire [3:0] A_an, B_an;
wire [7:0] A_seg, B_seg;
// if not using 'generate' block, modules are instantiated at
// the top level, not in other 'if'/'case'/... structures.
// and name the 2 instantiations
A_7seg u_A_7seg (.CLOCK(CLOCK), .an(A_an), .seg(A_seg));
B_7seg u_B_7seg (.CLOCK(CLOCK), .SW(SW), .led(B_led), .an(B_an), .seg(B_seg));
// this extra circuit is needed to select between the two
always#(*)begin
if(SW[15])begin
led = B_led;
an = B_an;
seg = B_seg;
end
else begin
led = 16'h0; // <-- I assume the inactive value for 'led' is all-zero
an = A_an;
seg = A_seg;
end
end
endmodule
You may also want to use SW[15] to gate the inputs to the one that is not currently working to reduce power consumption.
You need to figure out the schematic before you understand how to write the code.

Quartus Error (10028) with memory

My goal is to form this code with Quartus, but the problem is I don't know how to fix the problem.
I've tried to know what Error 10028 means, but I cant figure out how to work with it.
Can someone teach me how to fix it or if there's a way to bypass it?
module mem (r_wb,addr,d,q);
input r_wb;//0write 1read
input [7:0] addr;
input [7:0 ] d;
output [7:0] q;
reg [7:0] q;
reg [7:0] mem_bank [0:255];
always #(r_wb)
if (r_wb) q=mem_bank[addr];
else mem_bank[addr]=d;
always #(addr)
if (r_wb) q=mem_bank[addr];
else mem_bank[addr]=d;
always #(d)
if (r_wb) q=mem_bank[addr];
else mem_bank[addr]=d;
endmodule
The code you put in your comment is mostly correct in the fact that you do need a clocking signal. However you should be using non-blocking assignment (<=).
I would recommend changing your model header to ANSI style which has been around since 2001. The non-ANSI style required q the be identified three times; port list, direction, type. ANSI style compacts it. Non-ANSI is good to understand because a lot of synthesizers and code generators still use it by default. But any modern simulator or synthesizer will accept ANSI style as input.
module mem (
input clk,
input r_wb, //0write 1read
input [7:0] addr,
input [7:0 ] d,
output reg [7:0] q) ;
reg [7:0] mem_bank [0:255];
always #(posedge clk)
if (r_wb) q<=mem_bank[addr];
else mem_bank[addr]<=d;
endmodule

How can i make my verilog shifter more general?

Here i have a shifter but as of rite now it only works for up to 3 bits. I've been looking and i can't find out how to make it work for up to 8 bits.
module shifter(a,b,out);
input [7:0] a, b;
output [7:0] out;
wire [7:0] out1, out2, out3;
mux_8b_2to1 first(a[7:0], {a[3:0],a[7:4]}, b[2], out1);
mux_8b_2to1 second(out1[7:0], {out1[5:0],out1[7:6]}, b[1], out2);
mux_8b_2to1 third(out2[7:0], {out2[6:0],out2[7]}, b[0], out);
endmodule
What you have is a Barrel Shifter. Two ways to make it more generic are make it a functional model (still synthesis-able) or structural model with a generate block. Both approaches follow IEEE Std 1364-2001 (aka Verilog-2001).
The functional generic approach for a barrel shifter only needs a down-shifter. The general function is out = {in,in} >> (WIDTH-shift) where leftover bits can be ignored. To protect for double-roll (i.e. shift > WIDTH ), use the mod operator on the shift (WIDTH-(shift%WIDTH)).
module barrel_shifter_functional #( parameter CTRL=3, parameter WIDTH=CTRL**2 )
( input wire [WIDTH-1:0] in,
input wire [ CTRL-1:0] shift,
output wire [WIDTH-1:0] out );
assign out = {2{in}} >> (WIDTH-(shift%WIDTH));
endmodule
The structural generic approach for a barrel shifter needs a generate block. The for loop in the generate block will unravel at compile time, not run time like a for loop like in an always block. To keep it generic also have have the 2-to-1 mux have a parametrized width. FYI, you can use the generate block with functional code too, for example comment out the mux_2to1 instantiation and uncomment the assign statement below it. Learn more about the generate block by reading IEEE Std 1800-2012 ยง 27. Generate constructs.
module barrel_shifter_structeral #( parameter CTRL=3, parameter WIDTH=CTRL**2 )
( input wire [WIDTH-1:0] in,
input wire [ CTRL-1:0] shift,
output wire [WIDTH-1:0] out );
wire [WIDTH-1:0] tmp [CTRL:0];
assign tmp[CTRL] = in;
assign out = tmp[0];
genvar i;
generate
for (i = 0; i < CTRL; i = i + 1) begin : mux
mux_2to1 #(.WIDTH(WIDTH)) g(
.in0(tmp[i+1]),
.in1({tmp[i+1][WIDTH-(2**i)-1:0],tmp[i+1][WIDTH-1:WIDTH-(2**i)]}),
.sel(shift[i]),
.out(tmp[i]) );
// assign tmp[i] = shift[i] ? {tmp[i+1][WIDTH-(2**i)-1:0],tmp[i+1][WIDTH-1:WIDTH-(2**i)]} : tmp[i+1];
end : mux
endgenerate
endmodule
module mux_2to1 #( parameter WIDTH=8 )
( input wire [WIDTH-1:0] in0, in1,
input wire sel,
output wire [WIDTH-1:0] out );
assign out = sel ? in1 : in0;
endmodule
Both examples are functionally equivalent and synthesize provided CTRL is less than or equal to the ceiling of log2(WIDTH). Synthesis will likely give different results. The generate method will exclusively use 2-to-1 muxes while the pure functional method will depend on the quality of the optimizer.
Working example # http://www.edaplayground.com/s/6/500
I've used the >> and << operators to generate a synthetizable design using ISEWebPack, as this:
module shifter(
input wire [7:0] a,
input wire [7:0] b,
input wire leftright, // 0=shift right, 1=shift left
output reg [7:0] out
);
always #* begin
if (leftright==0)
out = a>>b;
else
out = a<<b;
end
endmodule
This way, the symthesis tool will know that you want to implement a shifter and can use its own macros to best synthetize it:
Synthesizing Unit <shifter>.
Related source file is "shifter.v".
Found 8-bit shifter logical right for signal <out$shift0002> created at line 30.
Found 8-bit shifter logical left for signal <out$shift0003> created at line 32.

Resources