Using Xilinx Core Generator – Division in FPGA
Xilinx ISE comes with a number of cores which can be used with their products. While we are working on our Final Year Project at the university we used a number of these cores to make our work easy. In this article I will share my experiences on Xilinx core generator by implementing a division core as an example.
Verilog HDL supports division by a constant such as
· (constant)/ (constant) or
· (variable)/(constant with power of two manner)
But when it goes to division of variable by variable or constant by variable it will not support a simple division and must use separate core (using Xilinx core generator or an advanced module designed by someone else). Look at following example.
module simpleDivision( quo, div, clk ); input clk; input [7:0] div; output reg [7:0] quo = 0; always @ (posedge clk) quo = div/4; endmodule
I used following test bench program to simulate above code and observed that the results will come within single clock cycle as below.
module test_simpleDiv; reg [7:0] div; reg clk; wire [7:0] quo; simpleDivision uut ( .quo(quo), .div(div), .clk(clk) ); initial begin div = 0; clk = 0; #100; #10 div = 20; #10 div = 5; #10 div = 121; #10 div = 13; #30 $finish; end always #5 clk = ~clk; endmodule
Note that the line
always #5 clk = ~clk;
will generate the clock signal with the period of 10ns. Result was as below.
When It goes to (variable/variable) division, Xilinx core generator supports a division core with two modes which can be used with division,
· Radix2 mode
· High Radix mode
I’ll discuss how to generate the radix division core using Xilinx core generator, add a simple wrapper to the core and simulation results of the division.
Division Core with Radix2 algorithm
1. Right Click on your project hierarchy and select new source.
2. From the next window select “IP (CORE Generator Architecture Wizard)”, put a file name and click next.
3. Then expand “Math Functions”, “Dividers”, “Divider Generator” and click next.
4. After some time (depends on the performance of your PC) the core generator will Start. I used following configuration for the core I used in this post.
· Algorithm type: radix2
· Remainder type: remainder
· Operand sign : unsigned
· Divider, Quotient : 10 bits
· Divisor width: 8 bits
· Clocks per Division: 1
You can view the data sheet of the core by clicking the “Datasheet” button and click “Generate button” to generate the core.
Again after some time your core will be generated. Next step is to create wrapper module to hide the complexity of the core. In this case since the core is not much complex (high radix is bit complex than this in my opinion) the wrapper will be simple. You can view the HDL functional model and HDL instantiation template by clicking the options in design tab.
You can use the timing diagram from the data sheet do design your wrapper. Timing model for the above is as below.
Therefore the wrapper and the test bench code will be as below. According to the timing diagram the input data are taken at the positive edge of the clock signal when the rfd flag (ready for data) is up Therefore we can add an always block on clk signal with rfd condition to load data to the dividend and divisor (which is not coded in here). At the same time we can use the positive or negative edge of the clock to load output to the registers. In here we do not use the CE signal.
module divCoreWrap( clk, dataInDvd, dataInDvs, dataOutquo, dataOutrem, ready ); input clk; input [7:0] dataInDvs; input [9:0] dataInDvd; output reg [9:0] dataOutquo; output reg [7:0] dataOutrem; output ready; wire [9:0] quotient; wire [7:0] fractional; wire rfd; always@(posedge clk) begin dataOutquo <= quotient; dataOutrem <= fractional; end dividerModule YourInstanceName ( .clk(clk), // input clk .rfd(ready), // ouput rfd .dividend(dataInDvd), // input [9 : 0] dividend .divisor(dataInDvs), // input [7 : 0] divisor .quotient(quotient), // ouput [9 : 0] quotient .fractional(fractional)); // ouput [7 : 0] fractional endmodule
module test_001; reg clk; reg [9:0] dataInDvd; reg [7:0] dataInDvs; wire [9:0] dataOutquo; wire [7:0] dataOutrem; wire ready; divCoreWrap uut ( .clk(clk), .dataInDvd(dataInDvd), .dataInDvs(dataInDvs), .dataOutquo(dataOutquo), .dataOutrem(dataOutrem), .ready(ready) ); initial begin clk = 0; dataInDvd = 0; dataInDvs = 0; #100; dataInDvd = 105; dataInDvs = 100; #10 dataInDvd = 529; dataInDvs = 10; #200 $finish; end always #5 clk = ~clk; endmodule
As you can see the result will be available at the output after 12 clock cycles after placing data on the input buses.
Hope you have a basic Idea in using Xilinx core generator, writing a wrapper and simulations. Thank you very much for reading.