Failed to use "generate" for memory - verilog

I'm using Verilog-2001 with Vivado 2015.4. There is my code:
parameter SHIFT = 16;
wire integrators_reset;
reg [INTEGRATOR_WIDTH - 1 : 0] sum_mem [SHIFT - 1 : 0];
reg [SHIFT - 1 : 0] full_mem;
wire [SHIFT - 1 : 0] equal;
genvar i;
generate
for(i = 0; i < SHIFT; i = i + 1) begin
always #(negedge equal[i]) begin
if(integrators_reset) begin
sum_mem[i] <= 0;
full_mem[i] <= 0;
end
else begin
if(sum_mem[i] == INTEGRATOR_MAX)
full_mem[i] <= 1;
else
sum_mem[i] <= sum_mem[i] + 1;
end
end
end
endgenerate
There is the error:
ERROR: [DRC 23-20] Rule violation (MDRV-1) Multiple Driver Nets- Net sum_mem[0][0] has multiple drivers
If i'm not using "generate" all is fine. For example:
always #(negedge equal[0]) begin
if(integrators_reset) begin
sum_mem[0] <= 0;
full_mem[0] <= 0;
end
else begin
if(sum_mem[0] == INTEGRATOR_MAX)
full_mem[0] <= 1;
else
sum_mem[0] <= sum_mem[0] + 1;
end
end
And there is not errors during implementation.

This seems like a tool limitation. You should be able to assign different fixed elements of an unpacked array from different always blocks. One workaround would be to move the declaration of sum_mem into the generate block.
for(I = 0; I < SHIFT; i = i + 1) begin : block_name
reg [INTEGRATOR_WIDTH - 1 : 0] sum_mem;
always #(negedge equal[I]) begin
if(integrators_reset) begin
sum_mem <= 0;
full_mem[i] <= 0;
end
else begin
if(sum_mem[i] == INTEGRATOR_MAX)
full_mem[i] <= 1;
else
sum_mem <= sum_mem + 1;
end
end
end
Now you have block_name[0].sum_mem, block_name[1].sum_mem, but you can not access block_name with a variable index.

Related

Verilog synthesis is giving me an error that I don't understand

I am getting this error when synthesizing my code, but I don't know what it means. It reads:
Error- net "Count[0] or a directly connected net is driven by more
than one source and not all drivers are three state.
It says the same errors for vectors count[0] - count[4] as well as for my load and k values. The code is my representation of an SPI Master. The SPI master has an instantiation of a shift register that is used to push out information.
module SPIMaster(output reg SCLK, CS, MOSI,
input EN, CLK, MISO,
input [7:0] m_data);
wire master_out;
reg [4:0] count;
wire [7:0] data_buff;
wire SCLK1;
reg master_in, c_sw, k, state, load;
shiftReg register_out (master_out, data_buff, load, (~SCLK), master_in, m_data);
assign SCLK1 = (~c_sw) | CLK;
always#(posedge CLK) begin
if(state) begin
if (k == 1) begin
state <= 0;
c_sw <= 0;
CS <= 1;
count <= 0;
k <= 0;
load <= 0;
end
else begin
state <= 1;
c_sw <= 1;
CS <= 0;
end
end
else begin
if (EN == 1) begin
state <= 1;
c_sw <= 1;
CS <= 0;
count <= 0;
k <= 0;
load <= 1;
end
else begin
state <= 0;
c_sw <= 0;
CS <= 1;
count <= 0;
k <= 0;
load <= 0;
end
end
end
always#(posedge SCLK1) begin
if (CS == 0) master_in <= MISO;
if (count == 7) begin
load <= 0;
end
else if (count == 15)begin
load <= 0;
end
else begin
load <= 1;
end
end
always#(negedge SCLK1) begin
if (count == 23) k <= 1;
else k <= 0;
if (CS == 0) begin
MOSI <= master_out;
count <= count + 1;
end
end
endmodule
Your code does not adhere to good synthesis coding practices because you assign to count from 2 different always blocks and those 2 blocks are triggered by different clock signals. You should make all assignments to count from the same always block.
The same is true of load and k.

