How to use float numbers with quartus megawizard ALTMULT_ACCUM(MAC)? - verilog

I am using the below mentioned module and testbench to use MAC megawizard in quartus, can anyone tell me how can I use floating point numbers for the same megawizard?
Testbench
`timescale 1ns/1ps
module projecttry2_tb;
reg [15:0] A, B;
wire [31:0] P;
reg clk;
projecttry2 M(.A(A),.B(B),.P(P),.clk(clk));
initial
begin
clk = 1;
forever #25 clk = ~clk;
end
initial
begin
A=3008;
B=255;
#50
A=5859;
B=255;
#50
A=1133;
B=255;
#50
A=0;
B=0;
end
endmodule
Design Module
module projecttry2(A,B,P,clk);
input [15:0] A,B;
output [31:0] P;
input clk;
mult_acc mult_acc_inst (
.clock0(clk),
.dataa(A),
.datab(B),
.result (P)
);
endmodule

ALTFP_MULT is available and documented on page 40 of Floating-Point Megafunctions.

Related

How to get more info in testbench results?

I realize that this may be very easy to fix but I can't find a way to make it work.
My question is how can I get visual signals of CE2 and CEO in this case? I know by looking on RTL Scheme CE2 and CEO isn't connected to pins. And I just can't connect them.
CE2 should be ON when first counter reach 9 but on waveform its always as X. And CEO should be ON when Q is 9 but on waveform its always Z.
This circuit is just for self learning.
Testbench
Circuit Scheme
TOP MODULE:
`timescale 1ns / 1ps
module top(
input CLK,
input CLR,
input CE,
input CE2,
output reg [3:0] Q,
output reg [3:0] Q2,
output wire CEO,
output CEO2
);
wire CLK;
wire CLR;
wire CENABLE;
wire CE2;
wire Q;
wire Q2;
wire CEO;
wire CEO2;
licznik licznik(.CLK(CLK),.CLR(CLR),.CE(CE),.CEO(CENABLE),.Q(Q));
licznik2 licznik2(.CLK(CLK),.CLR(CLR),.CE2(CENABLE),.Q2(Q2),.CEO2(CEO2));
endmodule
TESTBENCH:
`timescale 1ns / 1ps
module testbench;
reg CLK;
reg CLR;
reg CE;
reg CE2;
wire [3:0] Q;
wire [3:0] Q2;
wire CEO;
wire CEO2;
top UUT (
.CLK(CLK),
.CLR(CLR),
.CE(CE),
.CE2(CE2),
.Q(Q),
.Q2(Q2),
.CEO(CEO),
.CEO2(CEO2)
);
initial CLK=1'b0;
always #5 CLK=~CLK;
initial
begin
CLR = 1'b1;
CE= 1'b1;
#18 CLR = 1'b0;
end
endmodule
FIRST MODULE:
`timescale 1ns / 1ps
module licznik(
input CLK,
input CLR,
input CE,
output reg [3:0] Q,
output CEO
);
always #(posedge CLK or posedge CLR)
if(CLR)
Q <= 4'd0;
else begin
if(CE) begin
if(Q != 4'd9)
Q <= Q + 1;
else
Q <= 4'd0;
end
end
assign CEO = CE & (Q == 4'd9);
endmodule
SECOND MODULE:
`timescale 1ns / 1ps
module licznik2(
input CLK,
input CLR,
input CE2,
output reg [3:0] Q2,
output CEO2
);
always #(posedge CLK or posedge CLR)
if(CLR)
Q2 <= 4'd0;
else begin
if(CE2) begin
if(Q2 != 4'd9)
Q2 <= Q2 + 1;
else
Q2 <= 4'd0;
end
end
assign CEO2 = CE2 & (Q2 == 4'd9);
endmodule
I ran your code on 2 simulators, and I got compile errors on both. Try your code on EDAPlayground.
To fix the compile errors, I removed the wire declarations in module top. To fix the problem with Z on CEO, I replaced CENABLE with CEO. Here is the new top module:
module top(
input CLK,
input CLR,
input CE,
input CE2,
output reg [3:0] Q,
output reg [3:0] Q2,
output wire CEO,
output CEO2
);
licznik licznik(.CLK(CLK),.CLR(CLR),.CE(CE),.CEO(CEO),.Q(Q));
licznik2 licznik2(.CLK(CLK),.CLR(CLR),.CE2(CEO),.Q2(Q2),.CEO2(CEO2));
endmodule
CE2 is X because it is an undriven input. I think you can just delete it.

Verilog did not give the expected result

I wrote this Verilog code. The inner module is an 8-bit mux, and the top module is used to test the mux. It should display 11110000, but it displayed xxxxxxxx every time. How do I fix this?
module testbench;
reg CLK;
test mytest(CLK);
initial begin
CLK = 1'b0;
#10
CLK = 1'b1;
end
endmodule
module test(CLK);
input CLK;
reg [7:0] in0,in1;
reg sel;
wire [7:0] out;
mux myux(in0,in1,sel,out);
always #(posedge CLK) begin
sel = 1'b0;
in0 = 8'b11110000;
$display("%b",out);
end
endmodule
This is the mux module:
module mux(in0,in1,sel,out);
input sel;
input [7:0] in1,in0;
output [7:0] out;
reg out;
always #(in0,in1,sel) begin
if(sel == 1'b0) begin
out = in0;
end
else begin
out = in1;
end
end
endmodule
The problem is that you did not run your simulation long enough. You only ran it for one clock cycle. Here is one way to change your testbench module to run many clock cycles:
module testbench;
reg CLK;
test mytest(CLK);
initial begin
CLK = 1'b0;
forever #10 CLK =~CLK;
end
initial #1000 $finish;
endmodule
I now see output like this:
xxxxxxxx
11110000
11110000
11110000
11110000
Also, I got a compile error with your code. In your mux module, you should change:
reg out;
to:
reg [7:0] out;

Why is iverilog complaining about my testbench module?

I'm writing a verilog module for my CompSci class and this module specifically is the data memory module. Structurally and analytically, I'm looking at it and it should work based off of the other files that I have, but I'm not sure why this one specifically is acting up and giving me all x's. Hoping a fresh set of eyes can help find the error I missed. Thanks in advance.
datamem.v:
module datamem(Ina, Inb, enable, readwrite, dataOut, clk, rst);
input wire [31:0] Ina;
input wire [31:0] Inb;
input wire enable;
input wire readwrite;
input wire clk;
input wire rst;
reg [31:0] memory[0:65535];
output reg [31:0] dataOut;
always #(memory[Ina]) begin
dataOut = memory[Ina];
end
always #(posedge clk) begin
if(1'b1 == readwrite) begin
memory[Ina] = Inb;
end
end
endmodule
datamem_tb.v:
module datamem_tb();
reg [31:0] Ina;
reg [31:0] Inb;
reg enable;
reg readwrite;
reg clk;
reg rst;
wire [31:0] dataOut;
datamem DUT (Ina, Inb, enable, readwrite, dataOut, clk, rst);
initial
begin
Ina <= 32'd0;
Inb <= 32'd0;
enable <= 0;
readwrite <= 0;
#20 Ina <= 32'd1234;
#20 Inb <= 32'd1234;
#20 Ina <= 32'd0517;
#20 Inb <= 32'd10259;
end
always #(Ina or Inb)
#1 $display("| Ina = %d | Inb = %d | dataOut = %d |", Ina, Inb, dataOut);
endmodule
A few things as to why you are getting all 'x:
You never run the clock, you need to add something like the following to have the clock toggle:
initial begin
clk = 1'b0;
forever #5 clk = ~clk;
end
You never assert readwrite which is required to write to your memory module (you set it to 0 on line 20 and never change it). Without being written to, memory will retain its original value of 'x for every element
Aside from that, there are a few other issues with your module:
Use implicit sensitive lists (instead of always #(memory[inA]) use always #(*))
Use non-blocking assignment for your memory write (memory[inA] <= inB)
Consider using $monitor instead of $display for your print statements to avoid timing issues, and you only need call it at the beginning of your initial block in your testbench (http://referencedesigner.com/tutorials/verilog/verilog_09.php)
Your rst and enable arent connected to anything.
Another example of a memory unit implementation can be found here:
Data memory unit

Always loop Verilog

This my Verilog code to convert the number x into form x=a0*R+a1 ,e.g 51 = 5*10 +1. My code does not work, it cannot enter the always loop.
`timescale 1ns / 1ps
module poly(
input [15:0] r,
input [15:0] x,
output reg[15:0] a1,
output reg [15:0] a0,
output finish,
input clk,
input reset
);
reg [15:0] sum;
assign finish =(sum > x);
always# (posedge clk )
begin
if(reset)
begin
a0 <=0;
sum <=0;
end
else if (!finish)
begin
a0 <=a0+1;
sum <= sum+r;
end
else
a1<=x-sum;
end
initial begin
$monitor ( "a1=%b,a0=%b,finish=%b,reset=%b",a1,a0,finish,reset);
end
endmodule
testbench
`timescale 1ns / 1ps
module tb_p;
reg [15:0] r;
reg [15:0] x;
wire[15:0] a1;
wire [15:0] a0;
wire finish;
reg clk;
reg reset;
initial clk=0;
always #5 clk=!clk;
poly m1(r,x,a1,a0,finish,clk,reset);
initial begin
r<=10;
x <=17;
#1 reset<=1;
#2 reset<=0;
end
endmodule
Since your reset signal is synchronous to the clock, you need to extend it so that it is high for at least one posedge of the clock:
initial begin
r<=10;
x <=17;
#1 reset<=1;
#20 reset<=0;
#500 $finish;
end
Note that I added $finish just so my simulation would end.

Simulation output is all zeroes

My code for the design block and the testbench compiles; however, when I simulate, I'm not getting the correct output. Can anyone tell me where I'm going wrong in my code?
Here is the code for testbench:
module testbench;
reg [511:0]FROM_LS;
reg CLK;
reg [63:0]TO_IF_ID;
initial
begin
CLK= 0;
TO_IF_ID[63:0]=63'b0;
FROM_LS[511:480]= 32'b00011_00000_00100_01100_11100_10111_01;
FROM_LS[479:448]=32'b00_11000_00100_01111_11111_00011_10000;
end
always
begin
#10 CLK= ~ CLK;
//FROM_LS[511:448]= ~ FROM_LS[511:448];
$display("FROM_LS= %b", FROM_LS);
$display("TO_IF_ID= %b", TO_IF_ID);
end
endmodule
and here is the code for the design block:
module inst_line_buffer(input wire [511:0]from_LS,
input wire clk,
output reg [63:0]to_if_id);
parameter mem_size=16;
integer k;
reg [31:0] ilb[0:mem_size-1];
initial
begin
for (k = 0; k < mem_size ; k = k + 1)
begin
ilb[k] = 32'b00;
//$display ("ilb= %b",ilb[k]);
end
end
always #(posedge clk)
begin
ilb[0]= from_LS[511:480];
ilb[1]= from_LS[479:448];
ilb[2]= from_LS[447:416];
ilb[3]= from_LS[415:384];
ilb[4]= from_LS[383:352];
ilb[5]= from_LS[351:320];
ilb[6]= from_LS[319:288];
ilb[7]= from_LS[287:256];
ilb[8]= from_LS[255:224];
ilb[9]= from_LS[223:192];
ilb[10]= from_LS[191:160];
ilb[11]= from_LS[159:128];
ilb[12]= from_LS[127:96];
ilb[13]= from_LS[95:64];
ilb[14]= from_LS[63:32];
ilb[15]= from_LS[31:00];
to_if_id [63:32]= ilb[0];
to_if_id [31:0]= ilb[1];
$display("ilb= %b", ilb[1]);
end
endmodule
I'm expecting that the value of TO_IF_ID should be 0001100000001000110011100101110100110000010001111111110001110000, but I'm getting all zeros.
When you run a simulation on your testbench module, TO_IF_ID is always 0 because you only assigned a value to it once at time 0 in your initial block. If you want the value to change, it needs to be driven somehow.
As Andy pointed out in a comment, you probably meant to instantiate the inst_line_buffer module in your testbench. Verilog will not do this magically for you. But then, you should declare TO_IF_ID as a wire instead of a reg and remove it from the initial block.
module testbench;
reg [511:0]FROM_LS;
reg CLK;
wire [63:0]TO_IF_ID;
inst_line_buffer inst_line_buffer (
.from_LS (FROM_LS),
.clk (CLK),
.to_if_id (TO_IF_ID)
);
initial begin
CLK= 0;
FROM_LS[511:480]= 32'b00011_00000_00100_01100_11100_10111_01;
FROM_LS[479:448]=32'b00_11000_00100_01111_11111_00011_10000;
#500 $finish;
end
always
begin
#10 CLK= ~ CLK;
//FROM_LS[511:448]= ~ FROM_LS[511:448];
$display("FROM_LS= %b", FROM_LS);
$display("TO_IF_ID= %b", TO_IF_ID);
end
endmodule

Resources