I have a Verilog project below that implements an LSFR. Currently, the code does not compile correctly in Xilinx ISE 14.6. It errors out with:
ERROR:HDLCompilers:108 - "top.v" line 70 Part-select of scalar wire array 'q' is illegal
ERROR:HDLCompilers:107 - "top.v" line 70 Illegal right hand side of nonblocking assignment
ERROR:HDLCompilers:108 - "top.v" line 74 Part-select of scalar wire array 'q' is illegal
ERROR:HDLCompilers:107 - "top.v" line 74 Illegal right hand side of nonblocking assignment
Which is pointing at this point in my code:
always # (display) begin
if(display == 1'b0) begin
LSB <= q[3:0];
switch <= LSB;
end
else begin
MSB <= q[7:4];
switch <= MSB;
end
end
I looked up the error in the Xilinx user guide, and it says to resolve the issue, give the value a bit width greater than 2. Since it's already at 8, I'm not sure what's wrong.
Here's my entire top module:
`timescale 1ns / 1ps
module top (c, start, clk_in, display, segments);
input [7:0] c;
input start, clk_in;
output [3:0] display;
output [6:0] segments;
reg [6:0] segments;
reg [3:0] display;
reg [3:0] LSB;
reg [3:0] MSB;
wire q[7:0];
wire q_[7:0];
wire clk, dff0_w, dff1_w, dff2_w, dff3_w, dff4_w, dff5_w, dff6_w;
reg [3:0] switch;
initial begin
display <= 4'b0111;
end
clock_divider #(15) divider(.cin(clk_in), .cout(clk));
//switch changes back and forth between the MSB and LSB of the 8 bit number when muxing
decoder bits(clk, switch, segments);
//D adders
dff dff0(.D(dff0_w),.Q(q[0]),.clk(clk),.start(start));
dff dff1(q[0],q[1],clk,start);
dff dff2(q[1],q[2],clk,start);
dff dff3(q[2],q[3],clk,start);
dff dff4(q[3],q[4],clk,start);
dff dff5(q[4],q[5],clk,start);
dff dff6(q[5],q[6],clk,start);
dff dff7(q[6],q[7],clk,start);
//xor gates
xor (dff6_w, q[7], q_[6]);
xor (dff5_w, dff6_w, q_[5]);
xor (dff4_w, dff5_w, q_[4]);
xor (dff3_w, dff4_w, q_[3]);
xor (dff2_w, dff3_w, q_[2]);
xor (dff1_w, dff2_w, q_[1]);
xor (dff0_w, dff1_w, q_[0]);
//buffer the C values
assign q_[0] = c[0] ? 1'b0 : q[0];
assign q_[1] = c[1] ? 1'b0 : q[1];
assign q_[2] = c[2] ? 1'b0 : q[2];
assign q_[3] = c[3] ? 1'b0 : q[3];
assign q_[4] = c[4] ? 1'b0 : q[4];
assign q_[5] = c[5] ? 1'b0 : q[5];
assign q_[6] = c[6] ? 1'b0 : q[6];
assign q_[7] = 1 ? 1'b0 : q[7]; //Cn is always 1
//mux the display
always # (posedge clk) begin
if(display == 4'b0111)
display <= 4'b1011;
else
display <= 4'b0111;
end
//display the appropriate value when the anode is asserted
always # (display) begin
if(display == 1'b0) begin
LSB <= q[3:0];
switch <= LSB;
end
else begin
MSB <= q[7:4];
switch <= MSB;
end
end
endmodule
Try changing:
wire q[7:0];
wire q_[7:0];
to:
wire [7:0] q;
wire [7:0] q_;
That clears up compile errors for me.
Related
I am trying to delay a 32-bit signal using shift register. My logic is a single flip flop delay a signal by 1 clk so I use shift register as it is combination of flip flop can someone guide me what is wrong with this code.
module delay_n_cycles (
input wire [31:0] data_in,
input wire clk,
output reg [31:0] data_out,
parameter N = 5
);
reg [31:0] shift_reg;
always #(posedge clk) begin
shift_reg <= {shift_reg[30:0], data_in};
if (N == 0) begin
data_out <= shift_reg[31];
end else begin
data_out <= shift_reg[N-1];
end
end
endmodule
First of all, your code is syntactically wrong. parameter cannot be declared in a way you provided.
Your shift register is only 32 bit wide. Usually, to delay multi-bit data this way, you need to keep N copies of data in the register, shift them at one end and read at the other. I guess the following should help:
module delay_n_cycles #(parameter N = 5)(
input wire [31:0] data_in,
input wire clk,
output reg [31:0] data_out
);
reg [N-1:0][31:0] shift_reg;
always #(posedge clk) begin
shift_reg <= (shift_reg << 32) | data_in;
data_out <= shift_reg[N-1];
end
endmodule
This code will work with system verilog because it used packed multi-dimensional arrays.
You need to shift the reg by 32 (width of the data) in packed version.
Here is an example of a testbench:
module tb();
bit clk;
int clkCount;
initial
forever begin
#5 clk = ~clk;
clkCount++;
end
logic [31:0] data_in, data_out;
initial begin
$monitor("%0t (%0d) [%h]: %0d --> %0d", $time, clkCount, ds.shift_reg[4], data_in, ds.data_out);
for(int i = 0; i < 20; i++) begin
#10 data_in = i;
end
$finish;
end
delay_n_cycles ds(data_in, clk, data_out);
endmodule
module data_mem(
input clk,
input [31:0] addr,
input [31:0] wdata,
input wr_en,
input rd_en,
output [31:0] rdata
);
reg [7:0] Mem [255:0];
assign rdata = rd_en ? Mem[addr]:32'bxxxxxxxx;
always # (posedge clk) begin
if (wr_en)
Mem[addr] <= wdata;
end
endmodule
Want to assign 4 bytes Mem[3:0] to wdata for write when wr_en flag is 1.
more accurately Mem[addr+3: addr]. how can i do this?
Three options:
Use concatenations: {Mem[addr+3],Mem[addr+2],Mem[addr+1],Mem[addr]} <= wdata;
Explicit range selection:
begin
Mem[addr+3] <= wdata[31:24];
// other assigments
Mem[addr] <= wdata[7:0];
end
Or you can Indexing vectors and arrays with +: which allows for(i=0;i<4;i=i+1) Mem[addr+i] <= wdata[i*8 +: 8]
I made 4_to_1 MUX with 2_to_1 MUX. I used always syntax. The output is delayed one time unit, but I don't know why.
When I change the always condition of 4_to_1 MUX's module sel to *, it works well. Why is this working?
module MUX_2_to_1 (
a0,a1,sel,out);
input [3:0]a0;
input [3:0]a1;
input sel;
output reg [3:0]out;
always #(sel)
begin
if (sel == 0)
out <= a0;
else if (sel == 1)
out <= a1;
end
endmodule
*
module MUX_4_to_1(
x0,x1,x2,x3,sel,out);
input [3:0]x0;
input [3:0]x1;
input [3:0]x2;
input [3:0]x3;
input [1:0]sel;
output reg [3:0]out;
wire [3:0]w0;
wire [3:0]w1;
MUX_2_to_1 m0 (x0,x1,sel[0],w0);
MUX_2_to_1 m1 (x2,x3,sel[0],w1);
always #(sel)
begin
if(sel[1] == 0)
out <= w0;
else if (sel[1] == 1)
out <= w1;
end
endmodule
*
`timescale 100ps/1ps
module Testbench_Mux;
reg [3:0]x0;
reg [3:0]x1;
reg [3:0]x2;
reg [3:0]x3;
reg [1:0]sel;
wire [3:0]out;
MUX_4_to_1 m0 (x0,x1,x2,x3,sel,out);
initial
begin
x0 = 4'b0001; x1 = 4'b0010; x2 = 4'b0100; x3 = 4'b1000;
#0 sel = 2'b00;
#5 sel = 2'b01;
#5 sel = 2'b10;
#5 sel = 2'b11;
#5 $stop;
end
endmodule
You are not using recommended Verilog coding practices for combinational logic. One problem is that you used an incomplete sensitivity list:
always #(sel)
Since there are 2 other signals, w0 and w1, which are read in the always block, they must also be in the sensitivity list. The verbose way to do this is:
always #(sel or w0 or w1)
The preferred way to do this is to use the compact * syntax:
always #(*)
This assures that the always block will be triggered when any change occurs to any signal read in the block.
Another issue is that you should always use blocking assignments for combinational logic. There is ample documentation out there as to the reason.
Change <= to =:
always #(*)
begin
if(sel[1] == 0)
out = w0;
else if (sel[1] == 1)
out = w1;
end
If you don't follow these recommendations, you get undesired simulation results.
You should change your MUX_2_to_1 module as well.
parameter N1 = 5;
parameter N2 = 5;
wire [(N1+N2-1):0] seckey [8:1];
shiftreg #(.depth(N1+N2-1)) sr1( .clk(clk), .reset(reset), .data_in(muxout[1]), .data_out(seckey[0]));
//--------------------------------------------------------------------------//
module shiftreg(
input clk,
input reset,
input data_in,
output data_out
);
parameter depth = 9;
wire [depth:0] connect_wire;
wire [depth:0] data_out;
//wire [depth:0] data_out;
assign connect_wire[0] = data_in;
assign data_out[depth:0] = connect_wire[depth:0];
genvar i;
generate
for(i=1; i<=depth; i=i+1) begin: loop1
ff dff(.d(connect_wire[i-1]), .clk(clk), .reset(reset), .q(connect_wire[i]));
end
endgenerate
endmodule
//--------------------------------------------------------------------//
module ff(
input d,
input clk,
input reset,
output reg q
);
always # (posedge clk or posedge reset)
begin
if (reset) begin
q <= 1'b0;
end
else begin
q <= d;
end
end
endmodule
//------------------------------------------------------------------------//
Value of N1 and N2 is 5.
I am getting the error "Size mismatch in connection of port (data_out). Formal port size is 10-bit while actual signal size is 1-bit"
I have set the size of the data_out port to be 10 bits but its still showing the signal size to be 1 bit.
To set the size of data_out, you need to set the size where you declare the parameter. Try the header below
module shiftreg(clk, reset, data_in, data_out);
parameter depth = 9;
input clk;
input reset;
input data_in;
input [depth:0] data_out;
Also:
assign data_out[depth:0] = connect_wire[depth:0];
can be replaced with
assign data_out = connect_wire;
This code should dispaly S for 1 sec then turn off for 1 sec and then dispaly G for 1 sec and then turn of for 1 sec and then display S for 1 sec and so on.
The problem is I am getting S then off then G then off then G then off and so on. I believe the error in the hex7segm module but I could not find a solution. Any help would be appreciated
Here is the code:
module asqw (output wire [6:0]a2g,output wire [3:0]AN,input wire fastclk);
wire slowclk;
slow_clock xx(fastclk,slowclk);
hex7segm zz(slowclk,a2g,AN);
endmodule
moduleslow_clock (input wire fastclk,output wire slowclk);
reg[27:0]period_count=0;
always#(posedge fastclk)
begin
period_count<=period_count+1;
end
assign slowclk=period_count[27];
endmodule
module hex7segm (input wire slowclk,
output reg [6:0]a2g,
output reg [3:0]AN
);
reg[1:0]x;
reg[1:0]y=0;
always#(*)
begin
if(slowclk)
begin
x=y;
AN= 4'b1110;
y=y+1;
if(y==2) y=0;
else
x=2;
AN= 4'b1110;
end
case(x)
0: a2g=7'b0100100;
1: a2g=7'b0100000;
2: a2g=7'b1111111;
default: a2g=7'b0100100;
endcase
end
endmodule
Hi probably a little bit late to answer but here it is: The main problem is that you are mixing combinational and sequential logic. You need to separate these two. Moreover, I couldn't see why your new clock has a duty cycle of 50%.
Top module:
module asqw (
output [6:0]a2g,
input wire fastclk);
wire slowclk;
slow_clock xx(fastclk,slowclk);
hex7segm zz(slowclk,a2g);
endmodule
Seven Segment Driver:
module hex7segm (
input wire slowclk,
output reg [6:0]a2g
);
localparam S = 7'b0100100;
localparam G = 7'b0100000;
localparam OFF = 7'b1111111;
reg [2:0] state = 0;
always # (posedge slowclk)
begin
state <= (state == 5) ? 0 : state + 3'b1;
end
always # (*)
begin
case(state)
0: a2g <= S;
2: a2g <= G;
4: a2g <= S;
default: a2g <= OFF;
endcase
end
endmodule
Slow clock:
module slow_clock (
input wire fastclk,
output reg slowclk = 0
);
reg[27:0]period_count = 0;
always#(posedge fastclk)
begin
period_count <= (period_count == 25000000) ? 0 : period_count+ 28'b1;
slowclk <= (period_count == 25000000) ? ~slowclk : slowclk;
end
endmodule