Triangular signal with noise +1, -1 in Verilog

I am struggling for some time already and I can't find a simple and useful solution.
I would like to simulate triangular signal in size of 16 bits
and add a random noise to it with values 1 , 0, -1. It is important that signal with noise never differs for more than 1 from original noise and from previous value in noised signal.
For example, I would like values in that way:
ORIGINAL SIGNAL: 11111 22222 33333 44444 55555 ...
NOISED SIGNAL : 12321 12332 23434 34345 45665 ...
I simulated signal for values between 0 and 30766 because main focus now is adding noise to this original signal. This code work properly because I removed the conditions which limit the difference between values for maximum 1.
This signal is used for test bench.
reg [15:0] SIGNAL_i;
reg [15:0] SIGNAL_ii;
reg [15:0] SIGNAL_noise_i;
reg [15:0] SIGNAL_noise_reg; //za hranjenje zasumljenega signala
int RANDOM_noise_i;
int COUNT_end;
int COUNT;
initial SIGNAL_i=1;
initial COUNT_end=0;
initial COUNT=3'd4;
initial SIGNAL_ii=0;
initial SIGNAL_noise_i=1;
initial SIGNAL_noise_reg=0;
initial RANDOM_noise_i=1;
initial CLK = 1;
always #5 CLK = ~CLK;
always #10
begin
SIGNAL_noise_reg <= SIGNAL_noise_i;
RANDOM_noise_i = $signed($urandom_range(0,2))-1; //random noise generation
//upcount
if ((SIGNAL_i<16'd30766) && (SIGNAL_ii<SIGNAL_i)) //32765
begin
begin
if (COUNT_end==COUNT)
begin
assign SIGNAL_noise_i=SIGNAL_i + (RANDOM_noise_i);
SIGNAL_i=SIGNAL_i + 1;
SIGNAL_ii=SIGNAL_ii + 1;
COUNT_end=0;
COUNT_end=0;
end
else
begin
assign SIGNAL_noise_i=SIGNAL_i + (RANDOM_noise_i);
COUNT_end= COUNT_end + 1;
end
end
end
//counter on zero
else if (SIGNAL_i == 0)
begin
SIGNAL_i = 1;
SIGNAL_ii = 0;
SIGNAL_noise_i = SIGNAL_i + RANDOM_noise_i;
end
//down count
else
begin
if (COUNT_end==COUNT)
begin
assign SIGNAL_noise_i=SIGNAL_i + (RANDOM_noise_i);
SIGNAL_i=SIGNAL_i - 1;
SIGNAL_ii=SIGNAL_ii + 1;
COUNT_end=0;
COUNT_end=0;
end
else
begin
assign SIGNAL_noise_i=SIGNAL_i + (RANDOM_noise_i);
COUNT_end= COUNT_end + 1;
end
end
end
end
I would really appreciate your help!
Thank you.
I got the signal I wanted but for sure there are also beter ways to implement it. I simplified it a bit.
always #10
begin
SIGNAL_noise_reg <= SIGNAL_noise_i;
RANDOM_noise_i = $signed($urandom_range(0,2))-1;
if ((SIGNAL_i<16'd30766) && (SIGNAL_ii<SIGNAL_i)) //32765
begin
if(COUNT_end==COUNT-1)
begin
assign SIGNAL_noise_i=SIGNAL_i-1;
SIGNAL_i=SIGNAL_i + 1;
SIGNAL_ii=SIGNAL_ii + 1;
COUNT_end=0;
end
else if (COUNT_end == 0)
begin
assign SIGNAL_noise_i=SIGNAL_i -1;
COUNT_end= COUNT_end + 1;
end
else
begin
if (SIGNAL_i + RANDOM_noise_i - SIGNAL_noise_i > 1)
begin
assign SIGNAL_noise_i=SIGNAL_i;
COUNT_end= COUNT_end + 1;
end
else
begin
assign SIGNAL_noise_i=SIGNAL_i + RANDOM_noise_i;
COUNT_end= COUNT_end + 1;
end
end
end
else if (SIGNAL_i == 0)
begin
SIGNAL_i = 1;
SIGNAL_ii = 0;
SIGNAL_noise_i = SIGNAL_i + RANDOM_noise_i;
end
else
begin
if(COUNT_end==COUNT-1)
begin
assign SIGNAL_noise_i=SIGNAL_i+1;
SIGNAL_i=SIGNAL_i - 1;
SIGNAL_ii=SIGNAL_ii + 1;
COUNT_end=0;
end
else if (COUNT_end == COUNT-2)
begin
assign SIGNAL_noise_i=SIGNAL_i;
COUNT_end= COUNT_end + 1;
end
else
begin
if (SIGNAL_i + RANDOM_noise_i - SIGNAL_noise_i > 1)
begin
assign SIGNAL_noise_i=SIGNAL_i;
COUNT_end= COUNT_end + 1;
end
else
begin
assign SIGNAL_noise_i=SIGNAL_i + RANDOM_noise_i;
COUNT_end= COUNT_end + 1;
end
end
end
end

I2C master for tmp007 sensor module

I'm trying to create an I2C protocol in verilog to read data from a sensor (TMP007)then show the data received using led but to no avail. I've been trying to put led (eg. LED_GREEN[2] =1;) in the state to test the flow of the state. Only the LED_GREEN1 and LED_GREEN[0] are lighten up. So I guess the problem does occur in STATE_WACK2. Anyone can help?
module tmpi2c(
input wire clk,
input wire reset,
inout reg i2c_sda,
output wire i2c_scl,
output reg [17:0] LED_RED, // LED Red[17:0]
output reg [7:0] LED_GREEN
);
// write to device address 0x40, 0x01h
localparam STATE_IDLE = 0;
localparam STATE_START = 1;
localparam STATE_ADDR = 2;
localparam STATE_RW = 3;
localparam STATE_WACK = 4;
localparam STATE_DATA = 5;
localparam STATE_WACK2 = 6;
localparam STATE_ADDR2 = 7;
localparam STATE_RW2 = 8;
localparam STATE_WACK3 = 9;
localparam STATE_READ = 10;
localparam STATE_WACK4 = 11;
localparam STATE_READ2 = 12;
localparam STATE_WACK5 = 13;
localparam STATE_STOP = 14;
localparam STATE_DISPLAY = 15;
reg enable; //(r=1, w=0)
reg clki2c = 0;
reg [9:0]counter = 0; // 10-bit counter size
reg [9:0] timer = 0;
reg [7:0] state;
reg [6:0] addr;
reg [7:0] data;
reg [7:0] count;
reg [15:0] value =0;
reg [4:0] ge,shi,bai;
reg i2c_scl_enable =0;
assign i2c_scl = (i2c_scl_enable == 0) ? 1 : ~clki2c;
reg i2c_sda_en;
wire i2c_sda_in = i2c_sda ;
// counter size calculation according to input and output frequencies
parameter sys_clk = 50000000; // 50 MHz system clock
//parameter clk_out = 400000; // 0.4 MHz clock output
parameter clk_out = 200000; // 0.2 MHz clock output
//parameter clk_out = 1; // 1Hz clock output
parameter max = sys_clk / (2*clk_out); // max-counter size
//clock divider from 50Mhz to 0.4Mhz
always#(posedge clk or posedge reset)
begin
if(reset) begin
counter <=0;
clki2c <= 0;
end
else begin
if (counter < max) begin
counter <= counter + 1'd1;
end
else begin
counter <= 0;
clki2c <= ~clki2c;
end
end
end
//end clock divider
always#(posedge clki2c) begin
if (!i2c_sda_en) begin i2c_sda = i2c_sda ;
end else begin
i2c_sda = 1'bz;
end
if (reset == 1)
begin
state <= 0;
//i2c_sda <= 1;
//i2c_scl <= 1;
i2c_sda_en <= 1;// i2c_sda ==z;
addr <= 7'h40;
count <= 8'd0;
data <= 8'h01;
LED_RED[17:0] = 0;
LED_GREEN[7:0] = 0;
end
else begin
case(state)
STATE_IDLE: begin //idle
state <= STATE_START;
end
STATE_START: begin //start
i2c_sda_en <= 0;
state <=STATE_ADDR;
count <= 6;
end
STATE_ADDR: begin //msb address bit
LED_GREEN[0] =1;
i2c_sda <= addr[count];
if (count ==0) state <= STATE_RW;
else count <= count -1;
end
STATE_RW: begin
i2c_sda <=0; //write here
state <=STATE_WACK;
end
STATE_WACK: begin
i2c_sda_en <= 1;
if(i2c_sda_in==1)
begin
state <= STATE_WACK;
end
else
begin
state <= STATE_DATA;
end
count <= 7 ;
i2c_sda_en <= 0;
end
STATE_DATA: begin
LED_GREEN[1] =1;
i2c_sda <= data[count];
if (count == 0) state <= STATE_WACK2;
else count <= count -1;
end
STATE_WACK2: begin
i2c_sda_en <= 1;
if(i2c_sda_in==1)
begin
state <= STATE_WACK2;
end
else
begin
state <= STATE_ADDR2;
//LED_GREEN[1] =1;
end
count <= 6;
i2c_sda_en <= 0;
end
STATE_ADDR2: begin
LED_GREEN[2] =1;
i2c_sda <= addr[count];
if (count ==0) state <= STATE_RW2;
else count <= count -1;
end
STATE_RW2: begin
i2c_sda <=1; //read here
state <=STATE_WACK3;
end
STATE_WACK3: begin
i2c_sda_en <= 1;
if(i2c_sda_in==1)
begin
state <= STATE_WACK2;
end
else
begin
state <= STATE_READ;
end
count <= 15;
//i2c_sda_en <= 0;
end
STATE_READ: begin
LED_GREEN[3] =1;
value[count] <= i2c_sda_in;
if (count == 8) state<= STATE_WACK4;
else count <= count -1;
end
STATE_WACK4: begin
i2c_sda_en <= 0;
i2c_sda <=1; //Master should leave SDA high to terminate a single-byte read operation.
state <= STATE_READ2;
count <= 7;
i2c_sda_en <= 1;
end
STATE_READ2: begin
LED_GREEN[4] =1;
value[count] <= i2c_sda_in;
if (count == 0) state<= STATE_WACK5;
else count <= count -1;
end
STATE_WACK5: begin
i2c_sda_en <= 0;
i2c_sda <=1; //Master should leave SDA high to terminate a two-byte read operation.
state <= STATE_STOP;
end
STATE_STOP: begin
//i2c_sda <=1;
state <= STATE_DISPLAY;
end
STATE_DISPLAY: begin
LED_RED[17] = value[15];
LED_RED[16] = value[14];
LED_RED[15] = value[13];
LED_RED[14] = value[12];
LED_RED[13] = value[11];
LED_RED[12] = value[10];
LED_RED[11] = value[9];
LED_RED[10] = value[8];
LED_RED[9] = value[7];
LED_RED[8] = value[6];
LED_RED[7] = value[5];
LED_RED[6] = value[4];
LED_RED[5] = value[3];
LED_RED[4] = value[2];
LED_RED[2] = value[0];
LED_RED[3] = value[1];
//display delay
if (timer < 100000) timer <= timer+1;
else timer <= 0;
state <= STATE_IDLE;
end
endcase
end
end
endmodule

why all the variables are 'x' during the simulation

I'm trying to simulate this module, but during the simulation all the variables 'x's. why ?
is there anything wrong with variable definition and use ?
I'm new at verilog, and I'm not sure if the usage that I did with the variable is right..
this is the module and the test-bench:
module viterbi_decoder(
clock , // Clock input of the design
reset , // active high, synchronous Reset input
in_vector ,
out_vector
);
//inputs
input clock;
input reset;
input [7:0]in_vector;
//outputs
output [7:0] out_vector;
reg [7:0] out_vector;
//local variables
integer index;
integer row00[4:0];
integer row01[4:0];
integer row10[4:0];
integer row11[4:0];
integer prev_row00[4:0];
integer prev_row01[4:0];
integer prev_row10[4:0];
integer prev_row11[4:0];
integer who;
integer from;
integer mini;
integer ham_dist_1;
integer ham_dist_2;
reg in[1:0];
always # (posedge clock)
begin
if (reset)
begin
//reset device
row00[0] <= 3;
row01[0] <= 3;
row10[0] <= 3;
row11[0] <= 3;
end
else
begin
row00[0] <= 3;
row01[0] <= 3;
row10[0] <= 3;
row11[0] <= 3;
for (index=0; index < 8; index = index + 2)
//mini([n-1,0],[n-1,1])
ham_dist_1 <= in_vector[index] ^ 0 + in_vector[index + 1] ^ 0 + row00[(index / 2)];
ham_dist_2 <= in_vector[index] ^ 1 + in_vector[index + 1] ^ 1 + row01[(index / 2)];
if (ham_dist_1 > ham_dist_2 )
begin
row00[index / 2 + 1] <= ham_dist_1;
prev_row00[index / 2 + 1] <= 0;
end
else
begin
row00[index / 2 + 1] <= ham_dist_2;
prev_row00[index / 2 + 1] <= 1;
end
ham_dist_1 <= in_vector[index] ^ 1 + in_vector[index + 1] ^ 0 + row10[(index / 2)];
ham_dist_2 <= in_vector[index] ^ 0 + in_vector[index + 1] ^ 1 + row11[(index / 2)];
if (ham_dist_1 > ham_dist_2 )
begin
row01[index / 2 + 1] <= ham_dist_1;
prev_row01[index / 2 + 1] <= 2;
end
else
begin
row01[index / 2 + 1] <= ham_dist_2;
prev_row01[index / 2 + 1] <= 3;
end
ham_dist_1 <= in_vector[index] ^ 0 + in_vector[index + 1] ^ 0 + row00[(index / 2)];
ham_dist_2 <= in_vector[index] ^ 1 + in_vector[index + 1] ^ 1 + row01[(index / 2)];
if (ham_dist_1 > ham_dist_2 )
begin
row10[index / 2 + 1] <= ham_dist_1;
prev_row10[index / 2 + 1] <= 0;
end
else
begin
row10[index / 2 + 1] <= ham_dist_2;
prev_row10[index / 2 + 1] <= 1;
end
ham_dist_1 <= in_vector[index] ^ 0 + in_vector[index + 1] ^ 1 + row10[(index / 2)];
ham_dist_2 <= in_vector[index] ^ 1 + in_vector[index + 1] ^ 0 + row11[(index / 2)];
if (ham_dist_1 > ham_dist_2 )
begin
row11[index / 2 + 1] <= ham_dist_1;
prev_row11[index / 2 + 1] <= 2;
end
else
begin
row11[index / 2 + 1] <= ham_dist_2;
prev_row11[index / 2 + 1] <= 3;
end
//trace back algorithm
who <= 00;
from <= prev_row00[4];
mini <= row00[4];
if (row01[4] < mini)
begin
who <= 01;
from <= prev_row01[4];
mini <= row01[4];
end
if (row10[4] < mini)
begin
who <= 10;
from <= prev_row10[4];
mini <= row10[4];
end
if (row11[4] < mini)
begin
who <= 11;
from <= prev_row11[4];
mini <= row11[4];
end
for (index=3; index > 0; index = index - 1 )
begin
if (who == 00 && from == 00)
begin
out_vector[(index + 1) * 2] <= 0;
out_vector[((index + 1) * 2 )- 1] <= 0;
who <= 00;
from <= prev_row00[index -1];
end
else if (who == 00 && from == 01)
begin
out_vector[(index + 1) * 2] <= 1;
out_vector[((index + 1) * 2 )- 1] <= 1;
who <= 01;
from <= prev_row01[index -1];
end
else if (who == 01 && from == 10)
begin
out_vector[(index + 1) * 2] <= 1;
out_vector[((index + 1) * 2 )- 1] <= 0;
who <= 10;
from <= prev_row10[index -1];
end
else if (who == 01 && from == 11)
begin
out_vector[(index + 1) * 2] <= 0;
out_vector[((index + 1) * 2 )- 1] <= 1;
who <= 11;
from <= prev_row11[index -1];
end
else if (who == 10 && from == 00)
begin
out_vector[(index + 1) * 2] <= 1;
out_vector[((index + 1) * 2 )- 1] <= 1;
who <= 00;
from <= prev_row00[index -1];
end
else if (who == 10 && from == 01)
begin
out_vector[(index + 1) * 2] <= 0;
out_vector[((index + 1) * 2 )- 1] <= 0;
who <= 01;
from <= prev_row01[index -1];
end
else if (who == 11 && from == 10)
begin
out_vector[(index + 1) * 2] <= 0;
out_vector[((index + 1) * 2 )- 1] <= 1;
who <= 10;
from <= prev_row10[index -1];
end
else if (who == 11 && from == 11)
begin
out_vector[(index + 1) * 2] <= 1;
out_vector[((index + 1) * 2 )- 1] <= 0;
who <= 11;
from <= prev_row11[index -1];
end
end
end
end
endmodule
`timescale 1ns /1ps
module Testbench;
reg clock_t;
reg reset_t;
reg [7:0] in_vector_t;
wire [7:0] out_vector_t;
viterbi_decoder viterbi_1(.clock(clock_t), .reset(reset_t), .in_vector(in_vector_t), .out_vector(out_vector_t));
initial begin
clock_t = 0;
reset_t = 0;
end
always #10000 clock_t = ~clock_t;
always#(posedge clock_t)
begin
//case 0
in_vector_t <= 00110101; // <= 1; reset_t <= 0;
#5 $display("Result_t = %b", out_vector_t);
//case 1
in_vector_t <= 00001111; //clock_t <= 1; reset_t <= 0;
#5 $display("Result_t = %b", out_vector_t);
//case 2
in_vector_t <= 00010101; //clock_t <= 1; reset_t <= 0;
#5 $display("Result_t = %b", out_vector_t);
//case 3
in_vector_t <= 00101100; //clock_t <= 1; reset_t <= 0;
#5 $display("Result_t = %b", out_vector_t);
//case 4
in_vector_t <= 00000000; //clock_t <= 1; reset_t <= 0;
#5 $display("Result_t = %b", out_vector_t);
end
endmodule
First, your test bench needs improvements. The clock is very slow and the dut will only see in_vector_t <= 00000000; one the next of any clock edge. I suggest you change your in_vector_t in relation to the clock edge. Also since you have a free running clock, you'll need to end the simulation with a $finish. Example:
always #5 clock_t = ~clock_t;
initial begin
$monitor("Result_t = %b", out_vector_t);
#(posedge clock_t) in_vector_t <= 8'b00110101; //case 0
#(posedge clock_t) in_vector_t <= 8'b00001111; //case 1
#(posedge clock_t) in_vector_t <= 8'b00010101; //case 2
#(posedge clock_t) in_vector_t <= 8'b00101100; //case 3
#(posedge clock_t) in_vector_t <= 8'b00000000; //case 4
#(posedge clock_t);
#5 $finish; // end simulation
end
In your design, there are may place where you set/compare two bit values to 10 or 11. These values are in decimal ten and eleven. You need to specify the width and base type, I.E. 2'b10 or 2'b11. The same is true for your test bench; 00001111 is decimal one thousand one hundred and eleven, 8'b00001111 is decimal fifteen.
You are using non-blocking (<=) inside a clocked always block. This is correct. The problem is your code appears to be depended on recently updated values. With non-blocking assignment, the register does not get new value until the end of the time step. Anything sampling/comparing the value will see the old value until then. In this case you need to split the block into two always blocks: one synchronous using non-blocking (<=) and one combinational using blocking (=). Not knowing your full intended logic I'll just give you the template to get started:
always #* begin : comb_logic__calc_next
// defaults (constants or flops)
next_example1 = 8'h00; // constant
next_example2 = example2;// flop
/* algorithms for here
.... made-up example * /
for (index = 0; index<8; index=index+1) begin
if (input_bus[index]==1'b1) next_example1[index] = 1'b1;
else next_example2[index] = ~next_example2[index];
if (next_example1[index]==example[7-index]) begin
next_example2 = {next_example2[6:0],next_example2[7]};
end
end
end
always #(posedge clock) begin : synchronous_logic__assign_flops
if (reset) begin
// constants only
example1 <= 8'h00;
example2 <= 8'h00;
end
else begin
// assign flops to next value
example1 <= next_example1;
example2 <= next_example2;
end
end
Beyond that you will need to run simulation with a waveform dumping.

How to test primality in Verilog?

I have the Verilog code shown below, and if I try to compile it I get an error message. The point is that I'm trying to manipulate an input, which as long as I know cannot be done in Verilog. The point is that I need check the following condition in Verilog:
static int prime(unsigned long long n)
{
unsigned long long val = 1;
unsigned long long divisor = 5;
if (n == 2 || n == 3)
return 1;
if (n < 2 || n%2 == 0 || n%3 == 0)
return 0;
for ( ; divisor<=n/divisor; val++, divisor=6*val-1)
{
if (n%divisor == 0 || n%(divisor+2) == 0)
return 0;
}
return 1;
}
At the moment I have the following code:
module prime(clk, rst, start, A, ready, P);
input clk, rst, start;
input [7:0] A;
output ready, P;
reg ready, P;
wire [7:0] divisor;
assign divisor = 5;
wire [7:0] val;
assign val = 1;
always # (posedge clk or posedge rst) begin
if (!rst) begin
P <= 0;
end
else if (start) begin
case (A)
0 : P <= 1;
1 : P <= 1;
2 : P <= 1;
3 : P <= 1;
endcase
if (A%2 == 0 && A != 2) begin
P <= 0;
end
else begin
for( ; divisor <= A/divisor; val=val+1, divisor=6*val-1) begin
if (A%divisor == 0 || A%(divisor+2) == 0) begin
P <= 0;
end
end
// need to set P to 1
end
end
end
endmodule
Please also note I need to test primes in the form of 6n+1 or 6n-1, and I also need to assume in my code that 0 and 1 are also primes.
If I try the above code I get an error message saying:
Enhanced FOR loop is not enabled for verilog
If anyone can help me solve the error and finish my logic in Verilog, I would be glad.
The Verilog BNF does not allow empty or compound statements in for(;;). Change the file to *.sv to compile it under SystemVerilog rules. Otherwise change your for loop statement to have simple statements
for( divisor =5; divisor <= A/divisor; divisor=6*val-1) begin
if (A%divisor == 0 || A%(divisor+2) == 0) begin
P <= 0;
end
val++;
end
Also, you can't make procedural assignments to wires. make them variables.

Resources