Reputation: 2521
I just started learning Verilog because I bought an FPGA. Since I don't have my FPGA yet, I started off with a somewhat big project, just to see where I get. I may have bitten off more than I can chew on this one, but I am trying to make a simple pipelined CORDIC module. The problem I am having in simulation here is that values will propagate from the testbench's input to uut, the unit under test, an instance of cordic rotator, those signals propagate to the first stage in the pipeline, xpipe[0]
, ypipe[0]
, zpipe[0]
, then to a cordic_stage
instance, but the outputs of this cordic_stage
instance do not seem to be changing any values in the xpipe[1]
, ypipe[1]
, or zpipe[1]
registers, they remain at zzzz
. Now I'm sure there's a million and one things wrong with my modules here, but I want to figure them out on my own. What I do want to know is why the values aren't making it out of the cordic_stage
into the next element in the pipelines' arrays, and how I can fix it. Here is my code below:
module cordic_stage #(
parameter ANGLE_WIDTH = 16,
parameter VALUE_WIDTH = 8,
parameter STAGE_I = 0
)(
input clk,
input [VALUE_WIDTH-1:0] xin,
input [VALUE_WIDTH-1:0] yin,
input [ANGLE_WIDTH-1:0] zin,
output reg [VALUE_WIDTH-1:0] xout,
output reg [VALUE_WIDTH-1:0] yout,
output reg [ANGLE_WIDTH-1:0] zout
);
parameter DELTA = 1 << (ANGLE_WIDTH - 2);
always @(posedge clk) begin
if (zin[ANGLE_WIDTH-1]) begin
xout <= xin + (yin >> STAGE_I); // These assignments to outputs are WORKING
yout <= yout - (xin >> STAGE_I);
zout <= zin + (DELTA >> STAGE_I);
end else begin
xout <= xin - (yin >> STAGE_I);
yout <= yout + (xin >> STAGE_I);
zout <= zin - (DELTA >> STAGE_I);
end
end
endmodule
module cordic_rotator #(
parameter ANGLE_WIDTH = 16,
parameter VALUE_WIDTH = 8
)(
input clk,
input [ANGLE_WIDTH-1:0] angle,
input [VALUE_WIDTH-1:0] xin,
input [VALUE_WIDTH-1:0] yin,
output [VALUE_WIDTH-1:0] xout,
output [VALUE_WIDTH-1:0] yout
);
reg [VALUE_WIDTH-1:0] xpipe [ANGLE_WIDTH:0]; // The second element in these pipelines arrays at index 1 never gets changed, so that it NOT WORKING
reg [VALUE_WIDTH-1:0] ypipe [ANGLE_WIDTH:0];
reg [ANGLE_WIDTH-2:0] zpipe [ANGLE_WIDTH:0];
always @(*) begin
xpipe[0] <= angle[ANGLE_WIDTH-1] ? -xin : xin; // These assignments to the first element in the pipeline are WORKING
ypipe[0] <= angle[ANGLE_WIDTH-1] ? -yin : yin;
zpipe[0] <= angle[ANGLE_WIDTH-2:0];
end
genvar i;
generate
for (i = 0; i < ANGLE_WIDTH; i = i + 1) begin: stages
cordic_stage #(ANGLE_WIDTH-1, VALUE_WIDTH, i) stage(clk, xpipe[i], ypipe[i], zpipe[i], xpipe[i+1], ypipe[i+1], zpipe[i+1]); // Values are being passed from the first stage in the pipeline at index zero to the first cordic_stage module, so that is WORKING
end
endgenerate
endmodule
module cordic_rotator_testbench;
// Inputs
reg clk;
reg [3:0] angle;
reg [3:0] xin;
reg [3:0] yin;
// Outputs
wire [3:0] xout;
wire [3:0] yout;
// Instantiate the Unit Under Test (UUT)
cordic_rotator #(4,4) uut (
.clk(clk),
.angle(angle),
.xin(xin),
.yin(yin),
.xout(xout),
.yout(yout)
);
initial begin
// Initialize Inputs
clk = 0;
angle = 0;
xin = 0;
yin = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
assign angle = 2; // These lines are also WORKING
assign xin = 8;
assign yin = 0;
end
always #5 clk = !clk;
endmodule
Upvotes: 1
Views: 1108
Reputation: 35933
You are driving a register xpipe
, directly from an output wire of a module, I would have thought that would be a syntax error, as register types are only supposed to be driven in procedural blocks.
You might try changing the xyzpipe types from reg to wire, since wire types are what are supposed to be driven by module outputs.
Addendum by OP: Code in cordic_rotator is changed for wire types, this fixes the problem.
wire [VALUE_WIDTH-1:0] xpipe [ANGLE_WIDTH:0];
wire [VALUE_WIDTH-1:0] ypipe [ANGLE_WIDTH:0];
wire [ANGLE_WIDTH-2:0] zpipe [ANGLE_WIDTH:0];
assign xpipe[0] = angle[ANGLE_WIDTH-1] ? -xin : xin;
assign ypipe[0] = angle[ANGLE_WIDTH-1] ? -yin : yin;
assign zpipe[0] = angle[ANGLE_WIDTH-2:0];
Upvotes: 1