Missing output on register file simulation - verilog

I'm trying to simulate a register file. My issues is that I am not getting an output for aData or bData. I suspect I have an issue with my assignments but I'm not sure. Still somewhat new to Verilog.
My code for the module:
`timescale 1ns / 1ps
module registerfile(
input [4:0] aAddress,
input [4:0] bAddress,
input [4:0] dAddress,
input [31:0] dData,
input write,
input [3:0] status,
input clock,
input reset,
output reg [31:0] aData,
output reg [31:0] bData
);
reg [31:0] registerfile [0:31];
integer i;
initial begin
for (i = 0; i <32; i = i +1 )
begin
registerfile[i] = 0;
end
end
always # (*)
begin
if (aAddress == 5'b00000)
begin
aData = 32'h0000_0000; //reg[0] already holds 0
end
else
begin
aData = registerfile[aAddress]; //contents of register file at aAddress sent out to aData
end
end
always # (*)
begin
if (bAddress == 5'b00000)
begin
bData = 32'h0000_0000; //reg[0] already holds 0
end
else
begin
bData = registerfile[bAddress]; //contents of register file at bAddress sent out to bData
end
end
always # (posedge clock)
begin
if (reset == 1)
begin
for (i = 0; i < 32; i = i + 1)
begin
registerfile[i] <= 0;
aData = 0;
bData = 0;
end
end
else if ((write == 1) && (dAddress != 0) && (dAddress != 31)) //reserve reg 0 for 0 constant and 31 for status register
begin
registerfile[dAddress] <= dData; //store dData
if (aAddress == dAddress) //handles special case
aData <= dData;
if (bAddress == dAddress) //handles special case
bData <= dData;
end
registerfile[31] <= {28'd0, status}; //status flags
end
endmodule
My code for the simulation:
`timescale 1ns / 1ps
module registerfile_test;
// Inputs
reg [4:0] aAddress;
reg [4:0] bAddress;
reg [4:0] dAddress;
reg [31:0] dData;
reg write;
reg [3:0] status;
reg clock;
reg reset;
// Outputs
wire [31:0] aData;
wire [31:0] bData;
// Instantiate the Unit Under Test (UUT)
registerfile uut (
.aAddress(aAddress),
.bAddress(bAddress),
.dAddress(dAddress),
.dData(dData),
.write(write),
.status(status),
.clock(clock),
.reset(reset),
.aData(aData),
.bData(bData)
);
reg [31:0] registerfile [0:31];
reg [31:0] testData1, testData2;
initial begin
// Initialize Inputs
aAddress = 0;
bAddress = 0;
dAddress = 0;
dData = 0;
write = 0;
clock = 0;
reset = 0;
// Wait 100 ns for global reset to finish
#100;
testData1 = 32'hFF0F_00FF;
testData2 = 32'h00F0_FF00;
aAddress = 5'b00101;
bAddress = 5'b00010;
dAddress = 5'b00110;
dData = 32'hFFFF_FFF0; //used to test
write = 1;
status = 4'b0000;
//write = 0;
registerfile[aAddress] = testData1;
registerfile[bAddress] = testData2;
end
// Add stimulus here
always begin
#10 clock = ~clock;
end
endmodule

You are assigning to aData in two separate always blocks. You shouldn't do that. Likewise for bData.
Also, reset is always 0 in your testbench.

Related

Machine state does not change output

As you can see in the code below, I have a machine state with a state called start. This state should take the value of coord_x_reg , increment it by one and assign it to the output port using the assign instruction at the end. The problems are:
The output coord_x does not change in the simulation as you can see in the photo
I imagine that the problem is that I cannot write and read from the register at the same time. How can I achieve the effect I want then? (I also tried using coord_x_reg as a integer variable)
When using reset, I have to comment some signals, other way I get Illegal left hand side of nonblocking assignment error.
module Ball
#(parameter SCR_W = 1280, //SCREEN RESOLUTION?
parameter SCR_H = 720,
parameter BALL_WIDTH = 30,
parameter PAD_Y_WIDTH = 26,
parameter PAD_Y_LENGTH = 168,
parameter PAD_x_POS_L = 67,
parameter PAD_x_POS_R = 1213 //SCR_W-PAD_x_POS_L
)
(
input wire CLK, RST,
input wire button_L, button_R,
input wire [9:0] pad_y_L,
input wire [9:0] pad_y_R,
output wire [9:0] coord_x,
output wire [9:0] coord_y,
output wire [3:0] score_left,
output wire [3:0] score_right
);
//STATES
localparam [3:0] //11 states needed we need 4 bits
start = 4'b0000,
start_race = 4'b0001,
left_player_begins = 4'b0010,
right_player_begins = 4'b0011,
top_left = 4'b0100,
top_right = 4'b0101,
bottom_left = 4'b0110,
bottom_right = 4'b0111,
score_L = 4'b1000,
score_R = 4'b1001,
game_over = 4'b1010;
//Current state variables
reg [3:0] state_reg, state_next;
//output registers
reg [9:0] coord_x_reg = 0;
reg [9:0] coord_y_reg = 0;
reg [3:0] score_left_reg = 0;
reg [3:0] score_right_reg = 0;
always #(posedge CLK, posedge RST)
begin
if(RST) // go to state zero if reset
begin
state_reg <= start;
//coord_x <= 0;
//coord_y <= 0;
//score_left <= 0;
//score_right <= 0;
end
else // otherwise update the states
begin
state_reg <= state_next;
end
end
//_________________________________________________________________________
// MACHINE STATE DESIGN
//_________________________________________________________________________
always #(state_reg) // <------------ PUT VARIABLES HERE???????!!!!!!!!!!!!!!!
begin
// store current state as next
state_next = state_reg; // REQUIRED: when no case statement is satisfied
case(state_reg)
start :
begin
coord_x_reg <= coord_x_reg + 1;
if (coord_x_reg == 10)
state_next = start_race;
end
start_race :
begin
state_next = start;
end
endcase
end
assign coord_x = coord_x_reg;
assign coord_y = coord_y_reg;
assign score_left = score_left_reg;
assign score_right = score_right_reg;
endmodule // Ball
By investigating, I came to the conclusion that the sensibility list was giving problems. I modified the code so the machine state is inside the always #(posedge CLK, posedge RST). Now works as expected. The new code:
module Ball
#(parameter SCR_W = 1280, //SCREEN RESOLUTION?
parameter SCR_H = 720,
parameter BALL_WIDTH = 30,
parameter PAD_Y_WIDTH = 26,
parameter PAD_Y_LENGTH = 168,
parameter PAD_x_POS_L = 67,
parameter PAD_x_POS_R = 1213 //SCR_W-PAD_x_POS_L
)
(
input wire CLK, RST,
input wire button_L, button_R,
input wire [9:0] pad_y_L,
input wire [9:0] pad_y_R,
output wire [9:0] coord_x,
output wire [9:0] coord_y,
output wire [3:0] score_left,
output wire [3:0] score_right
);
//STATES
localparam [3:0] //11 states needed we need 4 bits
start = 4'b0000,
start_race = 4'b0001,
left_player_begins = 4'b0010,
right_player_begins = 4'b0011,
top_left = 4'b0100,
top_right = 4'b0101,
bottom_left = 4'b0110,
bottom_right = 4'b0111,
score_L = 4'b1000,
score_R = 4'b1001,
game_over = 4'b1010;
//Current state variables
reg [3:0] state;
//output registers
reg [9:0] coord_x_reg = 0;
reg [9:0] coord_y_reg = 0;
reg [3:0] score_left_reg = 0;
reg [3:0] score_right_reg = 0;
always #(posedge CLK, posedge RST)
begin
if(RST) // go to state zero if reset
begin
state <= start;
coord_x <= 0;
coord_y <= 0;
score_left <= 0;
score_right <= 0;
end
else // otherwise update the states
begin
case(state)
start :
begin
coord_x_reg = coord_x_reg + 1;
if (coord_x_reg == 10)
state = start_race;
end
start_race :
begin
state = start_race;
end
endcase
end
end
assign coord_x = coord_x_reg;
assign coord_y = coord_y_reg;
assign score_left = score_left_reg;
assign score_right = score_right_reg;
endmodule // Ball ```

Register file not reading any data

I am trying to design a state machine that counts through and replaces values between 47 and 58. In my waveform though, I keep getting XXX for my R_data in the register file, and thus the rest of my top level design is thrown off. I can't seem to find a reason as to why R_data is outputting XXX for any address with R_en = 1. I'm on Vivado 2020.2; thank you for any help, and please let me know if I need to clarify anything.
Register:
`timescale 1ns / 1ps
module RegFile16x8(R_Addr, W_Addr, R_en, W_en, R_Data, W_Data, Clk, Rst);
input [3:0] R_Addr, W_Addr;
input Clk, Rst, R_en, W_en;
output reg [7:0] R_Data;
input [7:0] W_Data;
reg [7:0] RegFile [0:15];
always #(posedge Clk) begin
if (Rst == 1) begin
RegFile[0] <= 8'd48;
RegFile[1] <= 8'd53;
RegFile[2] <= 8'd68;
RegFile[3] <= 8'd57;
RegFile[4] <= 8'd55;
RegFile[5] <= 8'd59;
RegFile[6] <= 8'd40;
RegFile[7] <= 8'd49;
RegFile[8] <= 8'd31;
RegFile[9] <= 8'd38;
RegFile[10] <= 8'd54;
RegFile[11] <= 8'd50;
RegFile[12] <= 8'd63;
RegFile[13] <= 8'd58;
RegFile[14] <= 8'd70;
RegFile[15] <= 8'd51;
end
else if (W_en==1) begin
RegFile[W_Addr] <= W_Data;
end
end
always #(*) begin
if (R_en==1)
R_Data <= RegFile[R_Addr];
else
R_Data <= 8'bZZZZZZZZ;
end
endmodule
Top Level:
`timescale 1ns / 1ps
module PartA(Clk, Rst, go, done, count);
input Clk, Rst, go;
output reg [6:0] count;
output reg done;
reg [2:0] State, StateNext;
parameter s1 = 0, s2 = 1, s3 = 2, s4 = 3, s5 = 4, s6 = 5, s7 = 6, s8 = 7;
reg [4:0] i;
reg [7:0] temp;
reg R_en, W_en;
reg [7 :0] a_i;
wire [7:0] a_o;
//RegFile16x8(R_Addr, W_Addr, R_en, W_en, R_Data, W_Data, Clk, Rst);
RegFile16x8 r1(i[3:0], i[3:0], R_en, W_en, a_o, a_i, Clk, Rst);
always #(State, Rst, count) begin
R_en = 0;
W_en = 0;
case(State)
s1: begin
if(go == 1)
StateNext = s2;
else
StateNext = s1;
end
s2: begin
done = 0;
count = 0;
i = 0;
StateNext = s3;
end
s3: begin
if(i < 16)
StateNext = s4;
else
StateNext = s5;
end
s4: begin
R_en = 1;
temp = a_o;
if ((temp > 47) && (temp < 58))
StateNext = s7;
else
StateNext = s6;
end
s5: begin
done = 1;
StateNext = s1;
end
s6: begin
StateNext = s8;
end
s7: begin
W_en = 1;
count = count + 1;
a_i = temp - 48;
StateNext = s8;
end
s8: begin
i = i + 1;
StateNext = s3;
end
default: begin
StateNext = s1;
end
endcase
end
always #(posedge Clk) begin
if (Rst == 1)
State = s1;
else
State = StateNext;
end
endmodule
Test Bench:
`timescale 1ns / 1ps
module partA_tb();
reg Clk, Rst, go;
wire [6:0] count;
wire done;
PartA a1(Clk, Rst, go, done, count);
always begin
Clk = 0;
#200
Clk = 1;
#200;
end
initial begin
Rst = 1;
#200
Rst = 0;
go = 1;
end
endmodule
You need to keep Rst in the testbench high for a longer amount of time. The 1st posedge of Clk happens at time 200ns, and that is when you release the reset. You need to keep the reset asserted until after the 1st posedge of the clock in order to properly reset your RegFile, since it is a synchronous reset.
This testbench change allows RegFile to be reset to known values:
initial begin
Rst = 1;
#400
Rst = 0;
go = 1;
end
The change above removes the XXX from R_data.
I chose an arbitrary delay of 400, but it can be anything greater than 200. The key is that you need at least one posedge of Clk to sample Rst when it is high.

TestBench I2C Slave SDA won't go low

I'm trying to write an I2C Slave and test it in isolation.
I have a simulation that should be pulling SDA low when write_ack is high (Also highlighted by the red dots). However, you can see that SDA remains the same.
Part of me thinks it's to do with the way I'm testing with the force methods and the delays.
Any help appreciated.
I have found the keyword release which seems to help.
Code below & EDA Playground is here: https://edaplayground.com/x/6snM
/**
I2C Slave to Read/Write 8 bits of data only
*/
`timescale 1ns / 1ps
module Slave(
inout wire SDA,
input wire SCL);
reg [4:0] IDLE = 4'b0000;
reg [4:0] START = 4'b0001;
reg [4:0] READ_ADDRESS = 4'b0010;
reg [4:0] READ_WRITE = 4'b0011;
reg [4:0] DATA = 4'b0100;
reg [4:0] DATA_ACK = 4'b0101;
reg [4:0] STOP = 4'b0110;
reg [4:0] ADDRESS_ACK = 4'b0111;
reg [4:0] state = 4'b0010;
reg [6:0] slaveAddress = 7'b0001000;
reg [7:0] addr;
reg [6:0] addressCounter = 7'b0000000;
reg [7:0] data;
reg [6:0] dataCounter = 7'b0000000;
reg readWrite = 1'b0;
reg start = 0;
reg write_ack = 0;
assign SDA = (write_ack == 1) ? 0 : 'b1z;
always #(negedge SDA) begin
if ((start == 0) && (SCL == 1))
begin
start <= 1;
addressCounter <= 0;
dataCounter <= 0;
end
end
always #(posedge SDA) begin
if (state == DATA_ACK && SCL == 1)
begin
start <= 0;
state <= READ_ADDRESS;
end
end
always #(posedge SCL)
begin
if (start == 1)
begin
case (state)
READ_ADDRESS:
begin
addr[addressCounter] <= SDA;
addressCounter <= addressCounter + 1;
if (addressCounter == 6)
begin
state <= READ_WRITE;
end
end
READ_WRITE:
begin
readWrite <= SDA;
state <= ADDRESS_ACK;
end
ADDRESS_ACK:
begin
write_ack <= 1;
state <= DATA;
end
DATA:
begin
write_ack <= 0;
data[dataCounter] <= SDA;
dataCounter <= dataCounter + 1;
if (dataCounter == 8)
begin
state <= DATA_ACK;
write_ack <= 1;
end
end
DATA_ACK:
begin
write_ack <= 0;
state <= STOP;
end
STOP:
begin
start <= 0;
state <= READ_ADDRESS;
end
endcase
end
end
endmodule
Test Code
/**
Testing I2C Slace for reading/writing 8 bits of data only
*/
`timescale 1ns / 1ps
module Slave_TB ();
reg clk;
wire SDA;
wire SCL;
pullup(SDA);
pullup(SCL);
reg [6:0] addressToSend = 7'b0001000;
reg readWite = 1'b1;
reg [7:0] dataToSend = 8'b01100111;
integer ii=0;
initial begin
clk = 0;
force SCL = clk;
forever begin
clk = #1 ~clk;
force SCL = clk;
end
end
Slave #() UUT
(.SDA(SDA),
.SCL(SCL));
initial
begin
$display("Starting Testbench...");
clk = 0;
force SCL = clk;
#11
// Set SDA Low to start
force SDA = 0;
// Write address
for(ii=0; ii<7; ii=ii+1)
begin
$display("Address SDA %h to %h", SDA, addressToSend[ii]);
#2 force SDA = addressToSend[ii];
end
// Are we wanting to read or write to/from the device?
$display("Read/Write %h SDA: %h", readWite, SDA);
#2 force SDA = readWite;
$display("SDA: %h", SDA);
#2; // Wait for ACK bit
for(ii=0; ii<8; ii=ii+1)
begin
$display("Data SDA %h to %h", SDA, dataToSend[ii]);
#2 force SDA = dataToSend[ii];
end
#2; // Wait for ACK bit
// Force SDA high again, we are done
#2 force SDA = 1;
#100;
$finish();
end
initial
begin
// Required to dump signals to EPWave
$dumpfile("dump.vcd");
$dumpvars(0);
end
endmodule
Instead of using force, a more conventional approach is to add a tristate buffer to the testbench, just like you have in the design.
For SDA, create a buffer control signal (drive_sda) and a testbench data signal (sda_tb). Use a task to drive a byte and wait for the ACK.
Since SCL is not an inout, there is no need for a pullup, and it can be directly driven by clk.
module Slave_TB;
reg clk;
wire SDA;
wire SCL = clk;
pullup(SDA);
reg [6:0] addressToSend = 7'b000_1000; //8
reg readWite = 1'b1; //write
reg [7:0] dataToSend = 8'b0110_0111; //103 = 0x67
reg sda_tb;
reg drive_sda;
assign SDA = (drive_sda) ? sda_tb : 1'bz;
integer ii=0;
initial begin
clk = 0;
forever begin
clk = #1 ~clk;
end
end
Slave UUT
(.SDA(SDA),
.SCL(SCL));
initial begin
$display("Starting Testbench...");
drive_sda = 0;
sda_tb = 1;
#11;
// Set SDA Low to start
drive_sda = 1;
sda_tb = 0;
write({addressToSend, readWite});
write(dataToSend);
// Force SDA high again, we are done
#2;
drive_sda = 1;
sda_tb = 1;
#50;
$finish;
end
task write (reg [7:0] data);
integer ii;
for (ii=7; ii>=0; ii=ii-1) begin
$display("Data SDA %h to %h", SDA, data[ii]);
#2;
drive_sda = 1;
sda_tb = data[ii];
end
#2 drive_sda = 0;
endtask
initial begin
// Required to dump signals to EPWave
$dumpfile("dump.vcd");
$dumpvars(0);
end
endmodule

Generating unsigned number for booth multiplier

For an academic excercise, I have implemented a 32-bit Karatsuba multiplier which takes 17 cycles to run by doing parallel multiplication of 16 bits each and shifting them accordingly.
I am getting an issue where the partial products need to be unsigned, but booth multiplier is generating signed partial product for me, regardless of the input type I give, because of which I get incorrect partial products. How can I solve this?
For eg. my two signed inputs are 0xA000_000A and 0x000A_A000. So the first partial product of A000 * 000A should be 64000 but I get 0xFFFC4000 (FFFF_A000 * 0000_000A). I have shared my code here for the booth mult and its testbench.
module booth_multiplier
(
input logic clk,
input logic rst,
input logic valid,
input logic signed [15:0] Mul_X,
input logic signed [15:0] Mul_Y,
output logic signed [31:0] product,
output logic result_ready
);
logic unsigned Q_1;
bit [4:0] count;
logic signed [15:0] multiplier;
logic signed [15:0] multiplicand;
logic [15:0] A, temp_A;
logic signed [32:0] partial_product;
logic signed [32:0] partial_multiplier;
typedef enum {IDLE=0, OPERATE} fsm;
fsm state, next_state;
parameter ADD = 2'b01, SUB = 2'b10;
//assign product = multiplier[16:1];
always#(posedge clk or negedge rst)
begin
if(~rst)
begin
count <= 0;
state <= IDLE;
multiplier <= 0;
multiplicand <= 0;
end
else begin
count <= count+1;
state <= next_state;
end
end
always#(*)
begin
case(state)
IDLE : begin
Q_1 = 0;
A = 0;
count = 0;
product = 0;
temp_A = 0;
result_ready = 0;
if(valid) begin
multiplicand = Mul_X;
multiplier = Mul_Y;
partial_product = {A, multiplier, Q_1};
partial_multiplier = 0;
next_state = OPERATE;
end
end
OPERATE: begin
case(partial_product[1:0])
ADD: begin
temp_A = A + multiplicand;
multiplier = partial_product[16:1];
partial_multiplier = {temp_A, multiplier, Q_1};
partial_product = partial_multiplier >>> 1;
Q_1 = partial_product[0];
A = partial_product[32:17];
end
SUB: begin
temp_A = A - multiplicand;
multiplier = partial_product[16:1];
partial_multiplier = {temp_A, multiplier, Q_1};
partial_product = partial_multiplier >>> 1;
Q_1 = partial_product[0];
A = partial_product[32:17];
end
default: begin
temp_A = A;
multiplier = partial_product[16:1];
partial_multiplier = {temp_A, multiplier, Q_1};
partial_product = partial_multiplier >>> 1;
Q_1 = multiplier[0];
A = partial_product[32:17];
end
endcase
if(count == 16) begin
next_state = IDLE;
product = partial_product >> 1;
result_ready = 1;
end
else next_state = OPERATE;
end
endcase
end
endmodule
This I am using to do 4 parallel multiplications in
module fast_multiplier
(
input logic clk,
input logic rst,
input valid,
input logic signed [31:0] multiplicand,
input logic signed [31:0] multiplier,
output logic signed [63:0] product,
output logic ready);
logic [15:0] X1;
logic [15:0] Y1;
logic [15:0] Xr;
logic [15:0] Yr;
logic [31:0] X1_Yr;
logic [31:0] Xr_Yr;
logic [31:0] X1_Y1;
logic [31:0] Xr_Y1;
logic ready1, ready2, ready3, ready4;
assign X1 = multiplicand[31:16];
assign Y1 = multiplier[31:16];
assign Xr = multiplicand[15:0];
assign Yr = multiplier[15:0];
booth_multiplier X1Y1
(
.clk(clk),
.rst(rst),
.valid(valid),
.Mul_X(X1),
.Mul_Y(Y1),
.product(X1_Y1),
.result_ready(ready1));
booth_multiplier X1Yr
(
.clk(clk),
.rst(rst),
.valid(valid),
.Mul_X(X1),
.Mul_Y(Yr),
.product(X1_Yr),
.result_ready(ready2));
booth_multiplier XrY1
(
.clk(clk),
.rst(rst),
.valid(valid),
.Mul_X(Xr),
.Mul_Y(Y1),
.product(Xr_Y1),
.result_ready(ready3));
booth_multiplier XrYr
(
.clk(clk),
.rst(rst),
.valid(valid),
.Mul_X(Xr),
.Mul_Y(Yr),
.product(Xr_Yr),
.result_ready(ready4));
always#(posedge clk or negedge rst)
begin
if(~rst)
begin
product <= 0;
ready <= 0;
X1_Yr <= 0;
X1_Y1 <= 0;
Xr_Yr <= 0;
Xr_Y1 <= 0;
end
else begin
product <= ({32'b0,X1_Y1} << 32) + (({32'b0,X1_Yr} + {32'b0,Xr_Y1}) << 16) + {32'b0,Xr_Yr};
ready <= ready1 & ready2 & ready3 & ready4;
end
end
endmodule
Also, sharing the testbench,
module top_booth_multiplier ();
logic clk;
logic rst;
logic valid;
logic signed [31:0] multiplicand;
logic signed [31:0] multiplier;
logic signed [63:0] product;
logic ready;
fast_multiplier booth (.*);
initial
begin
clk = 0;
forever #10 clk = ~clk;
end
initial
begin
rst = 0;
#7 rst = 1;
#(posedge clk) valid <= 1;
multiplier = 32'hA000000A;
multiplicand = 32'h000AA000;
#(posedge clk) valid <= 0;
while(ready == 0)
begin
#(posedge clk);
end
repeat (20) #(posedge clk);
$finish;
end
endmodule
You need to consider "signed" inputs in booth multiplier ONLY for X1Y1 instance. All other instances MUST use "unsigned" inputs. This change should help!

Net 'VectorY[0]', or a directly connected net, is driven by more than one source, and at least one source is a constant net. (ELAB-368)

I am getting this error in VCS synthesizer. I have tried everything but it doesn't make sense to me.
it says VectorY[0], VectorY[1], VectorY[2], VectorY[3], or a directly connected net, is driven by more than one source, and at least one source is a constant net. (ELAB-368)
module control (clk, start, S1S2mux, newDist, CompStart, PEready, VectorX, VectorY, addressR, addressS1, addressS2,completed);
input clk;
input start;
output reg [15:0] S1S2mux;
output reg [15:0] newDist;
output CompStart;
output reg [15:0] PEready;
output reg [3:0] VectorX,VectorY;
output reg [7:0] AddressR;
output reg [9:0] AddressS1,AddressS2;
reg [12:0] count;
output reg completed;
integer i;
assign CompStart = start;
always #(posedge clk) begin
if(start==0) begin
count<= 12'b0;
completed<=0;
newDist<=0;
PEready<=0;
VectorX<=0;
VectorY<=0;
end
else if (completed==0)
count <= count+1'b1;
end
always #(count) begin
for (i = 0; i < 15; i = i+1)
begin
newDist [i] = (count [7:0] == i);
PEready [i] = (newDist [i] && !(count < 8'd256));
S1S2mux [i] = (count [3:0] > i);
end
addressR = count [7:0];
addressS1 = (count[11:8] + count[7:4] >> 4)*5'd32 + count [3:0];
addressS2 = (count[11:8] + count[7:4] >> 4)*4'd16 + count [3:0];
VectorX = count[3:0] - 4'd7;
VectorY = count[11:8] >> 4 - 4'd7;
completed = (count == 4'd16 * (8'd256 + 1));
end
endmodule
You can probably do like this...in systemverilog
create another logic variable
logic [3:0] VectorY_next;
and then in the sequential block, do ..
always_ff begin
if(start==0) begin
count<= 12'b0;
completed<=0;
newDist<=0;
PEready<=0;
VectorX<=0;
VectorY<=0;
end
else if (completed==0) begin
count <= count+1'b1;
VectorY <= VectorY_next;
end
end
And in the combinational block, you can write ...
always_comb begin
VectorY_next = VectorY;
for (i = 0; i < 15; i = i+1)
begin
.....
VectorY_next = count[11:8] >> 4 - 4'd7;
completed = (count == 4'd16 * (8'd256 + 1));
end
endmodule
And probably do the same for other ports too.To run using systemverilog, just use -sv option in the command line.

Resources