diff options
author | Clifford Wolf <clifford@clifford.at> | 2013-01-05 11:13:26 +0100 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2013-01-05 11:13:26 +0100 |
commit | 7764d0ba1dcf064ae487ee985c43083a0909e7f4 (patch) | |
tree | 18c05b8729df381af71b707748ce1d605e0df764 /tests |
initial import
Diffstat (limited to 'tests')
367 files changed, 28611 insertions, 0 deletions
diff --git a/tests/asicworld/README b/tests/asicworld/README new file mode 100644 index 00000000..0e96edb7 --- /dev/null +++ b/tests/asicworld/README @@ -0,0 +1 @@ +Borrowed verilog examples from http://www.asic-world.com/. diff --git a/tests/asicworld/code_hdl_models_GrayCounter.v b/tests/asicworld/code_hdl_models_GrayCounter.v new file mode 100644 index 00000000..23f0da04 --- /dev/null +++ b/tests/asicworld/code_hdl_models_GrayCounter.v @@ -0,0 +1,33 @@ +//========================================== +// Function : Code Gray counter. +// Coder : Alex Claros F. +// Date : 15/May/2005. +//======================================= + +module GrayCounter + #(parameter COUNTER_WIDTH = 4) + + (output reg [COUNTER_WIDTH-1:0] GrayCount_out, //'Gray' code count output. + + input wire Enable_in, //Count enable. + input wire Clear_in, //Count reset. + + input wire Clk); + + /////////Internal connections & variables/////// + reg [COUNTER_WIDTH-1:0] BinaryCount; + + /////////Code/////////////////////// + + always @ (posedge Clk) + if (Clear_in) begin + BinaryCount <= {COUNTER_WIDTH{1'b 0}} + 1; //Gray count begins @ '1' with + GrayCount_out <= {COUNTER_WIDTH{1'b 0}}; // first 'Enable_in'. + end + else if (Enable_in) begin + BinaryCount <= BinaryCount + 1; + GrayCount_out <= {BinaryCount[COUNTER_WIDTH-1], + BinaryCount[COUNTER_WIDTH-2:0] ^ BinaryCount[COUNTER_WIDTH-1:1]}; + end + +endmodule diff --git a/tests/asicworld/code_hdl_models_arbiter.v b/tests/asicworld/code_hdl_models_arbiter.v new file mode 100644 index 00000000..978e1987 --- /dev/null +++ b/tests/asicworld/code_hdl_models_arbiter.v @@ -0,0 +1,123 @@ +//----------------------------------------------------
+// A four level, round-robin arbiter. This was
+// orginally coded by WD Peterson in VHDL.
+//----------------------------------------------------
+module arbiter (
+ clk,
+ rst,
+ req3,
+ req2,
+ req1,
+ req0,
+ gnt3,
+ gnt2,
+ gnt1,
+ gnt0
+);
+// --------------Port Declaration-----------------------
+input clk;
+input rst;
+input req3;
+input req2;
+input req1;
+input req0;
+output gnt3;
+output gnt2;
+output gnt1;
+output gnt0;
+
+//--------------Internal Registers----------------------
+wire [1:0] gnt ;
+wire comreq ;
+wire beg ;
+wire [1:0] lgnt ;
+wire lcomreq ;
+reg lgnt0 ;
+reg lgnt1 ;
+reg lgnt2 ;
+reg lgnt3 ;
+reg lasmask ;
+reg lmask0 ;
+reg lmask1 ;
+reg ledge ;
+
+//--------------Code Starts Here-----------------------
+always @ (posedge clk)
+if (rst) begin
+ lgnt0 <= 0;
+ lgnt1 <= 0;
+ lgnt2 <= 0;
+ lgnt3 <= 0;
+end else begin
+ lgnt0 <=(~lcomreq & ~lmask1 & ~lmask0 & ~req3 & ~req2 & ~req1 & req0)
+ | (~lcomreq & ~lmask1 & lmask0 & ~req3 & ~req2 & req0)
+ | (~lcomreq & lmask1 & ~lmask0 & ~req3 & req0)
+ | (~lcomreq & lmask1 & lmask0 & req0 )
+ | ( lcomreq & lgnt0 );
+ lgnt1 <=(~lcomreq & ~lmask1 & ~lmask0 & req1)
+ | (~lcomreq & ~lmask1 & lmask0 & ~req3 & ~req2 & req1 & ~req0)
+ | (~lcomreq & lmask1 & ~lmask0 & ~req3 & req1 & ~req0)
+ | (~lcomreq & lmask1 & lmask0 & req1 & ~req0)
+ | ( lcomreq & lgnt1);
+ lgnt2 <=(~lcomreq & ~lmask1 & ~lmask0 & req2 & ~req1)
+ | (~lcomreq & ~lmask1 & lmask0 & req2)
+ | (~lcomreq & lmask1 & ~lmask0 & ~req3 & req2 & ~req1 & ~req0)
+ | (~lcomreq & lmask1 & lmask0 & req2 & ~req1 & ~req0)
+ | ( lcomreq & lgnt2);
+ lgnt3 <=(~lcomreq & ~lmask1 & ~lmask0 & req3 & ~req2 & ~req1)
+ | (~lcomreq & ~lmask1 & lmask0 & req3 & ~req2)
+ | (~lcomreq & lmask1 & ~lmask0 & req3)
+ | (~lcomreq & lmask1 & lmask0 & req3 & ~req2 & ~req1 & ~req0)
+ | ( lcomreq & lgnt3);
+end
+
+//----------------------------------------------------
+// lasmask state machine.
+//----------------------------------------------------
+assign beg = (req3 | req2 | req1 | req0) & ~lcomreq;
+always @ (posedge clk)
+begin
+ lasmask <= (beg & ~ledge & ~lasmask);
+ ledge <= (beg & ~ledge & lasmask)
+ | (beg & ledge & ~lasmask);
+end
+
+//----------------------------------------------------
+// comreq logic.
+//----------------------------------------------------
+assign lcomreq = ( req3 & lgnt3 )
+ | ( req2 & lgnt2 )
+ | ( req1 & lgnt1 )
+ | ( req0 & lgnt0 );
+
+//----------------------------------------------------
+// Encoder logic.
+//----------------------------------------------------
+assign lgnt = {(lgnt3 | lgnt2),(lgnt3 | lgnt1)};
+
+//----------------------------------------------------
+// lmask register.
+//----------------------------------------------------
+always @ (posedge clk )
+if( rst ) begin
+ lmask1 <= 0;
+ lmask0 <= 0;
+end else if(lasmask) begin
+ lmask1 <= lgnt[1];
+ lmask0 <= lgnt[0];
+end else begin
+ lmask1 <= lmask1;
+ lmask0 <= lmask0;
+end
+
+assign comreq = lcomreq;
+assign gnt = lgnt;
+//----------------------------------------------------
+// Drive the outputs
+//----------------------------------------------------
+assign gnt3 = lgnt3;
+assign gnt2 = lgnt2;
+assign gnt1 = lgnt1;
+assign gnt0 = lgnt0;
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_arbiter_tb.v b/tests/asicworld/code_hdl_models_arbiter_tb.v new file mode 100644 index 00000000..5e7bf46b --- /dev/null +++ b/tests/asicworld/code_hdl_models_arbiter_tb.v @@ -0,0 +1,62 @@ +module testbench (); + +reg clk; +reg rst; +reg req3; +reg req2; +reg req1; +reg req0; +wire gnt3; +wire gnt2; +wire gnt1; +wire gnt0; + +// Clock generator +always #1 clk = ~clk; + +initial begin + $dumpfile ("arbiter.vcd"); + $dumpvars(); + clk = 0; + rst = 1; + req0 = 0; + req1 = 0; + req2 = 0; + req3 = 0; + #10 rst = 0; + repeat (1) @ (posedge clk); + req0 <= 1; + repeat (1) @ (posedge clk); + req0 <= 0; + repeat (1) @ (posedge clk); + req0 <= 1; + req1 <= 1; + repeat (1) @ (posedge clk); + req2 <= 1; + req1 <= 0; + repeat (1) @ (posedge clk); + req3 <= 1; + req2 <= 0; + repeat (1) @ (posedge clk); + req3 <= 0; + repeat (1) @ (posedge clk); + req0 <= 0; + repeat (1) @ (posedge clk); + #10 $finish; +end + +// Connect the DUT +arbiter U ( + clk, + rst, + req3, + req2, + req1, + req0, + gnt3, + gnt2, + gnt1, + gnt0 +); + +endmodule diff --git a/tests/asicworld/code_hdl_models_cam.v b/tests/asicworld/code_hdl_models_cam.v new file mode 100644 index 00000000..0cebc07c --- /dev/null +++ b/tests/asicworld/code_hdl_models_cam.v @@ -0,0 +1,60 @@ +//----------------------------------------------------- +// Design Name : cam +// File Name : cam.v +// Function : CAM +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module cam ( +clk , // Cam clock +cam_enable , // Cam enable +cam_data_in , // Cam data to match +cam_hit_out , // Cam match has happened +cam_addr_out // Cam output address +); + +parameter ADDR_WIDTH = 8; +parameter DEPTH = 1 << ADDR_WIDTH; +//------------Input Ports-------------- +input clk; +input cam_enable; +input [DEPTH-1:0] cam_data_in; +//----------Output Ports-------------- +output cam_hit_out; +output [ADDR_WIDTH-1:0] cam_addr_out; +//------------Internal Variables-------- +reg [ADDR_WIDTH-1:0] cam_addr_out; +reg cam_hit_out; +reg [ADDR_WIDTH-1:0] cam_addr_combo; +reg cam_hit_combo; +reg found_match; +integer i; +//-------------Code Starts Here------- +always @(cam_data_in) begin + cam_addr_combo = {ADDR_WIDTH{1'b0}}; + found_match = 1'b0; + cam_hit_combo = 1'b0; + for (i=0; i<DEPTH; i=i+1) begin + if (cam_data_in[i] && !found_match) begin + found_match = 1'b1; + cam_hit_combo = 1'b1; + cam_addr_combo = i; + end else begin + found_match = found_match; + cam_hit_combo = cam_hit_combo; + cam_addr_combo = cam_addr_combo; + end + end +end + +// Register the outputs +always @(posedge clk) begin + if (cam_enable) begin + cam_hit_out <= cam_hit_combo; + cam_addr_out <= cam_addr_combo; + end else begin + cam_hit_out <= 1'b0; + cam_addr_out <= {ADDR_WIDTH{1'b0}}; + end +end + +endmodule diff --git a/tests/asicworld/code_hdl_models_clk_div.v b/tests/asicworld/code_hdl_models_clk_div.v new file mode 100644 index 00000000..c48ab0dd --- /dev/null +++ b/tests/asicworld/code_hdl_models_clk_div.v @@ -0,0 +1,27 @@ +//----------------------------------------------------- +// Design Name : clk_div +// File Name : clk_div.v +// Function : Divide by two counter +// Coder : Deepak Kumar Tala +//----------------------------------------------------- + +module clk_div (clk_in, enable,reset, clk_out); + // --------------Port Declaration----------------------- + input clk_in ; + input reset ; + input enable ; + output clk_out ; + //--------------Port data type declaration------------- + wire clk_in ; + wire enable ; +//--------------Internal Registers---------------------- +reg clk_out ; +//--------------Code Starts Here----------------------- +always @ (posedge clk_in) +if (reset) begin + clk_out <= 1'b0; +end else if (enable) begin + clk_out <= !clk_out ; +end + +endmodule diff --git a/tests/asicworld/code_hdl_models_clk_div_45.v b/tests/asicworld/code_hdl_models_clk_div_45.v new file mode 100644 index 00000000..d9d28967 --- /dev/null +++ b/tests/asicworld/code_hdl_models_clk_div_45.v @@ -0,0 +1,54 @@ +//----------------------------------------------------- +// Design Name : clk_div_45 +// File Name : clk_div_45.v +// Function : Divide by 4.5 +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module clk_div_45 ( +clk_in, // Input Clock +enable, // Enable is sync with falling edge of clk_in +clk_out // Output Clock +); + +// --------------Port Declaration----------------------- +input clk_in ; +input enable ; +output clk_out ; + +//--------------Port data type declaration------------- +wire clk_in ; +wire enable ; +wire clk_out ; + +//--------------Internal Registers---------------------- +reg [3:0] counter1 ; +reg [3:0] counter2 ; +reg toggle1 ; +reg toggle2 ; + +//--------------Code Starts Here----------------------- +always @ (posedge clk_in) +if (enable == 1'b0) begin + counter1 <= 4'b0; + toggle1 <= 0; +end else if ((counter1 == 3 && toggle2) || (~toggle1 && counter1 == 4)) begin + counter1 <= 4'b0; + toggle1 <= ~toggle1; +end else begin + counter1 <= counter1 + 1; +end + +always @ (negedge clk_in) +if (enable == 1'b0) begin + counter2 <= 4'b0; + toggle2 <= 0; +end else if ((counter2 == 3 && ~toggle2) || (toggle2 && counter2 == 4)) begin + counter2 <= 4'b0; + toggle2 <= ~toggle2; +end else begin + counter2 <= counter2 + 1; +end + +assign clk_out = (counter1 <3 && counter2 < 3) & enable; + +endmodule diff --git a/tests/asicworld/code_hdl_models_d_ff_gates.v b/tests/asicworld/code_hdl_models_d_ff_gates.v new file mode 100644 index 00000000..8706f154 --- /dev/null +++ b/tests/asicworld/code_hdl_models_d_ff_gates.v @@ -0,0 +1,29 @@ +module d_ff_gates(d,clk,q,q_bar); +input d,clk; +output q, q_bar; + +wire n1,n2,n3,q_bar_n; +wire cn,dn,n4,n5,n6; + +// First Latch +not (n1,d); + +nand (n2,d,clk); +nand (n3,n1,clk); + +nand (dn,q_bar_n,n2); +nand (q_bar_n,dn,n3); + +// Second Latch +not (cn,clk); + +not (n4,dn); + +nand (n5,dn,cn); +nand (n6,n4,cn); + +nand (q,q_bar,n5); +nand (q_bar,q,n6); + + +endmodule diff --git a/tests/asicworld/code_hdl_models_d_latch_gates.v b/tests/asicworld/code_hdl_models_d_latch_gates.v new file mode 100644 index 00000000..3f5f6b2b --- /dev/null +++ b/tests/asicworld/code_hdl_models_d_latch_gates.v @@ -0,0 +1,15 @@ +module d_latch_gates(d,clk,q,q_bar); +input d,clk; +output q, q_bar; + +wire n1,n2,n3; + +not (n1,d); + +nand (n2,d,clk); +nand (n3,n1,clk); + +nand (q,q_bar,n2); +nand (q_bar,q,n3); + +endmodule diff --git a/tests/asicworld/code_hdl_models_decoder_2to4_gates.v b/tests/asicworld/code_hdl_models_decoder_2to4_gates.v new file mode 100644 index 00000000..810003a8 --- /dev/null +++ b/tests/asicworld/code_hdl_models_decoder_2to4_gates.v @@ -0,0 +1,14 @@ +module decoder_2to4_gates (x,y,f0,f1,f2,f3); +input x,y; +output f0,f1,f2,f3; + +wire n1,n2; + +not i1 (n1,x); +not i2 (n2,y); +and a1 (f0,n1,n2); +and a2 (f1,n1,y); +and a3 (f2,x,n2); +and a4 (f3,x,y); + +endmodule diff --git a/tests/asicworld/code_hdl_models_decoder_using_assign.v b/tests/asicworld/code_hdl_models_decoder_using_assign.v new file mode 100644 index 00000000..ec0dc95b --- /dev/null +++ b/tests/asicworld/code_hdl_models_decoder_using_assign.v @@ -0,0 +1,20 @@ +//----------------------------------------------------- +// Design Name : decoder_using_assign +// File Name : decoder_using_assign.v +// Function : decoder using assign +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module decoder_using_assign ( +binary_in , // 4 bit binary input +decoder_out , // 16-bit out +enable // Enable for the decoder +); +input [3:0] binary_in ; +input enable ; +output [15:0] decoder_out ; + +wire [15:0] decoder_out ; + +assign decoder_out = (enable) ? (1 << binary_in) : 16'b0 ; + +endmodule diff --git a/tests/asicworld/code_hdl_models_decoder_using_case.v b/tests/asicworld/code_hdl_models_decoder_using_case.v new file mode 100644 index 00000000..ad42acdf --- /dev/null +++ b/tests/asicworld/code_hdl_models_decoder_using_case.v @@ -0,0 +1,43 @@ +//----------------------------------------------------- +// Design Name : decoder_using_case +// File Name : decoder_using_case.v +// Function : decoder using case +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module decoder_using_case ( +binary_in , // 4 bit binary input +decoder_out , // 16-bit out +enable // Enable for the decoder +); +input [3:0] binary_in ; +input enable ; +output [15:0] decoder_out ; + +reg [15:0] decoder_out ; + +always @ (enable or binary_in) +begin + decoder_out = 0; + if (enable) begin + case (binary_in) + 4'h0 : decoder_out = 16'h0001; + 4'h1 : decoder_out = 16'h0002; + 4'h2 : decoder_out = 16'h0004; + 4'h3 : decoder_out = 16'h0008; + 4'h4 : decoder_out = 16'h0010; + 4'h5 : decoder_out = 16'h0020; + 4'h6 : decoder_out = 16'h0040; + 4'h7 : decoder_out = 16'h0080; + 4'h8 : decoder_out = 16'h0100; + 4'h9 : decoder_out = 16'h0200; + 4'hA : decoder_out = 16'h0400; + 4'hB : decoder_out = 16'h0800; + 4'hC : decoder_out = 16'h1000; + 4'hD : decoder_out = 16'h2000; + 4'hE : decoder_out = 16'h4000; + 4'hF : decoder_out = 16'h8000; + endcase + end +end + +endmodule diff --git a/tests/asicworld/code_hdl_models_dff_async_reset.v b/tests/asicworld/code_hdl_models_dff_async_reset.v new file mode 100644 index 00000000..a156082f --- /dev/null +++ b/tests/asicworld/code_hdl_models_dff_async_reset.v @@ -0,0 +1,30 @@ +//----------------------------------------------------- +// Design Name : dff_async_reset +// File Name : dff_async_reset.v +// Function : D flip-flop async reset +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module dff_async_reset ( +data , // Data Input +clk , // Clock Input +reset , // Reset input +q // Q output +); +//-----------Input Ports--------------- +input data, clk, reset ; + +//-----------Output Ports--------------- +output q; + +//------------Internal Variables-------- +reg q; + +//-------------Code Starts Here--------- +always @ ( posedge clk or negedge reset) +if (~reset) begin + q <= 1'b0; +end else begin + q <= data; +end + +endmodule //End Of Module dff_async_reset diff --git a/tests/asicworld/code_hdl_models_dff_sync_reset.v b/tests/asicworld/code_hdl_models_dff_sync_reset.v new file mode 100644 index 00000000..7ef40454 --- /dev/null +++ b/tests/asicworld/code_hdl_models_dff_sync_reset.v @@ -0,0 +1,30 @@ +//----------------------------------------------------- +// Design Name : dff_sync_reset +// File Name : dff_sync_reset.v +// Function : D flip-flop sync reset +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module dff_sync_reset ( +data , // Data Input +clk , // Clock Input +reset , // Reset input +q // Q output +); +//-----------Input Ports--------------- +input data, clk, reset ; + +//-----------Output Ports--------------- +output q; + +//------------Internal Variables-------- +reg q; + +//-------------Code Starts Here--------- +always @ ( posedge clk) +if (~reset) begin + q <= 1'b0; +end else begin + q <= data; +end + +endmodule //End Of Module dff_sync_reset diff --git a/tests/asicworld/code_hdl_models_dlatch_reset.v b/tests/asicworld/code_hdl_models_dlatch_reset.v new file mode 100644 index 00000000..2cfc6fbd --- /dev/null +++ b/tests/asicworld/code_hdl_models_dlatch_reset.v @@ -0,0 +1,30 @@ +//----------------------------------------------------- +// Design Name : dlatch_reset +// File Name : dlatch_reset.v +// Function : DLATCH async reset +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module dlatch_reset ( +data , // Data Input +en , // LatchInput +reset , // Reset input +q // Q output +); +//-----------Input Ports--------------- +input data, en, reset ; + +//-----------Output Ports--------------- +output q; + +//------------Internal Variables-------- +reg q; + +//-------------Code Starts Here--------- +always @ ( en or reset or data) +if (~reset) begin + q <= 1'b0; +end else if (en) begin + q <= data; +end + +endmodule //End Of Module dlatch_reset diff --git a/tests/asicworld/code_hdl_models_encoder_4to2_gates.v b/tests/asicworld/code_hdl_models_encoder_4to2_gates.v new file mode 100644 index 00000000..0bfdc28a --- /dev/null +++ b/tests/asicworld/code_hdl_models_encoder_4to2_gates.v @@ -0,0 +1,8 @@ +module encoder_4to2_gates (i0,i1,i2,i3,y); +input i0,i1,i2,i3; +output [1:0] y; + +or o1 (y[0],i1,i3); +or o2 (y[1],i2,i3); + +endmodule diff --git a/tests/asicworld/code_hdl_models_encoder_using_case.v b/tests/asicworld/code_hdl_models_encoder_using_case.v new file mode 100644 index 00000000..32e1b720 --- /dev/null +++ b/tests/asicworld/code_hdl_models_encoder_using_case.v @@ -0,0 +1,42 @@ +//----------------------------------------------------- +// Design Name : encoder_using_case +// File Name : encoder_using_case.v +// Function : Encoder using Case +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module encoder_using_case( +binary_out , // 4 bit binary Output +encoder_in , // 16-bit Input +enable // Enable for the encoder +); +output [3:0] binary_out ; +input enable ; +input [15:0] encoder_in ; + +reg [3:0] binary_out ; + +always @ (enable or encoder_in) +begin + binary_out = 0; + if (enable) begin + case (encoder_in) + 16'h0002 : binary_out = 1; + 16'h0004 : binary_out = 2; + 16'h0008 : binary_out = 3; + 16'h0010 : binary_out = 4; + 16'h0020 : binary_out = 5; + 16'h0040 : binary_out = 6; + 16'h0080 : binary_out = 7; + 16'h0100 : binary_out = 8; + 16'h0200 : binary_out = 9; + 16'h0400 : binary_out = 10; + 16'h0800 : binary_out = 11; + 16'h1000 : binary_out = 12; + 16'h2000 : binary_out = 13; + 16'h4000 : binary_out = 14; + 16'h8000 : binary_out = 15; + endcase + end +end + +endmodule diff --git a/tests/asicworld/code_hdl_models_encoder_using_if.v b/tests/asicworld/code_hdl_models_encoder_using_if.v new file mode 100644 index 00000000..2c97ddba --- /dev/null +++ b/tests/asicworld/code_hdl_models_encoder_using_if.v @@ -0,0 +1,58 @@ +//----------------------------------------------------- +// Design Name : encoder_using_if +// File Name : encoder_using_if.v +// Function : Encoder using If +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module encoder_using_if( +binary_out , // 4 bit binary output +encoder_in , // 16-bit input +enable // Enable for the encoder +); +//-----------Output Ports--------------- +output [3:0] binary_out ; +//-----------Input Ports--------------- +input enable ; +input [15:0] encoder_in ; +//------------Internal Variables-------- +reg [3:0] binary_out ; +//-------------Code Start----------------- +always @ (enable or encoder_in) + begin + binary_out = 0; + if (enable) begin + if (encoder_in == 16'h0002) begin + binary_out = 1; + end if (encoder_in == 16'h0004) begin + binary_out = 2; + end if (encoder_in == 16'h0008) begin + binary_out = 3; + end if (encoder_in == 16'h0010) begin + binary_out = 4; + end if (encoder_in == 16'h0020) begin + binary_out = 5; + end if (encoder_in == 16'h0040) begin + binary_out = 6; + end if (encoder_in == 16'h0080) begin + binary_out = 7; + end if (encoder_in == 16'h0100) begin + binary_out = 8; + end if (encoder_in == 16'h0200) begin + binary_out = 9; + end if (encoder_in == 16'h0400) begin + binary_out = 10; + end if (encoder_in == 16'h0800) begin + binary_out = 11; + end if (encoder_in == 16'h1000) begin + binary_out = 12; + end if (encoder_in == 16'h2000) begin + binary_out = 13; + end if (encoder_in == 16'h4000) begin + binary_out = 14; + end if (encoder_in == 16'h8000) begin + binary_out = 15; + end + end +end + +endmodule diff --git a/tests/asicworld/code_hdl_models_full_adder_gates.v b/tests/asicworld/code_hdl_models_full_adder_gates.v new file mode 100644 index 00000000..1ddc4c56 --- /dev/null +++ b/tests/asicworld/code_hdl_models_full_adder_gates.v @@ -0,0 +1,18 @@ +//----------------------------------------------------- +// Design Name : full_adder_gates +// File Name : full_adder_gates.v +// Function : Full Adder Using Gates +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module full_adder_gates(x,y,z,sum,carry); +input x,y,z; +output sum,carry; +wire and1,and2,and3,sum1; + +and U_and1 (and1,x,y), + U_and2 (and2,x,z), + U_and3 (and3,y,z); +or U_or (carry,and1,and2,and3); +xor U_sum (sum,x,y,z); + +endmodule diff --git a/tests/asicworld/code_hdl_models_full_subtracter_gates.v b/tests/asicworld/code_hdl_models_full_subtracter_gates.v new file mode 100644 index 00000000..c24588ec --- /dev/null +++ b/tests/asicworld/code_hdl_models_full_subtracter_gates.v @@ -0,0 +1,20 @@ +//----------------------------------------------------- +// Design Name : full_subtracter_gates +// File Name : full_subtracter_gates.v +// Function : Full Subtracter Using Gates +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module full_subtracter_gates(x,y,z,difference,borrow); +input x,y,z; +output difference,borrow; + +wire inv_x,borrow1,borrow2,borrow3; + +not (inv_x,x); +and U_borrow1 (borrow1,inv_x,y), + U_borrow2 (borrow2,inv_x,z), + U_borrow3 (borrow3,y,z); + +xor U_diff (difference,borrow1,borrow2,borrows); + +endmodule diff --git a/tests/asicworld/code_hdl_models_gray_counter.v b/tests/asicworld/code_hdl_models_gray_counter.v new file mode 100644 index 00000000..bc1e740a --- /dev/null +++ b/tests/asicworld/code_hdl_models_gray_counter.v @@ -0,0 +1,33 @@ +//----------------------------------------------------- +// Design Name : gray_counter +// File Name : gray_counter.v +// Function : 8 bit gray counterS +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module gray_counter ( + out , // counter out + enable , // enable for counter + clk , // clock + rst // active hight reset + ); + + //------------Input Ports-------------- + input clk, rst, enable; + //----------Output Ports---------------- + output [ 7:0] out; + //------------Internal Variables-------- + wire [7:0] out; + reg [7:0] count; + //-------------Code Starts Here--------- + always @ (posedge clk) + if (rst) + count <= 0; + else if (enable) + count <= count + 1; + + assign out = { count[7], (count[7] ^ count[6]),(count[6] ^ + count[5]),(count[5] ^ count[4]), (count[4] ^ + count[3]),(count[3] ^ count[2]), (count[2] ^ + count[1]),(count[1] ^ count[0]) }; + +endmodule diff --git a/tests/asicworld/code_hdl_models_half_adder_gates.v b/tests/asicworld/code_hdl_models_half_adder_gates.v new file mode 100644 index 00000000..6acf243f --- /dev/null +++ b/tests/asicworld/code_hdl_models_half_adder_gates.v @@ -0,0 +1,14 @@ +//----------------------------------------------------- +// Design Name : half_adder_gates +// File Name : half_adder_gates.v +// Function : CCITT Serial CRC +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module half_adder_gates(x,y,sum,carry); +input x,y; +output sum,carry; + +and U_carry (carry,x,y); +xor U_sum (sum,x,y); + +endmodule diff --git a/tests/asicworld/code_hdl_models_lfsr.v b/tests/asicworld/code_hdl_models_lfsr.v new file mode 100644 index 00000000..63978083 --- /dev/null +++ b/tests/asicworld/code_hdl_models_lfsr.v @@ -0,0 +1,35 @@ +//----------------------------------------------------- +// Design Name : lfsr +// File Name : lfsr.v +// Function : Linear feedback shift register +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module lfsr ( +out , // Output of the counter +enable , // Enable for counter +clk , // clock input +reset // reset input +); + +//----------Output Ports-------------- +output [7:0] out; +//------------Input Ports-------------- +input enable, clk, reset; +//------------Internal Variables-------- +reg [7:0] out; +wire linear_feedback; + +//-------------Code Starts Here------- +assign linear_feedback = !(out[7] ^ out[3]); + +always @(posedge clk) +if (reset) begin // active high reset + out <= 8'b0 ; +end else if (enable) begin + out <= {out[6],out[5], + out[4],out[3], + out[2],out[1], + out[0], linear_feedback}; +end + +endmodule // End Of Module counter diff --git a/tests/asicworld/code_hdl_models_lfsr_updown.v b/tests/asicworld/code_hdl_models_lfsr_updown.v new file mode 100644 index 00000000..0bd29b83 --- /dev/null +++ b/tests/asicworld/code_hdl_models_lfsr_updown.v @@ -0,0 +1,35 @@ +`define WIDTH 8 +module lfsr_updown ( +clk , // Clock input +reset , // Reset input +enable , // Enable input +up_down , // Up Down input +count , // Count output +overflow // Overflow output +); + + input clk; + input reset; + input enable; + input up_down; + + output [`WIDTH-1 : 0] count; + output overflow; + + reg [`WIDTH-1 : 0] count; + + assign overflow = (up_down) ? (count == {{`WIDTH-1{1'b0}}, 1'b1}) : + (count == {1'b1, {`WIDTH-1{1'b0}}}) ; + + always @(posedge clk) + if (reset) + count <= {`WIDTH{1'b0}}; + else if (enable) begin + if (up_down) begin + count <= {~(^(count & `WIDTH'b01100011)),count[`WIDTH-1:1]}; + end else begin + count <= {count[`WIDTH-2:0],~(^(count & `WIDTH'b10110001))}; + end + end + +endmodule diff --git a/tests/asicworld/code_hdl_models_misc1.v b/tests/asicworld/code_hdl_models_misc1.v new file mode 100644 index 00000000..e3d9d5d6 --- /dev/null +++ b/tests/asicworld/code_hdl_models_misc1.v @@ -0,0 +1,22 @@ +module misc1 (a,b,c,d,y); +input a, b,c,d; +output y; + +wire net1,net2,net3; + +supply1 vdd; +supply0 vss; + +// y = !((a+b+c).d) + +pmos p1 (vdd,net1,a); +pmos p2 (net1,net2,b); +pmos p3 (net2,y,c); +pmos p4 (vdd,y,d); + +nmos n1 (vss,net3,a); +nmos n2 (vss,net3,b); +nmos n3 (vss,net3,c); +nmos n4 (net3,y,d); + +endmodule diff --git a/tests/asicworld/code_hdl_models_mux21_switch.v b/tests/asicworld/code_hdl_models_mux21_switch.v new file mode 100644 index 00000000..519c07fc --- /dev/null +++ b/tests/asicworld/code_hdl_models_mux21_switch.v @@ -0,0 +1,22 @@ +//----------------------------------------------------- +// Design Name : mux21_switch +// File Name : mux21_switch.v +// Function : 2:1 Mux using Switch Primitives +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module mux21_switch (out, ctrl, in1, in2); + + output out; + input ctrl, in1, in2; + wire w; + + supply1 power; + supply0 ground; + + pmos N1 (w, power, ctrl); + nmos N2 (w, ground, ctrl); + + cmos C1 (out, in1, w, ctrl); + cmos C2 (out, in2, ctrl, w); + +endmodule diff --git a/tests/asicworld/code_hdl_models_mux_2to1_gates.v b/tests/asicworld/code_hdl_models_mux_2to1_gates.v new file mode 100644 index 00000000..fc762159 --- /dev/null +++ b/tests/asicworld/code_hdl_models_mux_2to1_gates.v @@ -0,0 +1,18 @@ +//----------------------------------------------------- +// Design Name : mux_2to1_gates +// File Name : mux_2to1_gates.v +// Function : 2:1 Mux using Gate Primitives +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module mux_2to1_gates(a,b,sel,y); +input a,b,sel; +output y; + +wire sel,a_sel,b_sel; + +not U_inv (inv_sel,sel); +and U_anda (asel,a,inv_sel), + U_andb (bsel,b,sel); +or U_or (y,asel,bsel); + +endmodule diff --git a/tests/asicworld/code_hdl_models_mux_using_assign.v b/tests/asicworld/code_hdl_models_mux_using_assign.v new file mode 100644 index 00000000..4284f10c --- /dev/null +++ b/tests/asicworld/code_hdl_models_mux_using_assign.v @@ -0,0 +1,22 @@ +//----------------------------------------------------- +// Design Name : mux_using_assign +// File Name : mux_using_assign.v +// Function : 2:1 Mux using Assign +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module mux_using_assign( +din_0 , // Mux first input +din_1 , // Mux Second input +sel , // Select input +mux_out // Mux output +); +//-----------Input Ports--------------- +input din_0, din_1, sel ; +//-----------Output Ports--------------- +output mux_out; +//------------Internal Variables-------- +wire mux_out; +//-------------Code Start----------------- +assign mux_out = (sel) ? din_1 : din_0; + +endmodule //End Of Module mux diff --git a/tests/asicworld/code_hdl_models_mux_using_case.v b/tests/asicworld/code_hdl_models_mux_using_case.v new file mode 100644 index 00000000..123da448 --- /dev/null +++ b/tests/asicworld/code_hdl_models_mux_using_case.v @@ -0,0 +1,28 @@ +//----------------------------------------------------- +// Design Name : mux_using_case +// File Name : mux_using_case.v +// Function : 2:1 Mux using Case +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module mux_using_case( +din_0 , // Mux first input +din_1 , // Mux Second input +sel , // Select input +mux_out // Mux output +); +//-----------Input Ports--------------- +input din_0, din_1, sel ; +//-----------Output Ports--------------- +output mux_out; +//------------Internal Variables-------- +reg mux_out; +//-------------Code Starts Here--------- +always @ (sel or din_0 or din_1) +begin : MUX + case(sel ) + 1'b0 : mux_out = din_0; + 1'b1 : mux_out = din_1; + endcase +end + +endmodule //End Of Module mux diff --git a/tests/asicworld/code_hdl_models_mux_using_if.v b/tests/asicworld/code_hdl_models_mux_using_if.v new file mode 100644 index 00000000..4d42e208 --- /dev/null +++ b/tests/asicworld/code_hdl_models_mux_using_if.v @@ -0,0 +1,29 @@ +//----------------------------------------------------- +// Design Name : mux_using_if +// File Name : mux_using_if.v +// Function : 2:1 Mux using If +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module mux_using_if( +din_0 , // Mux first input +din_1 , // Mux Second input +sel , // Select input +mux_out // Mux output +); +//-----------Input Ports--------------- +input din_0, din_1, sel ; +//-----------Output Ports--------------- +output mux_out; +//------------Internal Variables-------- +reg mux_out; +//-------------Code Starts Here--------- +always @ (sel or din_0 or din_1) +begin : MUX + if (sel == 1'b0) begin + mux_out = din_0; + end else begin + mux_out = din_1 ; + end +end + +endmodule //End Of Module mux diff --git a/tests/asicworld/code_hdl_models_nand_switch.v b/tests/asicworld/code_hdl_models_nand_switch.v new file mode 100644 index 00000000..1ccdd3a7 --- /dev/null +++ b/tests/asicworld/code_hdl_models_nand_switch.v @@ -0,0 +1,14 @@ +module nand_switch(a,b,out); +input a,b; +output out; + +supply0 vss; +supply1 vdd; +wire net1; + +pmos p1 (vdd,out,a); +pmos p2 (vdd,out,b); +nmos n1 (vss,net1,a); +nmos n2 (net1,out,b); + +endmodule
\ No newline at end of file diff --git a/tests/asicworld/code_hdl_models_one_hot_cnt.v b/tests/asicworld/code_hdl_models_one_hot_cnt.v new file mode 100644 index 00000000..f6b84c6e --- /dev/null +++ b/tests/asicworld/code_hdl_models_one_hot_cnt.v @@ -0,0 +1,31 @@ +//----------------------------------------------------- +// Design Name : one_hot_cnt +// File Name : one_hot_cnt.v +// Function : 8 bit one hot counter +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module one_hot_cnt ( +out , // Output of the counter +enable , // enable for counter +clk , // clock input +reset // reset input +); +//----------Output Ports-------------- +output [7:0] out; + +//------------Input Ports-------------- +input enable, clk, reset; + +//------------Internal Variables-------- +reg [7:0] out; + +//-------------Code Starts Here------- +always @ (posedge clk) +if (reset) begin + out <= 8'b0000_0001 ; +end else if (enable) begin + out <= {out[6],out[5],out[4],out[3], + out[2],out[1],out[0],out[7]}; +end + +endmodule diff --git a/tests/asicworld/code_hdl_models_parallel_crc.v b/tests/asicworld/code_hdl_models_parallel_crc.v new file mode 100644 index 00000000..d8d0bf1c --- /dev/null +++ b/tests/asicworld/code_hdl_models_parallel_crc.v @@ -0,0 +1,53 @@ +//----------------------------------------------------- +// Design Name : parallel_crc_ccitt +// File Name : parallel_crc.v +// Function : CCITT Parallel CRC +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module parallel_crc_ccitt ( +clk , +reset , +enable , +init , +data_in , +crc_out +); +//-----------Input Ports--------------- +input clk ; +input reset ; +input enable ; +input init ; +input [7:0] data_in ; +//-----------Output Ports--------------- +output [15:0] crc_out; +//------------Internal Variables-------- +reg [15:0] crc_reg; +wire [15:0] next_crc; +//-------------Code Start----------------- +assign crc_out = crc_reg; +// CRC Control logic +always @ (posedge clk) +if (reset) begin + crc_reg <= 16'hFFFF; +end else if (enable) begin + if (init) begin + crc_reg <= 16'hFFFF; + end else begin + crc_reg <= next_crc; + end +end +// Parallel CRC calculation +assign next_crc[0] = data_in[7] ^ data_in[0] ^ crc_reg[4] ^ crc_reg[11]; +assign next_crc[1] = data_in[1] ^ crc_reg[5]; +assign next_crc[2] = data_in[2] ^ crc_reg[6]; +assign next_crc[3] = data_in[3] ^ crc_reg[7]; +assign next_crc[4] = data_in[4] ^ crc_reg[8]; +assign next_crc[5] = data_in[7] ^ data_in[5] ^ data_in[0] ^ crc_reg[4] ^ crc_reg[9] ^ crc_reg[11]; +assign next_crc[6] = data_in[6] ^ data_in[1] ^ crc_reg[5] ^ crc_reg[10]; +assign next_crc[7] = data_in[7] ^ data_in[2] ^ crc_reg[6] ^ crc_reg[11]; +assign next_crc[8] = data_in[3] ^ crc_reg[0] ^ crc_reg[7]; +assign next_crc[9] = data_in[4] ^ crc_reg[1] ^ crc_reg[8]; +assign next_crc[10] = data_in[5] ^ crc_reg[2] ^ crc_reg[9]; +assign next_crc[11] = data_in[6] ^ crc_reg[3] ^ crc_reg[10]; + +endmodule diff --git a/tests/asicworld/code_hdl_models_parity_using_assign.v b/tests/asicworld/code_hdl_models_parity_using_assign.v new file mode 100644 index 00000000..b0282e8d --- /dev/null +++ b/tests/asicworld/code_hdl_models_parity_using_assign.v @@ -0,0 +1,21 @@ +//----------------------------------------------------- +// Design Name : parity_using_assign +// File Name : parity_using_assign.v +// Function : Parity using assign +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module parity_using_assign ( +data_in , // 8 bit data in +parity_out // 1 bit parity out +); +output parity_out ; +input [7:0] data_in ; + +wire parity_out ; + +assign parity_out = (data_in[0] ^ data_in[1]) ^ + (data_in[2] ^ data_in[3]) ^ + (data_in[4] ^ data_in[5]) ^ + (data_in[6] ^ data_in[7]); + +endmodule diff --git a/tests/asicworld/code_hdl_models_parity_using_bitwise.v b/tests/asicworld/code_hdl_models_parity_using_bitwise.v new file mode 100644 index 00000000..0046fb14 --- /dev/null +++ b/tests/asicworld/code_hdl_models_parity_using_bitwise.v @@ -0,0 +1,16 @@ +//----------------------------------------------------- +// Design Name : parity_using_bitwise +// File Name : parity_using_bitwise.v +// Function : Parity using bitwise xor +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module parity_using_bitwise ( +data_in , // 8 bit data in +parity_out // 1 bit parity out +); +output parity_out ; +input [7:0] data_in ; + +assign parity_out = ^data_in; + +endmodule diff --git a/tests/asicworld/code_hdl_models_parity_using_function.v b/tests/asicworld/code_hdl_models_parity_using_function.v new file mode 100644 index 00000000..0d07aaeb --- /dev/null +++ b/tests/asicworld/code_hdl_models_parity_using_function.v @@ -0,0 +1,29 @@ +//----------------------------------------------------- +// Design Name : parity_using_function +// File Name : parity_using_function.v +// Function : Parity using function +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module parity_using_function ( +data_in , // 8 bit data in +parity_out // 1 bit parity out +); +output parity_out ; +input [7:0] data_in ; + +wire parity_out ; + +function parity; + input [31:0] data; + begin + parity = (data_in[0] ^ data_in[1]) ^ + (data_in[2] ^ data_in[3]) ^ + (data_in[4] ^ data_in[5]) ^ + (data_in[6] ^ data_in[7]); + end +endfunction + + +assign parity_out = parity(data_in); + +endmodule diff --git a/tests/asicworld/code_hdl_models_pri_encoder_using_assign.v b/tests/asicworld/code_hdl_models_pri_encoder_using_assign.v new file mode 100644 index 00000000..c1ce960c --- /dev/null +++ b/tests/asicworld/code_hdl_models_pri_encoder_using_assign.v @@ -0,0 +1,36 @@ +//----------------------------------------------------- +// Design Name : pri_encoder_using_assign +// File Name : pri_encoder_using_assign.v +// Function : Pri Encoder using assign +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module pri_encoder_using_assign ( +binary_out , // 4 bit binary output +encoder_in , // 16-bit input +enable // Enable for the encoder +); + +output [3:0] binary_out ; +input enable ; +input [15:0] encoder_in ; + +wire [3:0] binary_out ; + +assign binary_out = (!enable) ? 0 : ( + (encoder_in == 16'bxxxx_xxxx_xxxx_xxx1) ? 0 : + (encoder_in == 16'bxxxx_xxxx_xxxx_xx10) ? 1 : + (encoder_in == 16'bxxxx_xxxx_xxxx_x100) ? 2 : + (encoder_in == 16'bxxxx_xxxx_xxxx_1000) ? 3 : + (encoder_in == 16'bxxxx_xxxx_xxx1_0000) ? 4 : + (encoder_in == 16'bxxxx_xxxx_xx10_0000) ? 5 : + (encoder_in == 16'bxxxx_xxxx_x100_0000) ? 6 : + (encoder_in == 16'bxxxx_xxxx_1000_0000) ? 7 : + (encoder_in == 16'bxxxx_xxx1_0000_0000) ? 8 : + (encoder_in == 16'bxxxx_xx10_0000_0000) ? 9 : + (encoder_in == 16'bxxxx_x100_0000_0000) ? 10 : + (encoder_in == 16'bxxxx_1000_0000_0000) ? 11 : + (encoder_in == 16'bxxx1_0000_0000_0000) ? 12 : + (encoder_in == 16'bxx10_0000_0000_0000) ? 13 : + (encoder_in == 16'bx100_0000_0000_0000) ? 14 : 15); + +endmodule diff --git a/tests/asicworld/code_hdl_models_ram_sp_ar_sw.v b/tests/asicworld/code_hdl_models_ram_sp_ar_sw.v new file mode 100644 index 00000000..d3338f74 --- /dev/null +++ b/tests/asicworld/code_hdl_models_ram_sp_ar_sw.v @@ -0,0 +1,58 @@ +//----------------------------------------------------- +// Design Name : ram_sp_ar_sw +// File Name : ram_sp_ar_sw.v +// Function : Asynchronous read write RAM +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module ram_sp_ar_sw ( +clk , // Clock Input +address , // Address Input +data , // Data bi-directional +cs , // Chip Select +we , // Write Enable/Read Enable +oe // Output Enable +); + +parameter DATA_WIDTH = 8 ; +parameter ADDR_WIDTH = 8 ; +parameter RAM_DEPTH = 1 << ADDR_WIDTH; + +//--------------Input Ports----------------------- +input clk ; +input [ADDR_WIDTH-1:0] address ; +input cs ; +input we ; +input oe ; + +//--------------Inout Ports----------------------- +inout [DATA_WIDTH-1:0] data ; + +//--------------Internal variables---------------- +reg [DATA_WIDTH-1:0] data_out ; +reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; + +//--------------Code Starts Here------------------ + +// Tri-State Buffer control +// output : When we = 0, oe = 1, cs = 1 +assign data = (cs && oe && !we) ? data_out : 8'bz; + +// Memory Write Block +// Write Operation : When we = 1, cs = 1 +always @ (posedge clk) +begin : MEM_WRITE + if ( cs && we ) begin + mem[address] = data; + end +end + +// Memory Read Block +// Read Operation : When we = 0, oe = 1, cs = 1 +always @ (address or cs or we or oe) +begin : MEM_READ + if (cs && !we && oe) begin + data_out = mem[address]; + end +end + +endmodule // End of Module ram_sp_ar_sw diff --git a/tests/asicworld/code_hdl_models_ram_sp_sr_sw.v b/tests/asicworld/code_hdl_models_ram_sp_sr_sw.v new file mode 100644 index 00000000..c7fd9554 --- /dev/null +++ b/tests/asicworld/code_hdl_models_ram_sp_sr_sw.v @@ -0,0 +1,62 @@ +//----------------------------------------------------- +// Design Name : ram_sp_sr_sw +// File Name : ram_sp_sr_sw.v +// Function : Synchronous read write RAM +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module ram_sp_sr_sw ( +clk , // Clock Input +address , // Address Input +data , // Data bi-directional +cs , // Chip Select +we , // Write Enable/Read Enable +oe // Output Enable +); + +parameter DATA_WIDTH = 8 ; +parameter ADDR_WIDTH = 8 ; +parameter RAM_DEPTH = 1 << ADDR_WIDTH; + +//--------------Input Ports----------------------- +input clk ; +input [ADDR_WIDTH-1:0] address ; +input cs ; +input we ; +input oe ; + +//--------------Inout Ports----------------------- +inout [DATA_WIDTH-1:0] data ; + +//--------------Internal variables---------------- +reg [DATA_WIDTH-1:0] data_out ; +reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; +reg oe_r; + +//--------------Code Starts Here------------------ + +// Tri-State Buffer control +// output : When we = 0, oe = 1, cs = 1 +assign data = (cs && oe && !we) ? data_out : 8'bz; + +// Memory Write Block +// Write Operation : When we = 1, cs = 1 +always @ (posedge clk) +begin : MEM_WRITE + if ( cs && we ) begin + mem[address] = data; + end +end + +// Memory Read Block +// Read Operation : When we = 0, oe = 1, cs = 1 +always @ (posedge clk) +begin : MEM_READ + if (cs && !we && oe) begin + data_out = mem[address]; + oe_r = 1; + end else begin + oe_r = 0; + end +end + +endmodule // End of Module ram_sp_sr_sw diff --git a/tests/asicworld/code_hdl_models_rom_using_case.v b/tests/asicworld/code_hdl_models_rom_using_case.v new file mode 100644 index 00000000..6b700993 --- /dev/null +++ b/tests/asicworld/code_hdl_models_rom_using_case.v @@ -0,0 +1,42 @@ +//----------------------------------------------------- +// Design Name : rom_using_case +// File Name : rom_using_case.v +// Function : ROM using case +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module rom_using_case ( +address , // Address input +data , // Data output +read_en , // Read Enable +ce // Chip Enable +); +input [3:0] address; +output [7:0] data; +input read_en; +input ce; + +reg [7:0] data ; + +always @ (ce or read_en or address) +begin + case (address) + 0 : data = 10; + 1 : data = 55; + 2 : data = 244; + 3 : data = 0; + 4 : data = 1; + 5 : data = 8'hff; + 6 : data = 8'h11; + 7 : data = 8'h1; + 8 : data = 8'h10; + 9 : data = 8'h0; + 10 : data = 8'h10; + 11 : data = 8'h15; + 12 : data = 8'h60; + 13 : data = 8'h90; + 14 : data = 8'h70; + 15 : data = 8'h90; + endcase +end + +endmodule diff --git a/tests/asicworld/code_hdl_models_serial_crc.v b/tests/asicworld/code_hdl_models_serial_crc.v new file mode 100644 index 00000000..a4a63a26 --- /dev/null +++ b/tests/asicworld/code_hdl_models_serial_crc.v @@ -0,0 +1,54 @@ +//----------------------------------------------------- +// Design Name : serial_crc_ccitt +// File Name : serial_crc.v +// Function : CCITT Serial CRC +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module serial_crc_ccitt ( +clk , +reset , +enable , +init , +data_in , +crc_out +); +//-----------Input Ports--------------- +input clk ; +input reset ; +input enable ; +input init ; +input data_in ; +//-----------Output Ports--------------- +output [15:0] crc_out; +//------------Internal Variables-------- +reg [15:0] lfsr; +//-------------Code Start----------------- +assign crc_out = lfsr; +// Logic to CRC Calculation +always @ (posedge clk) +if (reset) begin + lfsr <= 16'hFFFF; +end else if (enable) begin + if (init) begin + lfsr <= 16'hFFFF; + end else begin + lfsr[0] <= data_in ^ lfsr[15]; + lfsr[1] <= lfsr[0]; + lfsr[2] <= lfsr[1]; + lfsr[3] <= lfsr[2]; + lfsr[4] <= lfsr[3]; + lfsr[5] <= lfsr[4] ^ data_in ^ lfsr[15]; + lfsr[6] <= lfsr[5]; + lfsr[7] <= lfsr[6]; + lfsr[8] <= lfsr[7]; + lfsr[9] <= lfsr[8]; + lfsr[10] <= lfsr[9]; + lfsr[11] <= lfsr[10]; + lfsr[12] <= lfsr[11] ^ data_in ^ lfsr[15]; + lfsr[13] <= lfsr[12]; + lfsr[14] <= lfsr[13]; + lfsr[15] <= lfsr[14]; + end +end + +endmodule diff --git a/tests/asicworld/code_hdl_models_t_gate_switch.v b/tests/asicworld/code_hdl_models_t_gate_switch.v new file mode 100644 index 00000000..1bff66af --- /dev/null +++ b/tests/asicworld/code_hdl_models_t_gate_switch.v @@ -0,0 +1,11 @@ +module t_gate_switch (L,R,nC,C);
+ inout L;
+ inout R;
+ input nC;
+ input C;
+
+ //Syntax: keyword unique_name (drain. source, gate);
+ pmos p1 (L,R,nC);
+ nmos p2 (L,R,C);
+
+endmodule
diff --git a/tests/asicworld/code_hdl_models_tff_async_reset.v b/tests/asicworld/code_hdl_models_tff_async_reset.v new file mode 100644 index 00000000..4c5a1fa9 --- /dev/null +++ b/tests/asicworld/code_hdl_models_tff_async_reset.v @@ -0,0 +1,27 @@ +//----------------------------------------------------- +// Design Name : tff_async_reset +// File Name : tff_async_reset.v +// Function : T flip-flop async reset +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module tff_async_reset ( +data , // Data Input +clk , // Clock Input +reset , // Reset input +q // Q output +); +//-----------Input Ports--------------- +input data, clk, reset ; +//-----------Output Ports--------------- +output q; +//------------Internal Variables-------- +reg q; +//-------------Code Starts Here--------- +always @ ( posedge clk or negedge reset) +if (~reset) begin + q <= 1'b0; +end else if (data) begin + q <= !q; +end + +endmodule //End Of Module tff_async_reset diff --git a/tests/asicworld/code_hdl_models_tff_sync_reset.v b/tests/asicworld/code_hdl_models_tff_sync_reset.v new file mode 100644 index 00000000..a962d53d --- /dev/null +++ b/tests/asicworld/code_hdl_models_tff_sync_reset.v @@ -0,0 +1,27 @@ +//----------------------------------------------------- +// Design Name : tff_sync_reset +// File Name : tff_sync_reset.v +// Function : T flip-flop sync reset +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module tff_sync_reset ( +data , // Data Input +clk , // Clock Input +reset , // Reset input +q // Q output +); +//-----------Input Ports--------------- +input data, clk, reset ; +//-----------Output Ports--------------- +output q; +//------------Internal Variables-------- +reg q; +//-------------Code Starts Here--------- +always @ ( posedge clk) +if (~reset) begin + q <= 1'b0; +end else if (data) begin + q <= !q; +end + +endmodule //End Of Module tff_async_reset diff --git a/tests/asicworld/code_hdl_models_uart.v b/tests/asicworld/code_hdl_models_uart.v new file mode 100644 index 00000000..40205250 --- /dev/null +++ b/tests/asicworld/code_hdl_models_uart.v @@ -0,0 +1,154 @@ +//----------------------------------------------------- +// Design Name : uart +// File Name : uart.v +// Function : Simple UART +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module uart ( +reset , +txclk , +ld_tx_data , +tx_data , +tx_enable , +tx_out , +tx_empty , +rxclk , +uld_rx_data , +rx_data , +rx_enable , +rx_in , +rx_empty +); +// Port declarations +input reset ; +input txclk ; +input ld_tx_data ; +input [7:0] tx_data ; +input tx_enable ; +output tx_out ; +output tx_empty ; +input rxclk ; +input uld_rx_data ; +output [7:0] rx_data ; +input rx_enable ; +input rx_in ; +output rx_empty ; + +// Internal Variables +reg [7:0] tx_reg ; +reg tx_empty ; +reg tx_over_run ; +reg [3:0] tx_cnt ; +reg tx_out ; +reg [7:0] rx_reg ; +reg [7:0] rx_data ; +reg [3:0] rx_sample_cnt ; +reg [3:0] rx_cnt ; +reg rx_frame_err ; +reg rx_over_run ; +reg rx_empty ; +reg rx_d1 ; +reg rx_d2 ; +reg rx_busy ; + +// UART RX Logic +always @ (posedge rxclk or posedge reset) +if (reset) begin + rx_reg <= 0; + rx_data <= 0; + rx_sample_cnt <= 0; + rx_cnt <= 0; + rx_frame_err <= 0; + rx_over_run <= 0; + rx_empty <= 1; + rx_d1 <= 1; + rx_d2 <= 1; + rx_busy <= 0; +end else begin + // Synchronize the asynch signal + rx_d1 <= rx_in; + rx_d2 <= rx_d1; + // Uload the rx data + if (uld_rx_data) begin + rx_data <= rx_reg; + rx_empty <= 1; + end + // Receive data only when rx is enabled + if (rx_enable) begin + // Check if just received start of frame + if (!rx_busy && !rx_d2) begin + rx_busy <= 1; + rx_sample_cnt <= 1; + rx_cnt <= 0; + end + // Start of frame detected, Proceed with rest of data + if (rx_busy) begin + rx_sample_cnt <= rx_sample_cnt + 1; + // Logic to sample at middle of data + if (rx_sample_cnt == 7) begin + if ((rx_d2 == 1) && (rx_cnt == 0)) begin + rx_busy <= 0; + end else begin + rx_cnt <= rx_cnt + 1; + // Start storing the rx data + if (rx_cnt > 0 && rx_cnt < 9) begin + rx_reg[rx_cnt - 1] <= rx_d2; + end + if (rx_cnt == 9) begin + rx_busy <= 0; + // Check if End of frame received correctly + if (rx_d2 == 0) begin + rx_frame_err <= 1; + end else begin + rx_empty <= 0; + rx_frame_err <= 0; + // Check if last rx data was not unloaded, + rx_over_run <= (rx_empty) ? 0 : 1; + end + end + end + end + end + end + if (!rx_enable) begin + rx_busy <= 0; + end +end + +// UART TX Logic +always @ (posedge txclk or posedge reset) +if (reset) begin + tx_reg <= 0; + tx_empty <= 1; + tx_over_run <= 0; + tx_out <= 1; + tx_cnt <= 0; +end else begin + if (ld_tx_data) begin + if (!tx_empty) begin + tx_over_run <= 0; + end else begin + tx_reg <= tx_data; + tx_empty <= 0; + end + end + if (tx_enable && !tx_empty) begin + tx_cnt <= tx_cnt + 1; + if (tx_cnt == 0) begin + tx_out <= 0; + end + if (tx_cnt > 0 && tx_cnt < 9) begin + tx_out <= tx_reg[tx_cnt -1]; + end + if (tx_cnt == 9) begin + tx_out <= 1; + tx_cnt <= 0; + tx_empty <= 1; + end + end + if (!tx_enable) begin + tx_cnt <= 0; + end +end + +endmodule diff --git a/tests/asicworld/code_hdl_models_up_counter.v b/tests/asicworld/code_hdl_models_up_counter.v new file mode 100644 index 00000000..ffe67099 --- /dev/null +++ b/tests/asicworld/code_hdl_models_up_counter.v @@ -0,0 +1,29 @@ +//----------------------------------------------------- +// Design Name : up_counter +// File Name : up_counter.v +// Function : Up counter +// Coder : Deepak +//----------------------------------------------------- +module up_counter ( +out , // Output of the counter +enable , // enable for counter +clk , // clock Input +reset // reset Input +); +//----------Output Ports-------------- + output [7:0] out; +//------------Input Ports-------------- + input enable, clk, reset; +//------------Internal Variables-------- + reg [7:0] out; +//-------------Code Starts Here------- +always @(posedge clk) +if (reset) begin + out <= 8'b0 ; +end else if (enable) begin + out <= out + 1; +end + + +endmodule + diff --git a/tests/asicworld/code_hdl_models_up_counter_load.v b/tests/asicworld/code_hdl_models_up_counter_load.v new file mode 100644 index 00000000..92ad895a --- /dev/null +++ b/tests/asicworld/code_hdl_models_up_counter_load.v @@ -0,0 +1,32 @@ +//----------------------------------------------------- +// Design Name : up_counter_load +// File Name : up_counter_load.v +// Function : Up counter with load +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module up_counter_load ( +out , // Output of the counter +data , // Parallel load for the counter +load , // Parallel load enable +enable , // Enable counting +clk , // clock input +reset // reset input +); +//----------Output Ports-------------- +output [7:0] out; +//------------Input Ports-------------- +input [7:0] data; +input load, enable, clk, reset; +//------------Internal Variables-------- +reg [7:0] out; +//-------------Code Starts Here------- +always @(posedge clk) +if (reset) begin + out <= 8'b0 ; +end else if (load) begin + out <= data; +end else if (enable) begin + out <= out + 1; +end + +endmodule diff --git a/tests/asicworld/code_hdl_models_up_down_counter.v b/tests/asicworld/code_hdl_models_up_down_counter.v new file mode 100644 index 00000000..fff2982a --- /dev/null +++ b/tests/asicworld/code_hdl_models_up_down_counter.v @@ -0,0 +1,29 @@ +//----------------------------------------------------- +// Design Name : up_down_counter +// File Name : up_down_counter.v +// Function : Up down counter +// Coder : Deepak Kumar Tala +//----------------------------------------------------- +module up_down_counter ( +out , // Output of the counter +up_down , // up_down control for counter +clk , // clock input +reset // reset input +); +//----------Output Ports-------------- +output [7:0] out; +//------------Input Ports-------------- +input up_down, clk, reset; +//------------Internal Variables-------- +reg [7:0] out; +//-------------Code Starts Here------- +always @(posedge clk) +if (reset) begin // active high reset + out <= 8'b0 ; +end else if (up_down) begin + out <= out + 1; +end else begin + out <= out - 1; +end + +endmodule diff --git a/tests/asicworld/code_specman_switch_fabric.v b/tests/asicworld/code_specman_switch_fabric.v new file mode 100644 index 00000000..1ac7ee70 --- /dev/null +++ b/tests/asicworld/code_specman_switch_fabric.v @@ -0,0 +1,82 @@ +module switch_fabric( + clk, reset, data_in0, data_in1, data_in2, + data_in3, data_in4, data_in5, data_in_valid0, + data_in_valid1, data_in_valid2, data_in_valid3, + data_in_valid4, data_in_valid5, data_out0, + data_out1, data_out2, data_out3, data_out4, + data_out5, data_out_ack0, data_out_ack1, + data_out_ack2, data_out_ack3, data_out_ack4, + data_out_ack5 +); + +input clk, reset; +input [7:0] data_in0, data_in1, data_in2, data_in3; +input [7:0] data_in4, data_in5; +input data_in_valid0, data_in_valid1, data_in_valid2; +input [7:0] data_in_valid3, data_in_valid4, data_in_valid5; +output [7:0] data_out0, data_out1, data_out2, data_out3; +output [7:0] data_out4, data_out5; +output data_out_ack0, data_out_ack1, data_out_ack2; +output [7:0] data_out_ack3, data_out_ack4, data_out_ack5; + +(* gentb_clock *) +wire clk; + +switch port_0 ( .clk(clk), .reset(reset), .data_in(data_in0), + .data_in_valid(data_in_valid0), .data_out(data_out0), + .data_out_ack(data_out_ack0)); + +switch port_1 ( .clk(clk), .reset(reset), .data_in(data_in1), + .data_in_valid(data_in_valid1), .data_out(data_out1), + .data_out_ack(data_out_ack1)); + +switch port_2 ( .clk(clk), .reset(reset), .data_in(data_in2), + .data_in_valid(data_in_valid2), .data_out(data_out2), . + data_out_ack(data_out_ack2)); + +switch port_3 ( .clk(clk), .reset(reset), .data_in(data_in3), + .data_in_valid(data_in_valid3), .data_out(data_out3), + .data_out_ack(data_out_ack3)); + +switch port_4 ( .clk(clk), .reset(reset), .data_in(data_in4), + .data_in_valid(data_in_valid4), .data_out(data_out4), + .data_out_ack(data_out_ack4)); + +switch port_5 ( .clk(clk), .reset(reset), .data_in(data_in5), + .data_in_valid(data_in_valid5), .data_out(data_out5), + .data_out_ack(data_out_ack5)); + +endmodule + +module switch ( + clk, + reset, + data_in, + data_in_valid, + data_out, + data_out_ack +); + +input clk; +input reset; +input [7:0] data_in; +input data_in_valid; +output [7:0] data_out; +output data_out_ack; + +reg [7:0] data_out; +reg data_out_ack; + +always @ (posedge clk) +if (reset) begin + data_out <= 0; + data_out_ack <= 0; +end else if (data_in_valid) begin + data_out <= data_in; + data_out_ack <= 1; +end else begin + data_out <= 0; + data_out_ack <= 0; +end + +endmodule diff --git a/tests/asicworld/code_tidbits_asyn_reset.v b/tests/asicworld/code_tidbits_asyn_reset.v new file mode 100644 index 00000000..58e47c56 --- /dev/null +++ b/tests/asicworld/code_tidbits_asyn_reset.v @@ -0,0 +1,18 @@ +module asyn_reset(clk,reset,a,c); + input clk; + input reset; + input a; + output c; + + wire clk; + wire reset; + wire a; + reg c; + +always @ (posedge clk or posedge reset) + if ( reset == 1'b1) begin + c <= 0; + end else begin + c <= a; + end +endmodule diff --git a/tests/asicworld/code_tidbits_blocking.v b/tests/asicworld/code_tidbits_blocking.v new file mode 100644 index 00000000..e13b72cc --- /dev/null +++ b/tests/asicworld/code_tidbits_blocking.v @@ -0,0 +1,17 @@ +module blocking (clk,a,c); +input clk; +input a; +output c; + +wire clk; +wire a; +reg c; +reg b; + +always @ (posedge clk ) +begin + b = a; + c = b; +end + +endmodule diff --git a/tests/asicworld/code_tidbits_fsm_using_always.v b/tests/asicworld/code_tidbits_fsm_using_always.v new file mode 100644 index 00000000..8a8775b9 --- /dev/null +++ b/tests/asicworld/code_tidbits_fsm_using_always.v @@ -0,0 +1,91 @@ +//----------------------------------------------------- +// This is FSM demo program using always block +// Design Name : fsm_using_always +// File Name : fsm_using_always.v +//----------------------------------------------------- +module fsm_using_always ( +clock , // clock +reset , // Active high, syn reset +req_0 , // Request 0 +req_1 , // Request 1 +gnt_0 , // Grant 0 +gnt_1 +); +//-------------Input Ports----------------------------- +input clock,reset,req_0,req_1; + //-------------Output Ports---------------------------- +output gnt_0,gnt_1; +//-------------Input ports Data Type------------------- +wire clock,reset,req_0,req_1; +//-------------Output Ports Data Type------------------ +reg gnt_0,gnt_1; +//-------------Internal Constants-------------------------- +parameter SIZE = 3 ; +parameter IDLE = 3'b001,GNT0 = 3'b010,GNT1 = 3'b100 ; +//-------------Internal Variables--------------------------- +reg [SIZE-1:0] state ;// Seq part of the FSM +reg [SIZE-1:0] next_state ;// combo part of FSM +//----------Code startes Here------------------------ +always @ (state or req_0 or req_1) +begin : FSM_COMBO + next_state = 3'b000; + case(state) + IDLE : if (req_0 == 1'b1) begin + next_state = GNT0; + end else if (req_1 == 1'b1) begin + next_state= GNT1; + end else begin + next_state = IDLE; + end + GNT0 : if (req_0 == 1'b1) begin + next_state = GNT0; + end else begin + next_state = IDLE; + end + GNT1 : if (req_1 == 1'b1) begin + next_state = GNT1; + end else begin + next_state = IDLE; + end + default : next_state = IDLE; + endcase +end +//----------Seq Logic----------------------------- +always @ (posedge clock) +begin : FSM_SEQ + if (reset == 1'b1) begin + state <= #1 IDLE; + end else begin + state <= #1 next_state; + end +end +//----------Output Logic----------------------------- +always @ (posedge clock) +begin : OUTPUT_LOGIC +if (reset == 1'b1) begin + gnt_0 <= #1 1'b0; + gnt_1 <= #1 1'b0; +end +else begin + case(state) + IDLE : begin + gnt_0 <= #1 1'b0; + gnt_1 <= #1 1'b0; + end + GNT0 : begin + gnt_0 <= #1 1'b1; + gnt_1 <= #1 1'b0; + end + GNT1 : begin + gnt_0 <= #1 1'b0; + gnt_1 <= #1 1'b1; + end + default : begin + gnt_0 <= #1 1'b0; + gnt_1 <= #1 1'b0; + end + endcase +end +end // End Of Block OUTPUT_LOGIC + +endmodule // End of Module arbiter diff --git a/tests/asicworld/code_tidbits_fsm_using_function.v b/tests/asicworld/code_tidbits_fsm_using_function.v new file mode 100644 index 00000000..404498a0 --- /dev/null +++ b/tests/asicworld/code_tidbits_fsm_using_function.v @@ -0,0 +1,94 @@ +//----------------------------------------------------- +// This is FSM demo program using function +// Design Name : fsm_using_function +// File Name : fsm_using_function.v +//----------------------------------------------------- +module fsm_using_function ( +clock , // clock +reset , // Active high, syn reset +req_0 , // Request 0 +req_1 , // Request 1 +gnt_0 , // Grant 0 +gnt_1 +); +//-------------Input Ports----------------------------- +input clock,reset,req_0,req_1; + //-------------Output Ports---------------------------- +output gnt_0,gnt_1; +//-------------Input ports Data Type------------------- +wire clock,reset,req_0,req_1; +//-------------Output Ports Data Type------------------ +reg gnt_0,gnt_1; +//-------------Internal Constants-------------------------- +parameter SIZE = 3 ; +parameter IDLE = 3'b001,GNT0 = 3'b010,GNT1 = 3'b100 ; +//-------------Internal Variables--------------------------- +reg [SIZE-1:0] state ;// Seq part of the FSM +wire [SIZE-1:0] next_state ;// combo part of FSM +//----------Code startes Here------------------------ +assign next_state = fsm_function(state, req_0, req_1); +//----------Function for Combo Logic----------------- +function [SIZE-1:0] fsm_function; + input [SIZE-1:0] state ; + input req_0 ; + input req_1 ; + case(state) + IDLE : if (req_0 == 1'b1) begin + fsm_function = GNT0; + end else if (req_1 == 1'b1) begin + fsm_function= GNT1; + end else begin + fsm_function = IDLE; + end + GNT0 : if (req_0 == 1'b1) begin + fsm_function = GNT0; + end else begin + fsm_function = IDLE; + end + GNT1 : if (req_1 == 1'b1) begin + fsm_function = GNT1; + end else begin + fsm_function = IDLE; + end + default : fsm_function = IDLE; + endcase +endfunction +//----------Seq Logic----------------------------- +always @ (posedge clock) +begin : FSM_SEQ + if (reset == 1'b1) begin + state <= #1 IDLE; + end else begin + state <= #1 next_state; + end +end +//----------Output Logic----------------------------- +always @ (posedge clock) +begin : OUTPUT_LOGIC +if (reset == 1'b1) begin + gnt_0 <= #1 1'b0; + gnt_1 <= #1 1'b0; +end +else begin + case(state) + IDLE : begin + gnt_0 <= #1 1'b0; + gnt_1 <= #1 1'b0; + end + GNT0 : begin + gnt_0 <= #1 1'b1; + gnt_1 <= #1 1'b0; + end + GNT1 : begin + gnt_0 <= #1 1'b0; + gnt_1 <= #1 1'b1; + end + default : begin + gnt_0 <= #1 1'b0; + gnt_1 <= #1 1'b0; + end + endcase +end +end // End Of Block OUTPUT_LOGIC + +endmodule // End of Module arbiter diff --git a/tests/asicworld/code_tidbits_fsm_using_single_always.v b/tests/asicworld/code_tidbits_fsm_using_single_always.v new file mode 100644 index 00000000..67cc0884 --- /dev/null +++ b/tests/asicworld/code_tidbits_fsm_using_single_always.v @@ -0,0 +1,63 @@ +//==================================================== +// This is FSM demo program using single always +// for both seq and combo logic +// Design Name : fsm_using_single_always +// File Name : fsm_using_single_always.v +//===================================================== +module fsm_using_single_always ( +clock , // clock +reset , // Active high, syn reset +req_0 , // Request 0 +req_1 , // Request 1 +gnt_0 , // Grant 0 +gnt_1 +); +//=============Input Ports============================= +input clock,reset,req_0,req_1; + //=============Output Ports=========================== +output gnt_0,gnt_1; +//=============Input ports Data Type=================== +wire clock,reset,req_0,req_1; +//=============Output Ports Data Type================== +reg gnt_0,gnt_1; +//=============Internal Constants====================== +parameter SIZE = 3 ; +parameter IDLE = 3'b001,GNT0 = 3'b010,GNT1 = 3'b100 ; +//=============Internal Variables====================== +reg [SIZE-1:0] state ;// Seq part of the FSM +reg [SIZE-1:0] next_state ;// combo part of FSM +//==========Code startes Here========================== +always @ (posedge clock) +begin : FSM +if (reset == 1'b1) begin + state <= #1 IDLE; + gnt_0 <= 0; + gnt_1 <= 0; +end else + case(state) + IDLE : if (req_0 == 1'b1) begin + state <= #1 GNT0; + gnt_0 <= 1; + end else if (req_1 == 1'b1) begin + gnt_1 <= 1; + state <= #1 GNT1; + end else begin + state <= #1 IDLE; + end + GNT0 : if (req_0 == 1'b1) begin + state <= #1 GNT0; + end else begin + gnt_0 <= 0; + state <= #1 IDLE; + end + GNT1 : if (req_1 == 1'b1) begin + state <= #1 GNT1; + end else begin + gnt_1 <= 0; + state <= #1 IDLE; + end + default : state <= #1 IDLE; +endcase +end + +endmodule // End of Module arbiter diff --git a/tests/asicworld/code_tidbits_nonblocking.v b/tests/asicworld/code_tidbits_nonblocking.v new file mode 100644 index 00000000..4a0d365e --- /dev/null +++ b/tests/asicworld/code_tidbits_nonblocking.v @@ -0,0 +1,17 @@ +module nonblocking (clk,a,c); +input clk; +input a; +output c; + +wire clk; +wire a; +reg c; +reg b; + +always @ (posedge clk ) +begin + b <= a; + c <= b; +end + +endmodule diff --git a/tests/asicworld/code_tidbits_reg_combo_example.v b/tests/asicworld/code_tidbits_reg_combo_example.v new file mode 100644 index 00000000..9689788c --- /dev/null +++ b/tests/asicworld/code_tidbits_reg_combo_example.v @@ -0,0 +1,13 @@ +module reg_combo_example( a, b, y); +input a, b; +output y; + +reg y; +wire a, b; + +always @ ( a or b) +begin + y = a & b; +end + +endmodule diff --git a/tests/asicworld/code_tidbits_reg_seq_example.v b/tests/asicworld/code_tidbits_reg_seq_example.v new file mode 100644 index 00000000..458c8792 --- /dev/null +++ b/tests/asicworld/code_tidbits_reg_seq_example.v @@ -0,0 +1,15 @@ +module reg_seq_example( clk, reset, d, q); +input clk, reset, d; +output q; + +reg q; +wire clk, reset, d; + +always @ (posedge clk or posedge reset) +if (reset) begin + q <= 1'b0; +end else begin + q <= d; +end + +endmodule diff --git a/tests/asicworld/code_tidbits_syn_reset.v b/tests/asicworld/code_tidbits_syn_reset.v new file mode 100644 index 00000000..994771b1 --- /dev/null +++ b/tests/asicworld/code_tidbits_syn_reset.v @@ -0,0 +1,19 @@ +module syn_reset (clk,reset,a,c); + input clk; + input reset; + input a; + output c; + + wire clk; + wire reset; + wire a; + reg c; + +always @ (posedge clk ) + if ( reset == 1'b1) begin + c <= 0; + end else begin + c <= a; + end + +endmodule diff --git a/tests/asicworld/code_tidbits_wire_example.v b/tests/asicworld/code_tidbits_wire_example.v new file mode 100644 index 00000000..577a535d --- /dev/null +++ b/tests/asicworld/code_tidbits_wire_example.v @@ -0,0 +1,9 @@ +module wire_example( a, b, y); + input a, b; + output y; + + wire a, b, y; + + assign y = a & b; + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_addbit.v b/tests/asicworld/code_verilog_tutorial_addbit.v new file mode 100644 index 00000000..22063b05 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_addbit.v @@ -0,0 +1,24 @@ +module addbit ( +a , // first input +b , // Second input +ci , // Carry input +sum , // sum output +co // carry output +); +//Input declaration +input a; +input b; +input ci; +//Ouput declaration +output sum; +output co; +//Port Data types +wire a; +wire b; +wire ci; +wire sum; +wire co; +//Code starts here +assign {co,sum} = a + b + ci; + +endmodule // End of Module addbit diff --git a/tests/asicworld/code_verilog_tutorial_always_example.v b/tests/asicworld/code_verilog_tutorial_always_example.v new file mode 100644 index 00000000..8b0fc206 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_always_example.v @@ -0,0 +1,11 @@ +module always_example(); +reg clk,reset,enable,q_in,data; + +always @ (posedge clk) +if (reset) begin + data <= 0; +end else if (enable) begin + data <= q_in; +end + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_bus_con.v b/tests/asicworld/code_verilog_tutorial_bus_con.v new file mode 100644 index 00000000..b100c813 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_bus_con.v @@ -0,0 +1,8 @@ +module bus_con (a,b, y); + input [3:0] a, b; + output [7:0] y; + wire [7:0] y; + + assign y = {a,b}; + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_comment.v b/tests/asicworld/code_verilog_tutorial_comment.v new file mode 100644 index 00000000..1cc0eb42 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_comment.v @@ -0,0 +1,25 @@ +/* This is a + Multi line comment + example */ +module addbit ( +a, +b, +ci, +sum, +co); + +// Input Ports Single line comment +input a; +input b; +input ci; +// Output ports +output sum; +output co; +// Data Types +wire a; +wire b; +wire ci; +wire sum; +wire co; + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_counter.v b/tests/asicworld/code_verilog_tutorial_counter.v new file mode 100644 index 00000000..53451974 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_counter.v @@ -0,0 +1,19 @@ +//-----------------------------------------------------
+// Design Name : counter
+// File Name : counter.v
+// Function : 4 bit up counter
+// Coder : Deepak
+//-----------------------------------------------------
+module counter (clk, reset, enable, count);
+input clk, reset, enable;
+output [3:0] count;
+reg [3:0] count;
+
+always @ (posedge clk)
+if (reset == 1'b1) begin
+ count <= 0;
+end else if ( enable == 1'b1) begin
+ count <= count + 1;
+end
+
+endmodule
diff --git a/tests/asicworld/code_verilog_tutorial_counter_tb.v b/tests/asicworld/code_verilog_tutorial_counter_tb.v new file mode 100644 index 00000000..10477938 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_counter_tb.v @@ -0,0 +1,113 @@ +///////////////////////////////////////////////////////////////////////////
+// MODULE : counter_tb //
+// TOP MODULE : -- //
+// //
+// PURPOSE : 4-bit up counter test bench //
+// //
+// DESIGNER : Deepak Kumar Tala //
+// //
+// Revision History //
+// //
+// DEVELOPMENT HISTORY : //
+// Rev0.0 : Jan 03, 2003 //
+// Initial Revision //
+// //
+///////////////////////////////////////////////////////////////////////////
+module testbench;
+
+reg clk, reset, enable;
+wire [3:0] count;
+reg dut_error;
+
+counter U0 (
+.clk (clk),
+.reset (reset),
+.enable (enable),
+.count (count)
+);
+
+event reset_enable;
+event terminate_sim;
+
+initial
+begin
+ $display ("###################################################");
+ clk = 0;
+ reset = 0;
+ enable = 0;
+ dut_error = 0;
+end
+
+always
+ #5 clk = !clk;
+
+initial
+begin
+ $dumpfile ("counter.vcd");
+ $dumpvars;
+end
+
+
+initial
+@ (terminate_sim) begin
+ $display ("Terminating simulation");
+ if (dut_error == 0) begin
+ $display ("Simulation Result : PASSED");
+ end
+ else begin
+ $display ("Simulation Result : FAILED");
+ end
+ $display ("###################################################");
+ #1 $finish;
+end
+
+
+
+event reset_done;
+
+initial
+forever begin
+ @ (reset_enable);
+ @ (negedge clk)
+ $display ("Applying reset");
+ reset = 1;
+ @ (negedge clk)
+ reset = 0;
+ $display ("Came out of Reset");
+ -> reset_done;
+end
+
+initial begin
+ #10 -> reset_enable;
+ @ (reset_done);
+ @ (negedge clk);
+ enable = 1;
+ repeat (5)
+ begin
+ @ (negedge clk);
+ end
+ enable = 0;
+ #5 -> terminate_sim;
+end
+
+
+reg [3:0] count_compare;
+
+always @ (posedge clk)
+if (reset == 1'b1)
+ count_compare <= 0;
+else if ( enable == 1'b1)
+ count_compare <= count_compare + 1;
+
+
+
+always @ (negedge clk)
+if (count_compare != count) begin
+ $display ("DUT ERROR AT TIME%d",$time);
+ $display ("Expected value %d, Got Value %d", count_compare, count);
+ dut_error = 1;
+ #5 -> terminate_sim;
+end
+
+endmodule
+
diff --git a/tests/asicworld/code_verilog_tutorial_d_ff.v b/tests/asicworld/code_verilog_tutorial_d_ff.v new file mode 100644 index 00000000..7a408360 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_d_ff.v @@ -0,0 +1,14 @@ +// D flip-flop Code +module d_ff ( d, clk, q, q_bar); +input d ,clk; +output q, q_bar; +wire d ,clk; +reg q, q_bar; + +always @ (posedge clk) +begin + q <= d; + q_bar <= !d; +end + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_decoder.v b/tests/asicworld/code_verilog_tutorial_decoder.v new file mode 100644 index 00000000..5efdbd7e --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_decoder.v @@ -0,0 +1,14 @@ +module decoder (in,out); +input [2:0] in; +output [7:0] out; +wire [7:0] out; +assign out = (in == 3'b000 ) ? 8'b0000_0001 : +(in == 3'b001 ) ? 8'b0000_0010 : +(in == 3'b010 ) ? 8'b0000_0100 : +(in == 3'b011 ) ? 8'b0000_1000 : +(in == 3'b100 ) ? 8'b0001_0000 : +(in == 3'b101 ) ? 8'b0010_0000 : +(in == 3'b110 ) ? 8'b0100_0000 : +(in == 3'b111 ) ? 8'b1000_0000 : 8'h00; + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_decoder_always.v b/tests/asicworld/code_verilog_tutorial_decoder_always.v new file mode 100644 index 00000000..4418ec70 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_decoder_always.v @@ -0,0 +1,20 @@ +module decoder_always (in,out); +input [2:0] in; +output [7:0] out; +reg [7:0] out; + +always @ (in) +begin + out = 0; + case (in) + 3'b001 : out = 8'b0000_0001; + 3'b010 : out = 8'b0000_0010; + 3'b011 : out = 8'b0000_0100; + 3'b100 : out = 8'b0000_1000; + 3'b101 : out = 8'b0001_0000; + 3'b110 : out = 8'b0100_0000; + 3'b111 : out = 8'b1000_0000; + endcase +end + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_escape_id.v b/tests/asicworld/code_verilog_tutorial_escape_id.v new file mode 100644 index 00000000..6c33da17 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_escape_id.v @@ -0,0 +1,14 @@ +// There must be white space after the +// string which uses escape character +module \1dff ( +q, // Q output +\q~ , // Q_out output +d, // D input +cl$k, // CLOCK input +\reset* // Reset input +); + +input d, cl$k, \reset* ; +output q, \q~ ; + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_explicit.v b/tests/asicworld/code_verilog_tutorial_explicit.v new file mode 100644 index 00000000..88427ff0 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_explicit.v @@ -0,0 +1,35 @@ +module explicit(); +reg clk,d,rst,pre; +wire q; + +// Here q_bar is not connected +// We can connect ports in any order +dff u0 ( +.q (q), +.d (d), +.clk (clk), +.q_bar (), +.rst (rst), +.pre (pre) +); + +endmodule + +// D fli-flop +module dff (q, q_bar, clk, d, rst, pre); +input clk, d, rst, pre; +output q, q_bar; +reg q; + +assign q_bar = ~q; + +always @ (posedge clk) +if (rst == 1'b1) begin + q <= 0; +end else if (pre == 1'b1) begin + q <= 1; +end else begin + q <= d; +end + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_first_counter.v b/tests/asicworld/code_verilog_tutorial_first_counter.v new file mode 100644 index 00000000..d35d4aac --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_first_counter.v @@ -0,0 +1,47 @@ +//----------------------------------------------------- +// This is my second Verilog Design +// Design Name : first_counter +// File Name : first_counter.v +// Function : This is a 4 bit up-counter with +// Synchronous active high reset and +// with active high enable signal +//----------------------------------------------------- +module first_counter ( +clock , // Clock input of the design +reset , // active high, synchronous Reset input +enable , // Active high enable signal for counter +counter_out // 4 bit vector output of the counter +); // End of port list +//-------------Input Ports----------------------------- +input clock ; +input reset ; +input enable ; +//-------------Output Ports---------------------------- +output [3:0] counter_out ; +//-------------Input ports Data Type------------------- +// By rule all the input ports should be wires +wire clock ; +wire reset ; +wire enable ; +//-------------Output Ports Data Type------------------ +// Output port can be a storage element (reg) or a wire +reg [3:0] counter_out ; + +//------------Code Starts Here------------------------- +// Since this counter is a positive edge trigged one, +// We trigger the below block with respect to positive +// edge of the clock. +always @ (posedge clock) +begin : COUNTER // Block Name + // At every rising edge of clock we check if reset is active + // If active, we load the counter output with 4'b0000 + if (reset == 1'b1) begin + counter_out <= 4'b0000; + end + // If enable is active, then we increment the counter + else if (enable == 1'b1) begin + counter_out <= counter_out + 1; + end +end // End of Block COUNTER + +endmodule // End of Module counter diff --git a/tests/asicworld/code_verilog_tutorial_first_counter_tb.v b/tests/asicworld/code_verilog_tutorial_first_counter_tb.v new file mode 100644 index 00000000..f065732b --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_first_counter_tb.v @@ -0,0 +1,36 @@ +module testbench(); +// Declare inputs as regs and outputs as wires +reg clock, reset, enable; +wire [3:0] counter_out; + +// Initialize all variables +initial begin + $display ("time\t clk reset enable counter"); + $monitor ("%g\t %b %b %b %b", + $time, clock, reset, enable, counter_out); + clock = 1; // initial value of clock + reset = 0; // initial value of reset + enable = 0; // initial value of enable + #5 reset = 1; // Assert the reset + #10 reset = 0; // De-assert the reset + #10 enable = 1; // Assert enable + #100 enable = 0; // De-assert enable + #5 $finish; // Terminate simulation +end + +// Clock generator +initial begin + #1; + forever + #5 clock = ~clock; // Toggle clock every 5 ticks +end + +// Connect DUT to test bench +first_counter U_counter ( +clock, +reset, +enable, +counter_out +); + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_flip_flop.v b/tests/asicworld/code_verilog_tutorial_flip_flop.v new file mode 100644 index 00000000..ed2e88c2 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_flip_flop.v @@ -0,0 +1,15 @@ +module flif_flop (clk,reset, q, d); +input clk, reset, d; +output q; +reg q; + +always @ (posedge clk ) +begin + if (reset == 1) begin + q <= 0; + end else begin + q <= d; + end +end + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_fsm_full.v b/tests/asicworld/code_verilog_tutorial_fsm_full.v new file mode 100644 index 00000000..fd2d559b --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_fsm_full.v @@ -0,0 +1,114 @@ +module fsm_full( +clock , // Clock +reset , // Active high reset +req_0 , // Active high request from agent 0 +req_1 , // Active high request from agent 1 +req_2 , // Active high request from agent 2 +req_3 , // Active high request from agent 3 +gnt_0 , // Active high grant to agent 0 +gnt_1 , // Active high grant to agent 1 +gnt_2 , // Active high grant to agent 2 +gnt_3 // Active high grant to agent 3 +); +// Port declaration here +input clock ; // Clock +input reset ; // Active high reset +input req_0 ; // Active high request from agent 0 +input req_1 ; // Active high request from agent 1 +input req_2 ; // Active high request from agent 2 +input req_3 ; // Active high request from agent 3 +output gnt_0 ; // Active high grant to agent 0 +output gnt_1 ; // Active high grant to agent 1 +output gnt_2 ; // Active high grant to agent 2 +output gnt_3 ; // Active high grant to agent + +// Internal Variables +reg gnt_0 ; // Active high grant to agent 0 +reg gnt_1 ; // Active high grant to agent 1 +reg gnt_2 ; // Active high grant to agent 2 +reg gnt_3 ; // Active high grant to agent + +parameter [2:0] IDLE = 3'b000; +parameter [2:0] GNT0 = 3'b001; +parameter [2:0] GNT1 = 3'b010; +parameter [2:0] GNT2 = 3'b011; +parameter [2:0] GNT3 = 3'b100; + +reg [2:0] state, next_state; + +always @ (state or req_0 or req_1 or req_2 or req_3) +begin + next_state = 0; + case(state) + IDLE : if (req_0 == 1'b1) begin + next_state = GNT0; + end else if (req_1 == 1'b1) begin + next_state= GNT1; + end else if (req_2 == 1'b1) begin + next_state= GNT2; + end else if (req_3 == 1'b1) begin + next_state= GNT3; + end else begin + next_state = IDLE; + end + GNT0 : if (req_0 == 1'b0) begin + next_state = IDLE; + end else begin + next_state = GNT0; + end + GNT1 : if (req_1 == 1'b0) begin + next_state = IDLE; + end else begin + next_state = GNT1; + end + GNT2 : if (req_2 == 1'b0) begin + next_state = IDLE; + end else begin + next_state = GNT2; + end + GNT3 : if (req_3 == 1'b0) begin + next_state = IDLE; + end else begin + next_state = GNT3; + end + default : next_state = IDLE; + endcase +end + +always @ (posedge clock) +begin : OUTPUT_LOGIC + if (reset) begin + gnt_0 <= 1'b0; + gnt_1 <= 1'b0; + gnt_2 <= 1'b0; + gnt_3 <= 1'b0; + state <= IDLE; + end else begin + state <= next_state; + case(state) + IDLE : begin + gnt_0 <= 1'b0; + gnt_1 <= 1'b0; + gnt_2 <= 1'b0; + gnt_3 <= 1'b0; + end + GNT0 : begin + gnt_0 <= 1'b1; + end + GNT1 : begin + gnt_1 <= 1'b1; + end + GNT2 : begin + gnt_2 <= 1'b1; + end + GNT3 : begin + gnt_3 <= 1'b1; + end + default : begin + state <= IDLE; + end + endcase + end +end + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_fsm_full_tb.v b/tests/asicworld/code_verilog_tutorial_fsm_full_tb.v new file mode 100644 index 00000000..0097b1c9 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_fsm_full_tb.v @@ -0,0 +1,48 @@ +module testbench(); +reg clock , reset ; +reg req_0 , req_1 , req_2 , req_3; +wire gnt_0 , gnt_1 , gnt_2 , gnt_3 ; + +initial begin + $display("Time\t R0 R1 R2 R3 G0 G1 G2 G3"); + $monitor("%g\t %b %b %b %b %b %b %b %b", + $time, req_0, req_1, req_2, req_3, gnt_0, gnt_1, gnt_2, gnt_3); + clock = 0; + reset = 0; + req_0 = 0; + req_1 = 0; + req_2 = 0; + req_3 = 0; + #10 reset = 1; + #10 reset = 0; + #10 req_0 = 1; + #20 req_0 = 0; + #10 req_1 = 1; + #20 req_1 = 0; + #10 req_2 = 1; + #20 req_2 = 0; + #10 req_3 = 1; + #20 req_3 = 0; + #10 $finish; +end + +initial begin + #1; + forever + #2 clock = ~clock; +end + +fsm_full U_fsm_full( +clock , // Clock +reset , // Active high reset +req_0 , // Active high request from agent 0 +req_1 , // Active high request from agent 1 +req_2 , // Active high request from agent 2 +req_3 , // Active high request from agent 3 +gnt_0 , // Active high grant to agent 0 +gnt_1 , // Active high grant to agent 1 +gnt_2 , // Active high grant to agent 2 +gnt_3 // Active high grant to agent 3 +); + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_good_code.v b/tests/asicworld/code_verilog_tutorial_good_code.v new file mode 100644 index 00000000..6ba77644 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_good_code.v @@ -0,0 +1,18 @@ + module addbit ( + a, + b, + ci, + sum, + co); + input a; + input b; + input ci; + output sum; + output co; + wire a; + wire b; + wire ci; + wire sum; + wire co; + + endmodule diff --git a/tests/asicworld/code_verilog_tutorial_if_else.v b/tests/asicworld/code_verilog_tutorial_if_else.v new file mode 100644 index 00000000..19b91d3f --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_if_else.v @@ -0,0 +1,13 @@ +module if_else(); + +reg dff; +wire clk,din,reset; + +always @ (posedge clk) +if (reset) begin + dff <= 0; +end else begin + dff <= din; +end + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_multiply.v b/tests/asicworld/code_verilog_tutorial_multiply.v new file mode 100644 index 00000000..1912e1e2 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_multiply.v @@ -0,0 +1,8 @@ +module muliply (a,product); + input [3:0] a; + output [4:0] product; + wire [4:0] product; + + assign product = a << 1; + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_mux_21.v b/tests/asicworld/code_verilog_tutorial_mux_21.v new file mode 100644 index 00000000..a6a0d35e --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_mux_21.v @@ -0,0 +1,9 @@ +module mux_21 (a,b,sel,y); + input a, b; + output y; + input sel; + wire y; + + assign y = (sel) ? b : a; + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_n_out_primitive.v b/tests/asicworld/code_verilog_tutorial_n_out_primitive.v new file mode 100644 index 00000000..814385a4 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_n_out_primitive.v @@ -0,0 +1,13 @@ +module n_out_primitive(); + +wire out,out_0,out_1,out_2,out_3,out_a,out_b,out_c; +wire in; + +// one output Buffer gate +buf u_buf0 (out,in); +// four output Buffer gate +buf u_buf1 (out_0, out_1, out_2, out_3, in); +// three output Invertor gate +not u_not0 (out_a, out_b, out_c, in); + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_parallel_if.v b/tests/asicworld/code_verilog_tutorial_parallel_if.v new file mode 100644 index 00000000..1dbe737e --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_parallel_if.v @@ -0,0 +1,21 @@ +module parallel_if(); + +reg [3:0] counter; +wire clk,reset,enable, up_en, down_en; + +always @ (posedge clk) +// If reset is asserted +if (reset == 1'b0) begin + counter <= 4'b0000; +end else begin + // If counter is enable and up count is mode + if (enable == 1'b1 && up_en == 1'b1) begin + counter <= counter + 1'b1; + end + // If counter is enable and down count is mode + if (enable == 1'b1 && down_en == 1'b1) begin + counter <= counter - 1'b1; + end +end + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_parity.v b/tests/asicworld/code_verilog_tutorial_parity.v new file mode 100644 index 00000000..764396c2 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_parity.v @@ -0,0 +1,41 @@ +//----------------------------------------------------- +// This is simple parity Program +// Design Name : parity +// File Name : parity.v +// Function : This program shows how a verilog +// primitive/module port connection are done +// Coder : Deepak +//----------------------------------------------------- +module parity ( +a , // First input +b , // Second input +c , // Third Input +d , // Fourth Input +y // Parity output +); + +// Input Declaration +input a ; +input b ; +input c ; +input d ; +// Ouput Declaration +output y ; +// port data types +wire a ; +wire b ; +wire c ; +wire d ; +wire y ; +// Internal variables +wire out_0 ; +wire out_1 ; + +// Code starts Here +xor u0 (out_0,a,b); + +xor u1 (out_1,c,d); + +xor u2 (y,out_0,out_1); + +endmodule // End Of Module parity diff --git a/tests/asicworld/code_verilog_tutorial_simple_function.v b/tests/asicworld/code_verilog_tutorial_simple_function.v new file mode 100644 index 00000000..5818a1d4 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_simple_function.v @@ -0,0 +1,10 @@ +module simple_function(); + +function myfunction; +input a, b, c, d; +begin + myfunction = ((a+b) + (c-d)); +end +endfunction + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_simple_if.v b/tests/asicworld/code_verilog_tutorial_simple_if.v new file mode 100644 index 00000000..a68cc4a8 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_simple_if.v @@ -0,0 +1,11 @@ +module simple_if(); + +reg latch; +wire enable,din; + +always @ (enable or din) +if (enable) begin + latch <= din; +end + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_task_global.v b/tests/asicworld/code_verilog_tutorial_task_global.v new file mode 100644 index 00000000..3ae86279 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_task_global.v @@ -0,0 +1,12 @@ +module task_global(); + +reg [7:0] temp_out; +reg [7:0] temp_in; + +task convert; +begin + temp_out = (9/5) *( temp_in + 32); +end +endtask + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_tri_buf.v b/tests/asicworld/code_verilog_tutorial_tri_buf.v new file mode 100644 index 00000000..a55b29ca --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_tri_buf.v @@ -0,0 +1,9 @@ +module tri_buf (a,b,enable); + input a; + output b; + input enable; + wire b; + +assign b = (enable) ? a : 1'bz; + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_v2k_reg.v b/tests/asicworld/code_verilog_tutorial_v2k_reg.v new file mode 100644 index 00000000..537a9e85 --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_v2k_reg.v @@ -0,0 +1,24 @@ +module v2k_reg(); + +// v2k allows to init variables +reg a = 0; +// Here only last variable is set to 0, i.e d = 0 +// Rest b, c are set to x +reg b, c, d = 0; +// reg data type can be signed in v2k +// We can assign with signed constants +reg signed [7:0] data = 8'shF0; + +// Function can return signed values +// Its ports can contain signed ports +function signed [7:0] adder; + input a_in; + input b_in; + input c_in; + input signed [7:0] data_in; + begin + adder = a_in + b_in + c_in + data_in; + end +endfunction + +endmodule diff --git a/tests/asicworld/code_verilog_tutorial_which_clock.v b/tests/asicworld/code_verilog_tutorial_which_clock.v new file mode 100644 index 00000000..418a2cfa --- /dev/null +++ b/tests/asicworld/code_verilog_tutorial_which_clock.v @@ -0,0 +1,12 @@ +module which_clock (x,y,q,d); +input x,y,d; +output q; +reg q; + +always @ (posedge x or posedge y) + if (x) + q <= 1'b0; + else + q <= d; + +endmodule diff --git a/tests/asicworld/run-test.sh b/tests/asicworld/run-test.sh new file mode 100755 index 00000000..bf27d15f --- /dev/null +++ b/tests/asicworld/run-test.sh @@ -0,0 +1,3 @@ +#!/bin/bash +make -C ../.. || exit 1 +exec bash ../tools/autotest.sh *.v diff --git a/tests/hana/README b/tests/hana/README new file mode 100644 index 00000000..37049405 --- /dev/null +++ b/tests/hana/README @@ -0,0 +1,14 @@ + +This test cases are copied from the hana project: +https://sourceforge.net/projects/sim-sim/ + +** Copy tests from hana: ** +while read fn; do cp -v $fn ALL_TESTS/${fn//\//_}; done < <(find test -name '*.v' ! -name '*_gold.v') + +** Eliminate test's we can't parse atm: ** +rm -f test_synthesizability*.v +rm -f test_parse2synthtrans_latch_1_test.v +rm -f test_parse2synthtrans_always_1_test.v +rm -f test_parse2synthtrans_always_2_test.v +for x in test_*.v; do ../../yosys -b "" $x || rm $x; done + diff --git a/tests/hana/hana_vlib.v b/tests/hana/hana_vlib.v new file mode 100644 index 00000000..fc82f138 --- /dev/null +++ b/tests/hana/hana_vlib.v @@ -0,0 +1,1139 @@ +/* +Copyright (C) 2009-2010 Parvez Ahmad +Written by Parvez Ahmad <parvez_ahmad@yahoo.co.uk>. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. */ + + +module BUF (input in, output out); + +assign out = in; + +endmodule + +module TRIBUF(input in, enable, output out); + +assign out = enable ? in : 1'bz; + +endmodule + +module INV(input in, output out); + +assign out = ~in; + +endmodule + +module AND2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output out); + +assign out = ∈ + +endmodule + +module AND3 #(parameter SIZE = 3) (input [SIZE-1:0] in, output out); + +assign out = ∈ + +endmodule + +module AND4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output out); + +assign out = ∈ + +endmodule + +module OR2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output out); + +assign out = |in; + +endmodule + +module OR3 #(parameter SIZE = 3) (input [SIZE-1:0] in, output out); + +assign out = |in; + +endmodule + +module OR4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output out); + +assign out = |in; + +endmodule + + +module NAND2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output out); + +assign out = ~∈ + +endmodule + +module NAND3 #(parameter SIZE = 3) (input [SIZE-1:0] in, output out); + +assign out = ~∈ + +endmodule + +module NAND4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output out); + +assign out = ~∈ + +endmodule + +module NOR2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output out); + +assign out = ~|in; + +endmodule + +module NOR3 #(parameter SIZE = 3) (input [SIZE-1:0] in, output out); + +assign out = ~|in; + +endmodule + +module NOR4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output out); + +assign out = ~|in; + +endmodule + + +module XOR2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output out); + +assign out = ^in; + +endmodule + +module XOR3 #(parameter SIZE = 3) (input [SIZE-1:0] in, output out); + +assign out = ^in; + +endmodule + +module XOR4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output out); + +assign out = ^in; + +endmodule + + +module XNOR2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output out); + +assign out = ~^in; + +endmodule + +module XNOR3 #(parameter SIZE = 3) (input [SIZE-1:0] in, output out); + +assign out = ~^in; + +endmodule + +module XNOR4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output out); + +assign out = ~^in; + +endmodule + +module DEC1 (input in, enable, output reg [1:0] out); + +always @(in or enable) + if(!enable) + out = 2'b00; + else begin + case (in) + 1'b0 : out = 2'b01; + 1'b1 : out = 2'b10; + endcase + end +endmodule + +module DEC2 (input [1:0] in, input enable, output reg [3:0] out); + +always @(in or enable) + if(!enable) + out = 4'b0000; + else begin + case (in) + 2'b00 : out = 4'b0001; + 2'b01 : out = 4'b0010; + 2'b10 : out = 4'b0100; + 2'b11 : out = 4'b1000; + endcase + end +endmodule + +module DEC3 (input [2:0] in, input enable, output reg [7:0] out); + +always @(in or enable) + if(!enable) + out = 8'b00000000; + else begin + case (in) + 3'b000 : out = 8'b00000001; + 3'b001 : out = 8'b00000010; + 3'b010 : out = 8'b00000100; + 3'b011 : out = 8'b00001000; + 3'b100 : out = 8'b00010000; + 3'b101 : out = 8'b00100000; + 3'b110 : out = 8'b01000000; + 3'b111 : out = 8'b10000000; + endcase + end +endmodule + +module DEC4 (input [3:0] in, input enable, output reg [15:0] out); + +always @(in or enable) + if(!enable) + out = 16'b0000000000000000; + else begin + case (in) + 4'b0000 : out = 16'b0000000000000001; + 4'b0001 : out = 16'b0000000000000010; + 4'b0010 : out = 16'b0000000000000100; + 4'b0011 : out = 16'b0000000000001000; + 4'b0100 : out = 16'b0000000000010000; + 4'b0101 : out = 16'b0000000000100000; + 4'b0110 : out = 16'b0000000001000000; + 4'b0111 : out = 16'b0000000010000000; + 4'b1000 : out = 16'b0000000100000000; + 4'b1001 : out = 16'b0000001000000000; + 4'b1010 : out = 16'b0000010000000000; + 4'b1011 : out = 16'b0000100000000000; + 4'b1100 : out = 16'b0001000000000000; + 4'b1101 : out = 16'b0010000000000000; + 4'b1110 : out = 16'b0100000000000000; + 4'b1111 : out = 16'b1000000000000000; + endcase + end +endmodule +module DEC5 (input [4:0] in, input enable, output reg [31:0] out); + +always @(in or enable) + if(!enable) + out = 32'b00000000000000000000000000000000; + else begin + case (in) + 5'b00000 : out = 32'b00000000000000000000000000000001; + 5'b00001 : out = 32'b00000000000000000000000000000010; + 5'b00010 : out = 32'b00000000000000000000000000000100; + 5'b00011 : out = 32'b00000000000000000000000000001000; + 5'b00100 : out = 32'b00000000000000000000000000010000; + 5'b00101 : out = 32'b00000000000000000000000000100000; + 5'b00110 : out = 32'b00000000000000000000000001000000; + 5'b00111 : out = 32'b00000000000000000000000010000000; + 5'b01000 : out = 32'b00000000000000000000000100000000; + 5'b01001 : out = 32'b00000000000000000000001000000000; + 5'b01010 : out = 32'b00000000000000000000010000000000; + 5'b01011 : out = 32'b00000000000000000000100000000000; + 5'b01100 : out = 32'b00000000000000000001000000000000; + 5'b01101 : out = 32'b00000000000000000010000000000000; + 5'b01110 : out = 32'b00000000000000000100000000000000; + 5'b01111 : out = 32'b00000000000000001000000000000000; + 5'b10000 : out = 32'b00000000000000010000000000000000; + 5'b10001 : out = 32'b00000000000000100000000000000000; + 5'b10010 : out = 32'b00000000000001000000000000000000; + 5'b10011 : out = 32'b00000000000010000000000000000000; + 5'b10100 : out = 32'b00000000000100000000000000000000; + 5'b10101 : out = 32'b00000000001000000000000000000000; + 5'b10110 : out = 32'b00000000010000000000000000000000; + 5'b10111 : out = 32'b00000000100000000000000000000000; + 5'b11000 : out = 32'b00000001000000000000000000000000; + 5'b11001 : out = 32'b00000010000000000000000000000000; + 5'b11010 : out = 32'b00000100000000000000000000000000; + 5'b11011 : out = 32'b00001000000000000000000000000000; + 5'b11100 : out = 32'b00010000000000000000000000000000; + 5'b11101 : out = 32'b00100000000000000000000000000000; + 5'b11110 : out = 32'b01000000000000000000000000000000; + 5'b11111 : out = 32'b10000000000000000000000000000000; + endcase + end +endmodule + +module DEC6 (input [5:0] in, input enable, output reg [63:0] out); + +always @(in or enable) + if(!enable) + out = 64'b0000000000000000000000000000000000000000000000000000000000000000; + else begin + case (in) + 6'b000000 : out = 64'b0000000000000000000000000000000000000000000000000000000000000001; + 6'b000001 : out = 64'b0000000000000000000000000000000000000000000000000000000000000010; + 6'b000010 : out = 64'b0000000000000000000000000000000000000000000000000000000000000100; + 6'b000011 : out = 64'b0000000000000000000000000000000000000000000000000000000000001000; + 6'b000100 : out = 64'b0000000000000000000000000000000000000000000000000000000000010000; + 6'b000101 : out = 64'b0000000000000000000000000000000000000000000000000000000000100000; + 6'b000110 : out = 64'b0000000000000000000000000000000000000000000000000000000001000000; + 6'b000111 : out = 64'b0000000000000000000000000000000000000000000000000000000010000000; + 6'b001000 : out = 64'b0000000000000000000000000000000000000000000000000000000100000000; + 6'b001001 : out = 64'b0000000000000000000000000000000000000000000000000000001000000000; + 6'b001010 : out = 64'b0000000000000000000000000000000000000000000000000000010000000000; + 6'b001011 : out = 64'b0000000000000000000000000000000000000000000000000000100000000000; + 6'b001100 : out = 64'b0000000000000000000000000000000000000000000000000001000000000000; + 6'b001101 : out = 64'b0000000000000000000000000000000000000000000000000010000000000000; + 6'b001110 : out = 64'b0000000000000000000000000000000000000000000000000100000000000000; + 6'b001111 : out = 64'b0000000000000000000000000000000000000000000000001000000000000000; + 6'b010000 : out = 64'b0000000000000000000000000000000000000000000000010000000000000000; + 6'b010001 : out = 64'b0000000000000000000000000000000000000000000000100000000000000000; + 6'b010010 : out = 64'b0000000000000000000000000000000000000000000001000000000000000000; + 6'b010011 : out = 64'b0000000000000000000000000000000000000000000010000000000000000000; + 6'b010100 : out = 64'b0000000000000000000000000000000000000000000100000000000000000000; + 6'b010101 : out = 64'b0000000000000000000000000000000000000000001000000000000000000000; + 6'b010110 : out = 64'b0000000000000000000000000000000000000000010000000000000000000000; + 6'b010111 : out = 64'b0000000000000000000000000000000000000000100000000000000000000000; + 6'b011000 : out = 64'b0000000000000000000000000000000000000001000000000000000000000000; + 6'b011001 : out = 64'b0000000000000000000000000000000000000010000000000000000000000000; + 6'b011010 : out = 64'b0000000000000000000000000000000000000100000000000000000000000000; + 6'b011011 : out = 64'b0000000000000000000000000000000000001000000000000000000000000000; + 6'b011100 : out = 64'b0000000000000000000000000000000000010000000000000000000000000000; + 6'b011101 : out = 64'b0000000000000000000000000000000000100000000000000000000000000000; + 6'b011110 : out = 64'b0000000000000000000000000000000001000000000000000000000000000000; + 6'b011111 : out = 64'b0000000000000000000000000000000010000000000000000000000000000000; + + 6'b100000 : out = 64'b0000000000000000000000000000000100000000000000000000000000000000; + 6'b100001 : out = 64'b0000000000000000000000000000001000000000000000000000000000000000; + 6'b100010 : out = 64'b0000000000000000000000000000010000000000000000000000000000000000; + 6'b100011 : out = 64'b0000000000000000000000000000100000000000000000000000000000000000; + 6'b100100 : out = 64'b0000000000000000000000000001000000000000000000000000000000000000; + 6'b100101 : out = 64'b0000000000000000000000000010000000000000000000000000000000000000; + 6'b100110 : out = 64'b0000000000000000000000000100000000000000000000000000000000000000; + 6'b100111 : out = 64'b0000000000000000000000001000000000000000000000000000000000000000; + 6'b101000 : out = 64'b0000000000000000000000010000000000000000000000000000000000000000; + 6'b101001 : out = 64'b0000000000000000000000100000000000000000000000000000000000000000; + 6'b101010 : out = 64'b0000000000000000000001000000000000000000000000000000000000000000; + 6'b101011 : out = 64'b0000000000000000000010000000000000000000000000000000000000000000; + 6'b101100 : out = 64'b0000000000000000000100000000000000000000000000000000000000000000; + 6'b101101 : out = 64'b0000000000000000001000000000000000000000000000000000000000000000; + 6'b101110 : out = 64'b0000000000000000010000000000000000000000000000000000000000000000; + 6'b101111 : out = 64'b0000000000000000100000000000000000000000000000000000000000000000; + 6'b110000 : out = 64'b0000000000000001000000000000000000000000000000000000000000000000; + 6'b110001 : out = 64'b0000000000000010000000000000000000000000000000000000000000000000; + 6'b110010 : out = 64'b0000000000000100000000000000000000000000000000000000000000000000; + 6'b110011 : out = 64'b0000000000001000000000000000000000000000000000000000000000000000; + 6'b110100 : out = 64'b0000000000010000000000000000000000000000000000000000000000000000; + 6'b110101 : out = 64'b0000000000100000000000000000000000000000000000000000000000000000; + 6'b110110 : out = 64'b0000000001000000000000000000000000000000000000000000000000000000; + 6'b110111 : out = 64'b0000000010000000000000000000000000000000000000000000000000000000; + 6'b111000 : out = 64'b0000000100000000000000000000000000000000000000000000000000000000; + 6'b111001 : out = 64'b0000001000000000000000000000000000000000000000000000000000000000; + 6'b111010 : out = 64'b0000010000000000000000000000000000000000000000000000000000000000; + 6'b111011 : out = 64'b0000100000000000000000000000000000000000000000000000000000000000; + 6'b111100 : out = 64'b0001000000000000000000000000000000000000000000000000000000000000; + 6'b111101 : out = 64'b0010000000000000000000000000000000000000000000000000000000000000; + 6'b111110 : out = 64'b0100000000000000000000000000000000000000000000000000000000000000; + 6'b111111 : out = 64'b1000000000000000000000000000000000000000000000000000000000000000; + endcase + end +endmodule + + +module MUX2(input [1:0] in, input select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + endcase +endmodule + + +module MUX4(input [3:0] in, input [1:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + endcase +endmodule + + +module MUX8(input [7:0] in, input [2:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + endcase +endmodule + +module MUX16(input [15:0] in, input [3:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + 8: out = in[8]; + 9: out = in[9]; + 10: out = in[10]; + 11: out = in[11]; + 12: out = in[12]; + 13: out = in[13]; + 14: out = in[14]; + 15: out = in[15]; + endcase +endmodule + +module MUX32(input [31:0] in, input [4:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + 8: out = in[8]; + 9: out = in[9]; + 10: out = in[10]; + 11: out = in[11]; + 12: out = in[12]; + 13: out = in[13]; + 14: out = in[14]; + 15: out = in[15]; + 16: out = in[16]; + 17: out = in[17]; + 18: out = in[18]; + 19: out = in[19]; + 20: out = in[20]; + 21: out = in[21]; + 22: out = in[22]; + 23: out = in[23]; + 24: out = in[24]; + 25: out = in[25]; + 26: out = in[26]; + 27: out = in[27]; + 28: out = in[28]; + 29: out = in[29]; + 30: out = in[30]; + 31: out = in[31]; + endcase +endmodule + +module MUX64(input [63:0] in, input [5:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + 8: out = in[8]; + 9: out = in[9]; + 10: out = in[10]; + 11: out = in[11]; + 12: out = in[12]; + 13: out = in[13]; + 14: out = in[14]; + 15: out = in[15]; + 16: out = in[16]; + 17: out = in[17]; + 18: out = in[18]; + 19: out = in[19]; + 20: out = in[20]; + 21: out = in[21]; + 22: out = in[22]; + 23: out = in[23]; + 24: out = in[24]; + 25: out = in[25]; + 26: out = in[26]; + 27: out = in[27]; + 28: out = in[28]; + 29: out = in[29]; + 30: out = in[30]; + 31: out = in[31]; + 32: out = in[32]; + 33: out = in[33]; + 34: out = in[34]; + 35: out = in[35]; + 36: out = in[36]; + 37: out = in[37]; + 38: out = in[38]; + 39: out = in[39]; + 40: out = in[40]; + 41: out = in[41]; + 42: out = in[42]; + 43: out = in[43]; + 44: out = in[44]; + 45: out = in[45]; + 46: out = in[46]; + 47: out = in[47]; + 48: out = in[48]; + 49: out = in[49]; + 50: out = in[50]; + 51: out = in[51]; + 52: out = in[52]; + 53: out = in[53]; + 54: out = in[54]; + 55: out = in[55]; + 56: out = in[56]; + 57: out = in[57]; + 58: out = in[58]; + 59: out = in[59]; + 60: out = in[60]; + 61: out = in[61]; + 62: out = in[62]; + 63: out = in[63]; + endcase +endmodule + +module ADD1(input in1, in2, cin, output out, cout); + +assign {cout, out} = in1 + in2 + cin; + +endmodule + +module ADD2 #(parameter SIZE = 2)(input [SIZE-1:0] in1, in2, + input cin, output [SIZE-1:0] out, output cout); + +assign {cout, out} = in1 + in2 + cin; + +endmodule + +module ADD4 #(parameter SIZE = 4)(input [SIZE-1:0] in1, in2, + input cin, output [SIZE-1:0] out, output cout); + +assign {cout, out} = in1 + in2 + cin; + +endmodule + +module ADD8 #(parameter SIZE = 8)(input [SIZE-1:0] in1, in2, + input cin, output [SIZE-1:0] out, output cout); + +assign {cout, out} = in1 + in2 + cin; + +endmodule + +module ADD16 #(parameter SIZE = 16)(input [SIZE-1:0] in1, in2, + input cin, output [SIZE-1:0] out, output cout); + +assign {cout, out} = in1 + in2 + cin; + +endmodule + +module ADD32 #(parameter SIZE = 32)(input [SIZE-1:0] in1, in2, + input cin, output [SIZE-1:0] out, output cout); + +assign {cout, out} = in1 + in2 + cin; + +endmodule +module ADD64 #(parameter SIZE = 64)(input [SIZE-1:0] in1, in2, + input cin, output [SIZE-1:0] out, output cout); + +assign {cout, out} = in1 + in2 + cin; + +endmodule + +module SUB1(input in1, in2, cin, output out, cout); + +assign {cout, out} = in1 - in2 - cin; + +endmodule + +module SUB2 #(parameter SIZE = 2)(input [SIZE-1:0] in1, in2, + input cin, output [SIZE-1:0] out, output cout); + +assign {cout, out} = in1 - in2 - cin; + +endmodule + +module SUB4 #(parameter SIZE = 4)(input [SIZE-1:0] in1, in2, + input cin, output [SIZE-1:0] out, output cout); + +assign {cout, out} = in1 - in2 - cin; + +endmodule + +module SUB8 #(parameter SIZE = 8)(input [SIZE-1:0] in1, in2, + input cin, output [SIZE-1:0] out, output cout); + +assign {cout, out} = in1 - in2 - cin; + +endmodule + +module SUB16 #(parameter SIZE = 16)(input [SIZE-1:0] in1, in2, + input cin, output [SIZE-1:0] out, output cout); + +assign {cout, out} = in1 - in2 - cin; + +endmodule + +module SUB32 #(parameter SIZE = 32)(input [SIZE-1:0] in1, in2, + input cin, output [SIZE-1:0] out, output cout); + +assign {cout, out} = in1 - in2 - cin; + +endmodule +module SUB64 #(parameter SIZE = 64)(input [SIZE-1:0] in1, in2, + input cin, output [SIZE-1:0] out, output cout); + +assign {cout, out} = in1 - in2 - cin; + +endmodule + +module MUL1 #(parameter SIZE = 1)(input in1, in2, output [2*SIZE-1:0] out); + +assign out = in1*in2; + +endmodule + +module MUL2 #(parameter SIZE = 2)(input [SIZE-1:0] in1, in2, output [2*SIZE-1:0] out); + +assign out = in1*in2; + +endmodule + +module MUL4 #(parameter SIZE = 4)(input [SIZE-1:0] in1, in2, output [2*SIZE-1:0] out); + +assign out = in1*in2; + +endmodule + +module MUL8 #(parameter SIZE = 8)(input [SIZE-1:0] in1, in2, output [2*SIZE-1:0] out); + +assign out = in1*in2; + +endmodule + +module MUL16 #(parameter SIZE = 16)(input [SIZE-1:0] in1, in2, output [2*SIZE-1:0] out); + +assign out = in1*in2; + +endmodule + +module MUL32 #(parameter SIZE = 32)(input [SIZE-1:0] in1, in2, output [2*SIZE-1:0] out); + +assign out = in1*in2; + +endmodule + +module MUL64 #(parameter SIZE = 64)(input [SIZE-1:0] in1, in2, output [2*SIZE-1:0] out); + +assign out = in1*in2; + +endmodule + +module DIV1 #(parameter SIZE = 1)(input in1, in2, output out, rem); + +assign out = in1/in2; +assign rem = in1%in2; + +endmodule + +module DIV2 #(parameter SIZE = 2)(input [SIZE-1:0] in1, in2, + output [SIZE-1:0] out, rem); + +assign out = in1/in2; +assign rem = in1%in2; + +endmodule + +module DIV4 #(parameter SIZE = 4)(input [SIZE-1:0] in1, in2, + output [SIZE-1:0] out, rem); + +assign out = in1/in2; +assign rem = in1%in2; + +endmodule + +module DIV8 #(parameter SIZE = 8)(input [SIZE-1:0] in1, in2, + output [SIZE-1:0] out, rem); + +assign out = in1/in2; +assign rem = in1%in2; + +endmodule + +module DIV16 #(parameter SIZE = 16)(input [SIZE-1:0] in1, in2, + output [SIZE-1:0] out, rem); + +assign out = in1/in2; +assign rem = in1%in2; + +endmodule + +module DIV32 #(parameter SIZE = 32)(input [SIZE-1:0] in1, in2, + output [SIZE-1:0] out, rem); + +assign out = in1/in2; +assign rem = in1%in2; + +endmodule + +module DIV64 #(parameter SIZE = 64)(input [SIZE-1:0] in1, in2, + output [SIZE-1:0] out, rem); + +assign out = in1/in2; +assign rem = in1%in2; + +endmodule + +module FF (input d, clk, output reg q); +always @( posedge clk) + q <= d; +endmodule + + +module RFF(input d, clk, reset, output reg q); +always @(posedge clk or posedge reset) + if(reset) + q <= 0; + else + q <= d; +endmodule + +module SFF(input d, clk, set, output reg q); +always @(posedge clk or posedge set) + if(set) + q <= 1; + else + q <= d; +endmodule + +module RSFF(input d, clk, set, reset, output reg q); +always @(posedge clk or posedge reset or posedge set) + if(reset) + q <= 0; + else if(set) + q <= 1; + else + q <= d; +endmodule + +module SRFF(input d, clk, set, reset, output reg q); +always @(posedge clk or posedge set or posedge reset) + if(set) + q <= 1; + else if(reset) + q <= 0; + else + q <= d; +endmodule + +module LATCH(input d, enable, output reg q); +always @( d or enable) + if(enable) + q <= d; +endmodule + +module RLATCH(input d, reset, enable, output reg q); +always @( d or enable or reset) + if(enable) + if(reset) + q <= 0; + else + q <= d; +endmodule + +module LSHIFT1 #(parameter SIZE = 1)(input in, shift, val, output reg out); + +always @ (in, shift, val) begin + if(shift) + out = val; + else + out = in; +end + +endmodule + + +module LSHIFT2 #(parameter SIZE = 2)(input [SIZE-1:0] in, + input [SIZE-1:0] shift, input val, + output reg [SIZE-1:0] out); + +always @(in or shift or val) begin + out = in << shift; + if(val) + out = out | ({SIZE-1 {1'b1} } >> (SIZE-1-shift)); +end +endmodule + +module LSHIFT4 #(parameter SIZE = 4)(input [SIZE-1:0] in, + input [2:0] shift, input val, output reg [SIZE-1:0] out); + +always @(in or shift or val) begin + out = in << shift; + if(val) + out = out | ({SIZE-1 {1'b1} } >> (SIZE-1-shift)); +end +endmodule + + +module LSHIFT8 #(parameter SIZE = 8)(input [SIZE-1:0] in, + input [3:0] shift, input val, output reg [SIZE-1:0] out); + +always @(in or shift or val) begin + out = in << shift; + if(val) + out = out | ({SIZE-1 {1'b1} } >> (SIZE-1-shift)); +end +endmodule + +module LSHIFT16 #(parameter SIZE = 16)(input [SIZE-1:0] in, + input [4:0] shift, input val, output reg [SIZE-1:0] out); + +always @(in or shift or val) begin + out = in << shift; + if(val) + out = out | ({SIZE-1 {1'b1} } >> (SIZE-1-shift)); +end +endmodule + +module LSHIFT32 #(parameter SIZE = 32)(input [SIZE-1:0] in, + input [5:0] shift, input val, output reg [SIZE-1:0] out); + +always @(in or shift or val) begin + out = in << shift; + if(val) + out = out | ({SIZE-1 {1'b1} } >> (SIZE-1-shift)); +end +endmodule + +module LSHIFT64 #(parameter SIZE = 64)(input [SIZE-1:0] in, + input [6:0] shift, input val, output reg [SIZE-1:0] out); + +always @(in or shift or val) begin + out = in << shift; + if(val) + out = out | ({SIZE-1 {1'b1} } >> (SIZE-1-shift)); +end +endmodule + +module RSHIFT1 #(parameter SIZE = 1)(input in, shift, val, output reg out); + +always @ (in, shift, val) begin + if(shift) + out = val; + else + out = in; +end + +endmodule + +module RSHIFT2 #(parameter SIZE = 2)(input [SIZE-1:0] in, + input [SIZE-1:0] shift, input val, + output reg [SIZE-1:0] out); + +always @(in or shift or val) begin + out = in >> shift; + if(val) + out = out | ({SIZE-1 {1'b1} } << (SIZE-1-shift)); +end + +endmodule + + +module RSHIFT4 #(parameter SIZE = 4)(input [SIZE-1:0] in, + input [2:0] shift, input val, + output reg [SIZE-1:0] out); + +always @(in or shift or val) begin + out = in >> shift; + if(val) + out = out | ({SIZE-1 {1'b1} } << (SIZE-1-shift)); +end +endmodule + +module RSHIFT8 #(parameter SIZE = 8)(input [SIZE-1:0] in, + input [3:0] shift, input val, + output reg [SIZE-1:0] out); + +always @(in or shift or val) begin + out = in >> shift; + if(val) + out = out | ({SIZE-1 {1'b1} } << (SIZE-1-shift)); +end + +endmodule + +module RSHIFT16 #(parameter SIZE = 16)(input [SIZE-1:0] in, + input [4:0] shift, input val, + output reg [SIZE-1:0] out); + +always @(in or shift or val) begin + out = in >> shift; + if(val) + out = out | ({SIZE-1 {1'b1} } << (SIZE-1-shift)); +end +endmodule + + +module RSHIFT32 #(parameter SIZE = 32)(input [SIZE-1:0] in, + input [5:0] shift, input val, + output reg [SIZE-1:0] out); + +always @(in or shift or val) begin + out = in >> shift; + if(val) + out = out | ({SIZE-1 {1'b1} } << (SIZE-1-shift)); +end +endmodule + +module RSHIFT64 #(parameter SIZE = 64)(input [SIZE-1:0] in, + input [6:0] shift, input val, + output reg [SIZE-1:0] out); + +always @(in or shift or val) begin + out = in >> shift; + if(val) + out = out | ({SIZE-1 {1'b1} } << (SIZE-1-shift)); +end +endmodule + +module CMP1 #(parameter SIZE = 1) (input in1, in2, + output reg equal, unequal, greater, lesser); + +always @ (in1 or in2) begin + if(in1 == in2) begin + equal = 1; + unequal = 0; + greater = 0; + lesser = 0; + end + else begin + equal = 0; + unequal = 1; + + if(in1 < in2) begin + greater = 0; + lesser = 1; + end + else begin + greater = 1; + lesser = 0; + end + end +end +endmodule + + +module CMP2 #(parameter SIZE = 2) (input [SIZE-1:0] in1, in2, + output reg equal, unequal, greater, lesser); + +always @ (in1 or in2) begin + if(in1 == in2) begin + equal = 1; + unequal = 0; + greater = 0; + lesser = 0; + end + else begin + equal = 0; + unequal = 1; + + if(in1 < in2) begin + greater = 0; + lesser = 1; + end + else begin + greater = 1; + lesser = 0; + end + end +end +endmodule + +module CMP4 #(parameter SIZE = 4) (input [SIZE-1:0] in1, in2, + output reg equal, unequal, greater, lesser); + +always @ (in1 or in2) begin + if(in1 == in2) begin + equal = 1; + unequal = 0; + greater = 0; + lesser = 0; + end + else begin + equal = 0; + unequal = 1; + + if(in1 < in2) begin + greater = 0; + lesser = 1; + end + else begin + greater = 1; + lesser = 0; + end + end +end +endmodule + +module CMP8 #(parameter SIZE = 8) (input [SIZE-1:0] in1, in2, + output reg equal, unequal, greater, lesser); + +always @ (in1 or in2) begin + if(in1 == in2) begin + equal = 1; + unequal = 0; + greater = 0; + lesser = 0; + end + else begin + equal = 0; + unequal = 1; + + if(in1 < in2) begin + greater = 0; + lesser = 1; + end + else begin + greater = 1; + lesser = 0; + end + end +end +endmodule + +module CMP16 #(parameter SIZE = 16) (input [SIZE-1:0] in1, in2, + output reg equal, unequal, greater, lesser); + +always @ (in1 or in2) begin + if(in1 == in2) begin + equal = 1; + unequal = 0; + greater = 0; + lesser = 0; + end + else begin + equal = 0; + unequal = 1; + + if(in1 < in2) begin + greater = 0; + lesser = 1; + end + else begin + greater = 1; + lesser = 0; + end + end +end +endmodule + +module CMP32 #(parameter SIZE = 32) (input [SIZE-1:0] in1, in2, + output reg equal, unequal, greater, lesser); + +always @ (in1 or in2) begin + if(in1 == in2) begin + equal = 1; + unequal = 0; + greater = 0; + lesser = 0; + end + else begin + equal = 0; + unequal = 1; + + if(in1 < in2) begin + greater = 0; + lesser = 1; + end + else begin + greater = 1; + lesser = 0; + end + end +end +endmodule + +module CMP64 #(parameter SIZE = 64) (input [SIZE-1:0] in1, in2, + output reg equal, unequal, greater, lesser); + +always @ (in1 or in2) begin + if(in1 == in2) begin + equal = 1; + unequal = 0; + greater = 0; + lesser = 0; + end + else begin + equal = 0; + unequal = 1; + + if(in1 < in2) begin + greater = 0; + lesser = 1; + end + else begin + greater = 1; + lesser = 0; + end + end +end +endmodule + +module VCC (output supply1 out); +endmodule + +module GND (output supply0 out); +endmodule + + +module INC1 #(parameter SIZE = 1) (input in, output [SIZE:0] out); + +assign out = in + 1; + +endmodule + +module INC2 #(parameter SIZE = 2) (input [SIZE-1:0] in, output [SIZE:0] out); + +assign out = in + 1; + +endmodule + +module INC4 #(parameter SIZE = 4) (input [SIZE-1:0] in, output [SIZE:0] out); +assign out = in + 1; + +endmodule + +module INC8 #(parameter SIZE = 8) (input [SIZE-1:0] in, output [SIZE:0] out); +assign out = in + 1; + +endmodule + +module INC16 #(parameter SIZE = 16) (input [SIZE-1:0] in, output [SIZE:0] out); +assign out = in + 1; + +endmodule + +module INC32 #(parameter SIZE = 32) (input [SIZE-1:0] in, output [SIZE:0] out); +assign out = in + 1; + +endmodule +module INC64 #(parameter SIZE = 64) (input [SIZE-1:0] in, output [SIZE:0] out); +assign out = in + 1; + +endmodule + diff --git a/tests/hana/run-test.sh b/tests/hana/run-test.sh new file mode 100755 index 00000000..b8e7231c --- /dev/null +++ b/tests/hana/run-test.sh @@ -0,0 +1,3 @@ +#!/bin/bash +make -C ../.. || exit 1 +exec bash ../tools/autotest.sh -l hana_vlib.v test_*.v diff --git a/tests/hana/test_intermout_always_comb_1_test.v b/tests/hana/test_intermout_always_comb_1_test.v new file mode 100644 index 00000000..2d5abc4a --- /dev/null +++ b/tests/hana/test_intermout_always_comb_1_test.v @@ -0,0 +1,13 @@ +module test(a, b, c, d, z); +input a, b, c, d; +output z; +reg z, temp1, temp2; + +always @(a or b or c or d) +begin + temp1 = a ^ b; + temp2 = c ^ d; + z = temp1 ^ temp2; +end + +endmodule diff --git a/tests/hana/test_intermout_always_comb_3_test.v b/tests/hana/test_intermout_always_comb_3_test.v new file mode 100644 index 00000000..234407ef --- /dev/null +++ b/tests/hana/test_intermout_always_comb_3_test.v @@ -0,0 +1,10 @@ +module test (in1, in2, out); +input in1, in2; +output reg out; + +always @ ( in1 or in2) + if(in1 > in2) + out = in1; + else + out = in2; +endmodule diff --git a/tests/hana/test_intermout_always_comb_4_test.v b/tests/hana/test_intermout_always_comb_4_test.v new file mode 100644 index 00000000..b0a94f29 --- /dev/null +++ b/tests/hana/test_intermout_always_comb_4_test.v @@ -0,0 +1,9 @@ +module test(a, b, c); +input b, c; +output reg a; + +always @(b or c) begin +a = b; +a = c; +end +endmodule diff --git a/tests/hana/test_intermout_always_comb_5_test.v b/tests/hana/test_intermout_always_comb_5_test.v new file mode 100644 index 00000000..5152781d --- /dev/null +++ b/tests/hana/test_intermout_always_comb_5_test.v @@ -0,0 +1,11 @@ +module test(ctrl, in1, in2, out); +input ctrl; +input in1, in2; +output reg out; + +always @ (ctrl or in1 or in2) + if(ctrl) + out = in1 & in2; + else + out = in1 | in2; +endmodule diff --git a/tests/hana/test_intermout_always_ff_3_test.v b/tests/hana/test_intermout_always_ff_3_test.v new file mode 100644 index 00000000..ed8630c3 --- /dev/null +++ b/tests/hana/test_intermout_always_ff_3_test.v @@ -0,0 +1,15 @@ +module NonBlockingEx(clk, merge, er, xmit, fddi, claim); +input clk, merge, er, xmit, fddi; +output reg claim; +reg fcr; + +always @(posedge clk) +begin + fcr = er | xmit; + + if(merge) + claim = fcr & fddi; + else + claim = fddi; +end +endmodule diff --git a/tests/hana/test_intermout_always_ff_4_test.v b/tests/hana/test_intermout_always_ff_4_test.v new file mode 100644 index 00000000..cac420a4 --- /dev/null +++ b/tests/hana/test_intermout_always_ff_4_test.v @@ -0,0 +1,11 @@ +module FlipFlop(clk, cs, ns); +input clk; +input [31:0] cs; +output [31:0] ns; +integer is; + +always @(posedge clk) + is <= cs; + +assign ns = is; +endmodule diff --git a/tests/hana/test_intermout_always_ff_5_test.v b/tests/hana/test_intermout_always_ff_5_test.v new file mode 100644 index 00000000..669b2a5f --- /dev/null +++ b/tests/hana/test_intermout_always_ff_5_test.v @@ -0,0 +1,13 @@ +module FlipFlop(clock, cs, ns); +input clock; +input [3:0] cs; +output reg [3:0] ns; +reg [3:0] temp; + +always @(posedge clock) +begin + temp = cs; + ns = temp; +end + +endmodule diff --git a/tests/hana/test_intermout_always_ff_6_test.v b/tests/hana/test_intermout_always_ff_6_test.v new file mode 100644 index 00000000..ad0a0df6 --- /dev/null +++ b/tests/hana/test_intermout_always_ff_6_test.v @@ -0,0 +1,7 @@ +module inc(clock, counter); + +input clock; +output reg [3:0] counter; +always @(posedge clock) + counter <= counter + 1; +endmodule diff --git a/tests/hana/test_intermout_always_ff_8_test.v b/tests/hana/test_intermout_always_ff_8_test.v new file mode 100644 index 00000000..0f29ea0a --- /dev/null +++ b/tests/hana/test_intermout_always_ff_8_test.v @@ -0,0 +1,11 @@ +module NegEdgeClock(q, d, clk, reset); +input d, clk, reset; +output reg q; + +always @(negedge clk or negedge reset) + if(!reset) + q <= 1'b0; + else + q <= d; + +endmodule diff --git a/tests/hana/test_intermout_always_ff_9_test.v b/tests/hana/test_intermout_always_ff_9_test.v new file mode 100644 index 00000000..f1f13bbe --- /dev/null +++ b/tests/hana/test_intermout_always_ff_9_test.v @@ -0,0 +1,14 @@ +module MyCounter (clock, preset, updown, presetdata, counter); +input clock, preset, updown; +input [1: 0] presetdata; +output reg [1:0] counter; + +always @(posedge clock) + if(preset) + counter <= presetdata; + else + if(updown) + counter <= counter + 1; + else + counter <= counter - 1; +endmodule diff --git a/tests/hana/test_intermout_always_latch_1_test.v b/tests/hana/test_intermout_always_latch_1_test.v new file mode 100644 index 00000000..a83be20d --- /dev/null +++ b/tests/hana/test_intermout_always_latch_1_test.v @@ -0,0 +1,9 @@ +module test(en, in, out); +input en; +input [1:0] in; +output reg [2:0] out; + +always @ (en or in) + if(en) + out = in + 1; +endmodule diff --git a/tests/hana/test_intermout_bufrm_1_test.v b/tests/hana/test_intermout_bufrm_1_test.v new file mode 100644 index 00000000..8e3d4222 --- /dev/null +++ b/tests/hana/test_intermout_bufrm_1_test.v @@ -0,0 +1,4 @@ +module test(input in, output out); +//no buffer removal +assign out = in; +endmodule diff --git a/tests/hana/test_intermout_bufrm_2_test.v b/tests/hana/test_intermout_bufrm_2_test.v new file mode 100644 index 00000000..853f1dc9 --- /dev/null +++ b/tests/hana/test_intermout_bufrm_2_test.v @@ -0,0 +1,7 @@ +module test(input in, output out); +//intermediate buffers should be removed +wire w1, w2; +assign w1 = in; +assign w2 = w1; +assign out = w2; +endmodule diff --git a/tests/hana/test_intermout_bufrm_6_test.v b/tests/hana/test_intermout_bufrm_6_test.v new file mode 100644 index 00000000..d4f3878d --- /dev/null +++ b/tests/hana/test_intermout_bufrm_6_test.v @@ -0,0 +1,22 @@ +module test(in, out); +input in; +output out; + +wire w1, w2, w3, w4; +assign w1 = in; +assign w2 = w1; +assign w4 = w3; +assign out = w4; +mybuf _mybuf(w2, w3); +endmodule + +module mybuf(in, out); +input in; +output out; +wire w1, w2, w3, w4; + +assign w1 = in; +assign w2 = w1; +assign out = w2; +endmodule + diff --git a/tests/hana/test_intermout_bufrm_7_test.v b/tests/hana/test_intermout_bufrm_7_test.v new file mode 100644 index 00000000..7b651302 --- /dev/null +++ b/tests/hana/test_intermout_bufrm_7_test.v @@ -0,0 +1,33 @@ +module test(in1, in2, out); +input in1, in2; +output out; +// Y with cluster of mybuf instances at the junction + +wire w1, w2, w3, w4, w5, w6, w7, w8, w9, w10; +assign w1 = in1; +assign w2 = w1; +assign w5 = in2; +assign w6 = w5; +assign w10 = w9; +assign out = w10; + +mybuf _mybuf0(w2, w3); +mybuf _mybuf1(w3, w4); + +mybuf _mybuf2(w6, w7); +mybuf _mybuf3(w7, w4); + +mybuf _mybuf4(w4, w8); +mybuf _mybuf5(w8, w9); +endmodule + +module mybuf(in, out); +input in; +output out; +wire w1, w2, w3, w4; + +assign w1 = in; +assign w2 = w1; +assign out = w2; +endmodule + diff --git a/tests/hana/test_intermout_exprs_add_test.v b/tests/hana/test_intermout_exprs_add_test.v new file mode 100644 index 00000000..ec70f347 --- /dev/null +++ b/tests/hana/test_intermout_exprs_add_test.v @@ -0,0 +1,10 @@ +module test(out, in1, in2, vin1, vin2, vout1); +output out; +input in1, in2; +input [1:0] vin1; +input [2:0] vin2; +output [3:0] vout1; + +assign out = in1 + in2; +assign vout1 = vin1 + vin2; +endmodule diff --git a/tests/hana/test_intermout_exprs_binlogic_test.v b/tests/hana/test_intermout_exprs_binlogic_test.v new file mode 100644 index 00000000..eec8c4b1 --- /dev/null +++ b/tests/hana/test_intermout_exprs_binlogic_test.v @@ -0,0 +1,13 @@ +module test(in1, in2, vin1, vin2, out, vout, vin3, vin4, vout1 ); +input in1, in2; +input [1:0] vin1; +input [3:0] vin2; +input [1:0] vin3; +input [3:0] vin4; +output vout, vout1; +output out; + +assign out = in1 && in2; +assign vout = vin1 && vin2; +assign vout1 = vin3 || vin4; +endmodule diff --git a/tests/hana/test_intermout_exprs_bitwiseneg_test.v b/tests/hana/test_intermout_exprs_bitwiseneg_test.v new file mode 100644 index 00000000..5b62bef0 --- /dev/null +++ b/tests/hana/test_intermout_exprs_bitwiseneg_test.v @@ -0,0 +1,5 @@ +module test(output out, input in, output [1:0] vout, input [1:0] vin); + +assign out = ~in; +assign vout = ~vin; +endmodule diff --git a/tests/hana/test_intermout_exprs_buffer_test.v b/tests/hana/test_intermout_exprs_buffer_test.v new file mode 100644 index 00000000..2b4cbc3e --- /dev/null +++ b/tests/hana/test_intermout_exprs_buffer_test.v @@ -0,0 +1,9 @@ +module buffer(in, out, vin, vout); +input in; +output out; +input [1:0] vin; +output [1:0] vout; + +assign out = in; +assign vout = vin; +endmodule diff --git a/tests/hana/test_intermout_exprs_condexpr_mux_test.v b/tests/hana/test_intermout_exprs_condexpr_mux_test.v new file mode 100644 index 00000000..11006e8b --- /dev/null +++ b/tests/hana/test_intermout_exprs_condexpr_mux_test.v @@ -0,0 +1,11 @@ +module test(in1, in2, out, vin1, vin2, vin3, vin4, vout1, vout2, en1, ven1, ven2); +input in1, in2, en1, ven1; +input [1:0] ven2; +output out; +input [1:0] vin1, vin2, vin3, vin4; +output [1:0] vout1, vout2; + +assign out = en1 ? in1 : in2; +assign vout1 = ven1 ? vin1 : vin2; +assign vout2 = ven2 ? vin3 : vin4; +endmodule diff --git a/tests/hana/test_intermout_exprs_condexpr_tribuf_test.v b/tests/hana/test_intermout_exprs_condexpr_tribuf_test.v new file mode 100644 index 00000000..5b778fe9 --- /dev/null +++ b/tests/hana/test_intermout_exprs_condexpr_tribuf_test.v @@ -0,0 +1,9 @@ +module test(in, out, en, vin1, vout1, en1); +input in, en, en1; +output out; +input [1:0] vin1; +output [1:0] vout1; + +assign out = en ? in : 1'bz; +assign vout1 = en1 ? vin1 : 2'bzz; +endmodule diff --git a/tests/hana/test_intermout_exprs_const_test.v b/tests/hana/test_intermout_exprs_const_test.v new file mode 100644 index 00000000..484d8103 --- /dev/null +++ b/tests/hana/test_intermout_exprs_const_test.v @@ -0,0 +1,7 @@ +module test (out, vout); +output out; +output [7:0] vout; + +assign out = 1'b1; +assign vout = 9; +endmodule diff --git a/tests/hana/test_intermout_exprs_constshift_test.v b/tests/hana/test_intermout_exprs_constshift_test.v new file mode 100644 index 00000000..eb21315d --- /dev/null +++ b/tests/hana/test_intermout_exprs_constshift_test.v @@ -0,0 +1,12 @@ +module test(in, out, vin, vout, vin1, vout1, vin2, vout2); + +input in; +input [3:0] vin, vin1, vin2; +output [3:0] vout, vout1, vout2; +output out; + +assign out = in << 1; +assign vout = vin << 2; +assign vout1 = vin1 >> 2; +assign vout2 = vin2 >>> 2; +endmodule diff --git a/tests/hana/test_intermout_exprs_div_test.v b/tests/hana/test_intermout_exprs_div_test.v new file mode 100644 index 00000000..21765fcd --- /dev/null +++ b/tests/hana/test_intermout_exprs_div_test.v @@ -0,0 +1,10 @@ +module test(out, in1, in2, vin1, vin2, vout1); +output out; +input in1, in2; +input [1:0] vin1; +input [2:0] vin2; +output [3:0] vout1; + +assign out = in1 / in2; +assign vout1 = vin1 / vin2; +endmodule diff --git a/tests/hana/test_intermout_exprs_logicneg_test.v b/tests/hana/test_intermout_exprs_logicneg_test.v new file mode 100644 index 00000000..b45b32b9 --- /dev/null +++ b/tests/hana/test_intermout_exprs_logicneg_test.v @@ -0,0 +1,7 @@ +module test(out, vout, in, vin); +output out, vout; +input in; +input [3:0] vin; +assign out = !in; +assign vout = !vin; +endmodule diff --git a/tests/hana/test_intermout_exprs_mod_test.v b/tests/hana/test_intermout_exprs_mod_test.v new file mode 100644 index 00000000..cea6b02d --- /dev/null +++ b/tests/hana/test_intermout_exprs_mod_test.v @@ -0,0 +1,10 @@ +module test(out, in1, in2, vin1, vin2, vout1); +output out; +input in1, in2; +input [1:0] vin1; +input [2:0] vin2; +output [3:0] vout1; + +assign out = in1 % in2; +assign vout1 = vin1 % vin2; +endmodule diff --git a/tests/hana/test_intermout_exprs_mul_test.v b/tests/hana/test_intermout_exprs_mul_test.v new file mode 100644 index 00000000..f9973dad --- /dev/null +++ b/tests/hana/test_intermout_exprs_mul_test.v @@ -0,0 +1,10 @@ +module test(out, in1, in2, vin1, vin2, vout1); +output out; +input in1, in2; +input [1:0] vin1; +input [2:0] vin2; +output [3:0] vout1; + +assign out = in1 * in2; +assign vout1 = vin1 * vin2; +endmodule diff --git a/tests/hana/test_intermout_exprs_redand_test.v b/tests/hana/test_intermout_exprs_redand_test.v new file mode 100644 index 00000000..35fdf73a --- /dev/null +++ b/tests/hana/test_intermout_exprs_redand_test.v @@ -0,0 +1,5 @@ +module test(output out, input [1:0] vin, output out1, input [3:0] vin1); + +assign out = &vin; +assign out1 = &vin1; +endmodule diff --git a/tests/hana/test_intermout_exprs_redop_test.v b/tests/hana/test_intermout_exprs_redop_test.v new file mode 100644 index 00000000..93fdb2e5 --- /dev/null +++ b/tests/hana/test_intermout_exprs_redop_test.v @@ -0,0 +1,16 @@ +module Reduction (A1, A2, A3, A4, A5, A6, Y1, Y2, Y3, Y4, Y5, Y6); +input [1:0] A1; +input [1:0] A2; +input [1:0] A3; +input [1:0] A4; +input [1:0] A5; +input [1:0] A6; +output Y1, Y2, Y3, Y4, Y5, Y6; +//reg Y1, Y2, Y3, Y4, Y5, Y6; +assign Y1=&A1; //reduction AND +assign Y2=|A2; //reduction OR +assign Y3=~&A3; //reduction NAND +assign Y4=~|A4; //reduction NOR +assign Y5=^A5; //reduction XOR +assign Y6=~^A6; //reduction XNOR +endmodule diff --git a/tests/hana/test_intermout_exprs_sub_test.v b/tests/hana/test_intermout_exprs_sub_test.v new file mode 100644 index 00000000..06e3a814 --- /dev/null +++ b/tests/hana/test_intermout_exprs_sub_test.v @@ -0,0 +1,10 @@ +module test(out, in1, in2, vin1, vin2, vout1); +output out; +input in1, in2; +input [1:0] vin1; +input [2:0] vin2; +output [3:0] vout1; + +assign out = in1 - in2; +assign vout1 = vin1 - vin2; +endmodule diff --git a/tests/hana/test_intermout_exprs_unaryminus_test.v b/tests/hana/test_intermout_exprs_unaryminus_test.v new file mode 100644 index 00000000..ee3f229a --- /dev/null +++ b/tests/hana/test_intermout_exprs_unaryminus_test.v @@ -0,0 +1,5 @@ +module test(output out, input in, output [31:0] vout, input [31:0] vin); + +assign out = -in; +assign vout = -vin; +endmodule diff --git a/tests/hana/test_intermout_exprs_unaryplus_test.v b/tests/hana/test_intermout_exprs_unaryplus_test.v new file mode 100644 index 00000000..07be5b24 --- /dev/null +++ b/tests/hana/test_intermout_exprs_unaryplus_test.v @@ -0,0 +1,4 @@ +module test(output out, input in); + +assign out = +in; +endmodule diff --git a/tests/hana/test_intermout_exprs_varshift_test.v b/tests/hana/test_intermout_exprs_varshift_test.v new file mode 100644 index 00000000..2ca35c09 --- /dev/null +++ b/tests/hana/test_intermout_exprs_varshift_test.v @@ -0,0 +1,10 @@ +module test(vin0, vout0); +input [2:0] vin0; +output reg [7:0] vout0; + +wire [7:0] myreg0, myreg1, myreg2; +integer i; +assign myreg0 = vout0 << vin0; + +assign myreg1 = myreg2 >> i; +endmodule diff --git a/tests/hana/test_parse2synthtrans_behavopt_1_test.v b/tests/hana/test_parse2synthtrans_behavopt_1_test.v new file mode 100644 index 00000000..c825739c --- /dev/null +++ b/tests/hana/test_parse2synthtrans_behavopt_1_test.v @@ -0,0 +1,22 @@ +module test(in, out, clk, reset); +input in, reset; +output reg out; +input clk; +reg signed [3:0] a; +reg signed [3:0] b; +reg signed [3:0] c; +reg [5:0] d; +reg [5:0] e; + +always @(clk or reset) begin + a = -4; + b = 2; + c = a + b; + d = a + b + c; + d = d*d; + if(b) + e = d*d; + else + e = d + d; +end +endmodule diff --git a/tests/hana/test_parse2synthtrans_case_1_test.v b/tests/hana/test_parse2synthtrans_case_1_test.v new file mode 100644 index 00000000..348c566a --- /dev/null +++ b/tests/hana/test_parse2synthtrans_case_1_test.v @@ -0,0 +1,26 @@ +module demultiplexer1_to_4 (out0, out1, out2, out3, in, s1, s0); +output out0, out1, out2, out3; +reg out0, out1, out2, out3; +input in; +input s1, s0; +reg [3:0] encoding; +reg [1:0] state; + always @(encoding) begin + case (encoding) + 4'bxx11: state = 1; + 4'bx0xx: state = 3; + 4'b11xx: state = 4; + 4'bx1xx: state = 2; + 4'bxx1x: state = 1; + 4'bxxx1: state = 0; + default: state = 0; + endcase + end + + always @(encoding) begin + case (encoding) + 4'b0000: state = 1; + default: state = 0; + endcase + end +endmodule diff --git a/tests/hana/test_parse2synthtrans_contassign_1_test.v b/tests/hana/test_parse2synthtrans_contassign_1_test.v new file mode 100644 index 00000000..78bf0077 --- /dev/null +++ b/tests/hana/test_parse2synthtrans_contassign_1_test.v @@ -0,0 +1,7 @@ +module test(in, out); + +input wire in; +output out; +assign out = (in+in); +assign out = 74; +endmodule diff --git a/tests/hana/test_parse2synthtrans_module_basic0_test.v b/tests/hana/test_parse2synthtrans_module_basic0_test.v new file mode 100644 index 00000000..67a272df --- /dev/null +++ b/tests/hana/test_parse2synthtrans_module_basic0_test.v @@ -0,0 +1,2 @@ +module test; +endmodule diff --git a/tests/hana/test_parse2synthtrans_operators_1_test.v b/tests/hana/test_parse2synthtrans_operators_1_test.v new file mode 100644 index 00000000..93b5691f --- /dev/null +++ b/tests/hana/test_parse2synthtrans_operators_1_test.v @@ -0,0 +1,11 @@ +module test(in, out); +input in; +output out; +parameter p1 = 10; +parameter p2 = 5; + +assign out = +p1; +assign out = -p2; +assign out = p1 + p2; +assign out = p1 - p2; +endmodule diff --git a/tests/hana/test_parse2synthtrans_param_1_test.v b/tests/hana/test_parse2synthtrans_param_1_test.v new file mode 100644 index 00000000..146eedf4 --- /dev/null +++ b/tests/hana/test_parse2synthtrans_param_1_test.v @@ -0,0 +1,7 @@ +module test(in, out); +input in; +output out; +parameter p = 10; + +assign out = p; +endmodule diff --git a/tests/hana/test_parse2synthtrans_port_scalar_1_test.v b/tests/hana/test_parse2synthtrans_port_scalar_1_test.v new file mode 100644 index 00000000..8cdf495a --- /dev/null +++ b/tests/hana/test_parse2synthtrans_port_scalar_1_test.v @@ -0,0 +1,6 @@ +module test(in, out, io); +inout io; +output out; +input in; + +endmodule diff --git a/tests/hana/test_parse2synthtrans_port_vector_1_test.v b/tests/hana/test_parse2synthtrans_port_vector_1_test.v new file mode 100644 index 00000000..a740282b --- /dev/null +++ b/tests/hana/test_parse2synthtrans_port_vector_1_test.v @@ -0,0 +1,9 @@ +module test(in1, in2, out1, out2, io1, io2); +inout [1:0] io1; +inout [0:1] io2; +output [1:0] out1; +output [0:1] out2; +input [1:0] in1; +input [0:1] in2; + +endmodule diff --git a/tests/hana/test_parse2synthtrans_v2k_comb_logic_sens_list_test.v b/tests/hana/test_parse2synthtrans_v2k_comb_logic_sens_list_test.v new file mode 100644 index 00000000..50f1d353 --- /dev/null +++ b/tests/hana/test_parse2synthtrans_v2k_comb_logic_sens_list_test.v @@ -0,0 +1,9 @@ +module test(q, d, clk, reset); +output reg q; +input d, clk, reset; + +always @ (posedge clk, negedge reset) + if(!reset) q <= 0; + else q <= d; + +endmodule diff --git a/tests/hana/test_parser_constructs_module_basic1_test.v b/tests/hana/test_parser_constructs_module_basic1_test.v new file mode 100644 index 00000000..67a272df --- /dev/null +++ b/tests/hana/test_parser_constructs_module_basic1_test.v @@ -0,0 +1,2 @@ +module test; +endmodule diff --git a/tests/hana/test_parser_constructs_param_basic0_test.v b/tests/hana/test_parser_constructs_param_basic0_test.v new file mode 100644 index 00000000..fd679230 --- /dev/null +++ b/tests/hana/test_parser_constructs_param_basic0_test.v @@ -0,0 +1,10 @@ +module test #( parameter v2kparam = 5) +(in, out, io, vin, vout, vio); +input in; +output out; +inout io; +input [3:0] vin; +output [v2kparam:0] vout; +inout [0:3] vio; +parameter myparam = 10; +endmodule diff --git a/tests/hana/test_parser_constructs_port_basic0_test.v b/tests/hana/test_parser_constructs_port_basic0_test.v new file mode 100644 index 00000000..8478e31d --- /dev/null +++ b/tests/hana/test_parser_constructs_port_basic0_test.v @@ -0,0 +1,8 @@ +module test(in, out, io, vin, vout, vio); +input in; +output out; +inout io; +input [3:0] vin; +output [3:0] vout; +inout [0:3] vio; +endmodule diff --git a/tests/hana/test_parser_directives_define_simpledef_test.v b/tests/hana/test_parser_directives_define_simpledef_test.v new file mode 100644 index 00000000..4a5d2345 --- /dev/null +++ b/tests/hana/test_parser_directives_define_simpledef_test.v @@ -0,0 +1,9 @@ +`define parvez ahmad +`define WIRE wire +`define TEN 10 + +module `parvez(); +parameter param = `TEN; +`WIRE w; +assign w = `TEN; +endmodule diff --git a/tests/hana/test_parser_misc_operators_test.v b/tests/hana/test_parser_misc_operators_test.v new file mode 100644 index 00000000..8fe8e7ba --- /dev/null +++ b/tests/hana/test_parser_misc_operators_test.v @@ -0,0 +1,29 @@ +module test(out, i0, i1, i2, i3, s1, s0); +output out; +input i0, i1, i2, i3; +input s1, s0; + +assign out = (~s1 & s0 & i0) | + (~s1 & s0 & i1) | + (s1 & ~s0 & i2) | + (s1 & s0 & i3); + +endmodule + +module ternaryop(out, i0, i1, i2, i3, s1, s0); +output out; +input i0, i1, i2, i3; +input s1, s0; + +assign out = s1 ? (s0 ? i3 : i2) : (s0 ? i1 : i0); + +endmodule + +module fulladd4(sum, c_out, a, b, c_in); +output [3:0] sum; +output c_out; +input [3:0] a, b; +input c_in; + +assign {c_out, sum} = a + b + c_in; +endmodule diff --git a/tests/hana/test_parser_v2k_comb_port_data_type_test.v b/tests/hana/test_parser_v2k_comb_port_data_type_test.v new file mode 100644 index 00000000..099585b5 --- /dev/null +++ b/tests/hana/test_parser_v2k_comb_port_data_type_test.v @@ -0,0 +1,6 @@ +module adder(sum , co, a, b, ci); +output reg [31:0] sum; +output reg co; +input wire [31:0] a, b; +input wire ci; +endmodule diff --git a/tests/hana/test_parser_v2k_comma_sep_sens_list_test.v b/tests/hana/test_parser_v2k_comma_sep_sens_list_test.v new file mode 100644 index 00000000..50f1d353 --- /dev/null +++ b/tests/hana/test_parser_v2k_comma_sep_sens_list_test.v @@ -0,0 +1,9 @@ +module test(q, d, clk, reset); +output reg q; +input d, clk, reset; + +always @ (posedge clk, negedge reset) + if(!reset) q <= 0; + else q <= d; + +endmodule diff --git a/tests/hana/test_simulation_always_15_test.v b/tests/hana/test_simulation_always_15_test.v new file mode 100644 index 00000000..5c5fed5b --- /dev/null +++ b/tests/hana/test_simulation_always_15_test.v @@ -0,0 +1,5 @@ +module test(input [1:0] in, output reg [1:0] out); + +always @(in) + out = in; +endmodule diff --git a/tests/hana/test_simulation_always_17_test.v b/tests/hana/test_simulation_always_17_test.v new file mode 100644 index 00000000..2d5abc4a --- /dev/null +++ b/tests/hana/test_simulation_always_17_test.v @@ -0,0 +1,13 @@ +module test(a, b, c, d, z); +input a, b, c, d; +output z; +reg z, temp1, temp2; + +always @(a or b or c or d) +begin + temp1 = a ^ b; + temp2 = c ^ d; + z = temp1 ^ temp2; +end + +endmodule diff --git a/tests/hana/test_simulation_always_18_test.v b/tests/hana/test_simulation_always_18_test.v new file mode 100644 index 00000000..234407ef --- /dev/null +++ b/tests/hana/test_simulation_always_18_test.v @@ -0,0 +1,10 @@ +module test (in1, in2, out); +input in1, in2; +output reg out; + +always @ ( in1 or in2) + if(in1 > in2) + out = in1; + else + out = in2; +endmodule diff --git a/tests/hana/test_simulation_always_19_test.v b/tests/hana/test_simulation_always_19_test.v new file mode 100644 index 00000000..5152781d --- /dev/null +++ b/tests/hana/test_simulation_always_19_test.v @@ -0,0 +1,11 @@ +module test(ctrl, in1, in2, out); +input ctrl; +input in1, in2; +output reg out; + +always @ (ctrl or in1 or in2) + if(ctrl) + out = in1 & in2; + else + out = in1 | in2; +endmodule diff --git a/tests/hana/test_simulation_always_1_test.v b/tests/hana/test_simulation_always_1_test.v new file mode 100644 index 00000000..211369cb --- /dev/null +++ b/tests/hana/test_simulation_always_1_test.v @@ -0,0 +1,5 @@ +module test(input in, output reg out); + +always @(in) + out = in; +endmodule diff --git a/tests/hana/test_simulation_always_20_test.v b/tests/hana/test_simulation_always_20_test.v new file mode 100644 index 00000000..6b3e861d --- /dev/null +++ b/tests/hana/test_simulation_always_20_test.v @@ -0,0 +1,15 @@ +module NonBlockingEx(clk, merge, er, xmit, fddi, claim); +input clk, merge, er, xmit, fddi; +output reg claim; +reg fcr; + +always @(posedge clk) +begin + fcr <= er | xmit; + + if(merge) + claim <= fcr & fddi; + else + claim <= fddi; +end +endmodule diff --git a/tests/hana/test_simulation_always_21_test.v b/tests/hana/test_simulation_always_21_test.v new file mode 100644 index 00000000..6c47b4bd --- /dev/null +++ b/tests/hana/test_simulation_always_21_test.v @@ -0,0 +1,11 @@ +module FlipFlop(clk, cs, ns); +input clk; +input [7:0] cs; +output [7:0] ns; +integer is; + +always @(posedge clk) + is <= cs; + +assign ns = is; +endmodule diff --git a/tests/hana/test_simulation_always_22_test.v b/tests/hana/test_simulation_always_22_test.v new file mode 100644 index 00000000..8d91f815 --- /dev/null +++ b/tests/hana/test_simulation_always_22_test.v @@ -0,0 +1,7 @@ +module inc(clock, counter); + +input clock; +output reg [7:0] counter; +always @(posedge clock) + counter <= counter + 1; +endmodule diff --git a/tests/hana/test_simulation_always_23_test.v b/tests/hana/test_simulation_always_23_test.v new file mode 100644 index 00000000..f1f13bbe --- /dev/null +++ b/tests/hana/test_simulation_always_23_test.v @@ -0,0 +1,14 @@ +module MyCounter (clock, preset, updown, presetdata, counter); +input clock, preset, updown; +input [1: 0] presetdata; +output reg [1:0] counter; + +always @(posedge clock) + if(preset) + counter <= presetdata; + else + if(updown) + counter <= counter + 1; + else + counter <= counter - 1; +endmodule diff --git a/tests/hana/test_simulation_always_27_test.v b/tests/hana/test_simulation_always_27_test.v new file mode 100644 index 00000000..577378fd --- /dev/null +++ b/tests/hana/test_simulation_always_27_test.v @@ -0,0 +1,13 @@ +module FlipFlop(clock, cs, ns); +input clock; +input cs; +output reg ns; +reg temp; + +always @(posedge clock) +begin + temp <= cs; + ns <= temp; +end + +endmodule diff --git a/tests/hana/test_simulation_always_29_test.v b/tests/hana/test_simulation_always_29_test.v new file mode 100644 index 00000000..55606832 --- /dev/null +++ b/tests/hana/test_simulation_always_29_test.v @@ -0,0 +1,9 @@ +module test(input in, output reg [1:0] out); + + always @(in) + begin + out = in; + out = out + in; + end + +endmodule diff --git a/tests/hana/test_simulation_always_31_tt.v b/tests/hana/test_simulation_always_31_tt.v new file mode 100644 index 00000000..299c0ca4 --- /dev/null +++ b/tests/hana/test_simulation_always_31_tt.v @@ -0,0 +1,50 @@ +module test(clk, cond, data); +input cond; +input clk; +output data; + +wire synth_net; +wire synth_net_0; +wire synth_net_1; +wire synth_net_2; + +wire synth_net_3; +wire synth_net_4; +wire synth_net_5; +wire synth_net_6; + +wire synth_net_7; +wire synth_net_8; +wire synth_net_9; +wire synth_net_10; + +wire synth_net_11; +wire tmp; +AND2 synth_AND(.in({synth_net_0, synth_net_1}), . + out(synth_net_2)); +AND2 synth_AND_0(.in({synth_net_3, synth_net_4}), .out( + synth_net_5)); +AND2 synth_AND_1(.in({synth_net_6, synth_net_7}), .out( + synth_net_8)); +AND2 synth_AND_2(.in({synth_net_9, synth_net_10}), .out( + synth_net_11)); +BUF synth_BUF(.in(synth_net), .out(synth_net_0)); +BUF + synth_BUF_0(.in(data), .out(synth_net_3)); +BUF synth_BUF_1(.in(synth_net_8) + , .out(tmp)); +BUF synth_BUF_2(.in(tmp), .out(synth_net_9)); +MUX2 synth_MUX(. + in({synth_net_2, synth_net_5}), .select(cond), .out(synth_net_6)); +MUX2 + synth_MUX_0(.in({synth_net_1, synth_net_4}), .select(cond), .out(synth_net_7 + )); +FF synth_FF(.d(synth_net_11), .clk(clk), .q(data)); +VCC synth_VCC(.out( + synth_net)); +VCC synth_VCC_0(.out(synth_net_1)); +VCC synth_VCC_1(.out( + synth_net_4)); +VCC synth_VCC_2(.out(synth_net_10)); +endmodule + diff --git a/tests/hana/test_simulation_and_1_test.v b/tests/hana/test_simulation_and_1_test.v new file mode 100644 index 00000000..fba639ca --- /dev/null +++ b/tests/hana/test_simulation_and_1_test.v @@ -0,0 +1,3 @@ +module test(input [1:0] in, output out); +assign out = in[0] & in[1]; +endmodule diff --git a/tests/hana/test_simulation_and_2_test.v b/tests/hana/test_simulation_and_2_test.v new file mode 100644 index 00000000..715bc7ca --- /dev/null +++ b/tests/hana/test_simulation_and_2_test.v @@ -0,0 +1,3 @@ +module test(input [1:0] in, output out); +assign out = in[0] && in[1]; +endmodule diff --git a/tests/hana/test_simulation_and_3_test.v b/tests/hana/test_simulation_and_3_test.v new file mode 100644 index 00000000..74dccabf --- /dev/null +++ b/tests/hana/test_simulation_and_3_test.v @@ -0,0 +1,3 @@ +module test(input [2:0] in, output out); +assign out = in[0] & in[1] & in[2]; +endmodule diff --git a/tests/hana/test_simulation_and_4_test.v b/tests/hana/test_simulation_and_4_test.v new file mode 100644 index 00000000..48ed9102 --- /dev/null +++ b/tests/hana/test_simulation_and_4_test.v @@ -0,0 +1,3 @@ +module test(input [2:0] in, output out); +assign out = in[0] && in[1] && in[2]; +endmodule diff --git a/tests/hana/test_simulation_and_5_test.v b/tests/hana/test_simulation_and_5_test.v new file mode 100644 index 00000000..29a35578 --- /dev/null +++ b/tests/hana/test_simulation_and_5_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +assign out = in[0] & in[1] & in[2] & in[3]; +endmodule diff --git a/tests/hana/test_simulation_and_6_test.v b/tests/hana/test_simulation_and_6_test.v new file mode 100644 index 00000000..ebce4eeb --- /dev/null +++ b/tests/hana/test_simulation_and_6_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +assign out = in[0] && in[1] && in[2] && in[3]; +endmodule diff --git a/tests/hana/test_simulation_and_7_test.v b/tests/hana/test_simulation_and_7_test.v new file mode 100644 index 00000000..d394adad --- /dev/null +++ b/tests/hana/test_simulation_and_7_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +and myand(out, in[0], in[1], in[2], in[3]); +endmodule diff --git a/tests/hana/test_simulation_buffer_1_test.v b/tests/hana/test_simulation_buffer_1_test.v new file mode 100644 index 00000000..e9bb7f61 --- /dev/null +++ b/tests/hana/test_simulation_buffer_1_test.v @@ -0,0 +1,3 @@ +module test(input in, output out); +assign out = in; +endmodule diff --git a/tests/hana/test_simulation_buffer_2_test.v b/tests/hana/test_simulation_buffer_2_test.v new file mode 100644 index 00000000..9a3f5aa3 --- /dev/null +++ b/tests/hana/test_simulation_buffer_2_test.v @@ -0,0 +1,4 @@ +module test(input [1:0] in, output [1:0] out); +assign out[0] = in[0]; +assign out[1] = in[1]; +endmodule diff --git a/tests/hana/test_simulation_buffer_3_test.v b/tests/hana/test_simulation_buffer_3_test.v new file mode 100644 index 00000000..9bca426d --- /dev/null +++ b/tests/hana/test_simulation_buffer_3_test.v @@ -0,0 +1,4 @@ +module test(input in, output [1:0] out); +assign out[0] = in; +assign out[1] = in; +endmodule diff --git a/tests/hana/test_simulation_decoder_2_test.v b/tests/hana/test_simulation_decoder_2_test.v new file mode 100644 index 00000000..5bdf1971 --- /dev/null +++ b/tests/hana/test_simulation_decoder_2_test.v @@ -0,0 +1,14 @@ +module test (input [1:0] in, input enable, output reg out); + +always @(in or enable) + if(!enable) + out = 4'b0000; + else begin + case (in) + 2'b00 : out = 0 ; + 2'b01 : out = 1; + 2'b10 : out = 0; + 2'b11 : out = 1; + endcase + end +endmodule diff --git a/tests/hana/test_simulation_decoder_3_test.v b/tests/hana/test_simulation_decoder_3_test.v new file mode 100644 index 00000000..44f5de12 --- /dev/null +++ b/tests/hana/test_simulation_decoder_3_test.v @@ -0,0 +1,14 @@ +module test (input [1:0] in, input enable, output reg [2:0] out); + +always @(in or enable) + if(!enable) + out = 3'b000; + else begin + case (in) + 2'b00 : out = 3'b001 ; + 2'b01 : out = 3'b010; + 2'b10 : out = 3'b010; + 2'b11 : out = 3'b100; + endcase + end +endmodule diff --git a/tests/hana/test_simulation_decoder_4_test.v b/tests/hana/test_simulation_decoder_4_test.v new file mode 100644 index 00000000..871a5bbf --- /dev/null +++ b/tests/hana/test_simulation_decoder_4_test.v @@ -0,0 +1,14 @@ +module test (input [2:0] in, output reg [7:0] out); + +always @(in ) + case (in) + 3'b000 : out = 8'b00000001; + 3'b001 : out = 8'b00000010; + 3'b010 : out = 8'b00000100; + 3'b011 : out = 8'b00001000; + 3'b100 : out = 8'b00010000; + 3'b101 : out = 8'b00100000; + 3'b110 : out = 8'b01000000; + 3'b111 : out = 8'b10000000; + endcase +endmodule diff --git a/tests/hana/test_simulation_decoder_5_test.v b/tests/hana/test_simulation_decoder_5_test.v new file mode 100644 index 00000000..497fa4bf --- /dev/null +++ b/tests/hana/test_simulation_decoder_5_test.v @@ -0,0 +1,17 @@ +module test (input [2:0] in, input enable, output reg [7:0] out); + +always @(in or enable ) + if(!enable) + out = 8'b00000000; + else + case (in) + 3'b000 : out = 8'b00000001; + 3'b001 : out = 8'b00000010; + 3'b010 : out = 8'b00000100; + 3'b011 : out = 8'b00001000; + 3'b100 : out = 8'b00010000; + 3'b101 : out = 8'b00100000; + 3'b110 : out = 8'b01000000; + 3'b111 : out = 8'b10000000; + endcase +endmodule diff --git a/tests/hana/test_simulation_decoder_6_test.v b/tests/hana/test_simulation_decoder_6_test.v new file mode 100644 index 00000000..fd19ad60 --- /dev/null +++ b/tests/hana/test_simulation_decoder_6_test.v @@ -0,0 +1,27 @@ +module test (input [3:0] in, input enable, output reg [15:0] out); + +always @(in or enable) + if(!enable) + out = 16'b0000000000000000; + else begin + case (in) + 4'b0000 : out = 16'b0000000000000001; + 4'b0001 : out = 16'b0000000000000010; + 4'b0010 : out = 16'b0000000000000100; + 4'b0011 : out = 16'b0000000000001000; + 4'b0100 : out = 16'b0000000000010000; + 4'b0101 : out = 16'b0000000000100000; + 4'b0110 : out = 16'b0000000001000000; + 4'b0111 : out = 16'b0000000010000000; + 4'b1000 : out = 16'b0000000100000000; + 4'b1001 : out = 16'b0000001000000000; + 4'b1010 : out = 16'b0000010000000000; + 4'b1011 : out = 16'b0000100000000000; + 4'b1100 : out = 16'b0001000000000000; + 4'b1101 : out = 16'b0010000000000000; + 4'b1110 : out = 16'b0100000000000000; + 4'b1111 : out = 16'b1000000000000000; + endcase + end +endmodule + diff --git a/tests/hana/test_simulation_decoder_7_test.v b/tests/hana/test_simulation_decoder_7_test.v new file mode 100644 index 00000000..462e9419 --- /dev/null +++ b/tests/hana/test_simulation_decoder_7_test.v @@ -0,0 +1,43 @@ +module test (input [4:0] in, input enable, output reg [31:0] out); + +always @(in or enable) + if(!enable) + out = 32'b00000000000000000000000000000000; + else begin + case (in) + 5'b00000 : out = 32'b00000000000000000000000000000001; + 5'b00001 : out = 32'b00000000000000000000000000000010; + 5'b00010 : out = 32'b00000000000000000000000000000100; + 5'b00011 : out = 32'b00000000000000000000000000001000; + 5'b00100 : out = 32'b00000000000000000000000000010000; + 5'b00101 : out = 32'b00000000000000000000000000100000; + 5'b00110 : out = 32'b00000000000000000000000001000000; + 5'b00111 : out = 32'b00000000000000000000000010000000; + 5'b01000 : out = 32'b00000000000000000000000100000000; + 5'b01001 : out = 32'b00000000000000000000001000000000; + 5'b01010 : out = 32'b00000000000000000000010000000000; + 5'b01011 : out = 32'b00000000000000000000100000000000; + 5'b01100 : out = 32'b00000000000000000001000000000000; + 5'b01101 : out = 32'b00000000000000000010000000000000; + 5'b01110 : out = 32'b00000000000000000100000000000000; + 5'b01111 : out = 32'b00000000000000001000000000000000; + 5'b10000 : out = 32'b00000000000000010000000000000000; + 5'b10001 : out = 32'b00000000000000100000000000000000; + 5'b10010 : out = 32'b00000000000001000000000000000000; + 5'b10011 : out = 32'b00000000000010000000000000000000; + 5'b10100 : out = 32'b00000000000100000000000000000000; + 5'b10101 : out = 32'b00000000001000000000000000000000; + 5'b10110 : out = 32'b00000000010000000000000000000000; + 5'b10111 : out = 32'b00000000100000000000000000000000; + 5'b11000 : out = 32'b00000001000000000000000000000000; + 5'b11001 : out = 32'b00000010000000000000000000000000; + 5'b11010 : out = 32'b00000100000000000000000000000000; + 5'b11011 : out = 32'b00001000000000000000000000000000; + 5'b11100 : out = 32'b00010000000000000000000000000000; + 5'b11101 : out = 32'b00100000000000000000000000000000; + 5'b11110 : out = 32'b01000000000000000000000000000000; + 5'b11111 : out = 32'b10000000000000000000000000000000; + endcase + end +endmodule + diff --git a/tests/hana/test_simulation_decoder_8_test.v b/tests/hana/test_simulation_decoder_8_test.v new file mode 100644 index 00000000..751d60f6 --- /dev/null +++ b/tests/hana/test_simulation_decoder_8_test.v @@ -0,0 +1,76 @@ +module test (input [5:0] in, input enable, output reg [63:0] out); + +always @(in or enable) + if(!enable) + out = 64'b0000000000000000000000000000000000000000000000000000000000000000; + else begin + case (in) + 6'b000000 : out = 64'b0000000000000000000000000000000000000000000000000000000000000001; + 6'b000001 : out = 64'b0000000000000000000000000000000000000000000000000000000000000010; + 6'b000010 : out = 64'b0000000000000000000000000000000000000000000000000000000000000100; + 6'b000011 : out = 64'b0000000000000000000000000000000000000000000000000000000000001000; + 6'b000100 : out = 64'b0000000000000000000000000000000000000000000000000000000000010000; + 6'b000101 : out = 64'b0000000000000000000000000000000000000000000000000000000000100000; + 6'b000110 : out = 64'b0000000000000000000000000000000000000000000000000000000001000000; + 6'b000111 : out = 64'b0000000000000000000000000000000000000000000000000000000010000000; + 6'b001000 : out = 64'b0000000000000000000000000000000000000000000000000000000100000000; + 6'b001001 : out = 64'b0000000000000000000000000000000000000000000000000000001000000000; + 6'b001010 : out = 64'b0000000000000000000000000000000000000000000000000000010000000000; + 6'b001011 : out = 64'b0000000000000000000000000000000000000000000000000000100000000000; + 6'b001100 : out = 64'b0000000000000000000000000000000000000000000000000001000000000000; + 6'b001101 : out = 64'b0000000000000000000000000000000000000000000000000010000000000000; + 6'b001110 : out = 64'b0000000000000000000000000000000000000000000000000100000000000000; + 6'b001111 : out = 64'b0000000000000000000000000000000000000000000000001000000000000000; + 6'b010000 : out = 64'b0000000000000000000000000000000000000000000000010000000000000000; + 6'b010001 : out = 64'b0000000000000000000000000000000000000000000000100000000000000000; + 6'b010010 : out = 64'b0000000000000000000000000000000000000000000001000000000000000000; + 6'b010011 : out = 64'b0000000000000000000000000000000000000000000010000000000000000000; + 6'b010100 : out = 64'b0000000000000000000000000000000000000000000100000000000000000000; + 6'b010101 : out = 64'b0000000000000000000000000000000000000000001000000000000000000000; + 6'b010110 : out = 64'b0000000000000000000000000000000000000000010000000000000000000000; + 6'b010111 : out = 64'b0000000000000000000000000000000000000000100000000000000000000000; + 6'b011000 : out = 64'b0000000000000000000000000000000000000001000000000000000000000000; + 6'b011001 : out = 64'b0000000000000000000000000000000000000010000000000000000000000000; + 6'b011010 : out = 64'b0000000000000000000000000000000000000100000000000000000000000000; + 6'b011011 : out = 64'b0000000000000000000000000000000000001000000000000000000000000000; + 6'b011100 : out = 64'b0000000000000000000000000000000000010000000000000000000000000000; + 6'b011101 : out = 64'b0000000000000000000000000000000000100000000000000000000000000000; + 6'b011110 : out = 64'b0000000000000000000000000000000001000000000000000000000000000000; + 6'b011111 : out = 64'b0000000000000000000000000000000010000000000000000000000000000000; + + 6'b100000 : out = 64'b0000000000000000000000000000000100000000000000000000000000000000; + 6'b100001 : out = 64'b0000000000000000000000000000001000000000000000000000000000000000; + 6'b100010 : out = 64'b0000000000000000000000000000010000000000000000000000000000000000; + 6'b100011 : out = 64'b0000000000000000000000000000100000000000000000000000000000000000; + 6'b100100 : out = 64'b0000000000000000000000000001000000000000000000000000000000000000; + 6'b100101 : out = 64'b0000000000000000000000000010000000000000000000000000000000000000; + 6'b100110 : out = 64'b0000000000000000000000000100000000000000000000000000000000000000; + 6'b100111 : out = 64'b0000000000000000000000001000000000000000000000000000000000000000; + 6'b101000 : out = 64'b0000000000000000000000010000000000000000000000000000000000000000; + 6'b101001 : out = 64'b0000000000000000000000100000000000000000000000000000000000000000; + 6'b101010 : out = 64'b0000000000000000000001000000000000000000000000000000000000000000; + 6'b101011 : out = 64'b0000000000000000000010000000000000000000000000000000000000000000; + 6'b101100 : out = 64'b0000000000000000000100000000000000000000000000000000000000000000; + 6'b101101 : out = 64'b0000000000000000001000000000000000000000000000000000000000000000; + 6'b101110 : out = 64'b0000000000000000010000000000000000000000000000000000000000000000; + 6'b101111 : out = 64'b0000000000000000100000000000000000000000000000000000000000000000; + 6'b110000 : out = 64'b0000000000000001000000000000000000000000000000000000000000000000; + 6'b110001 : out = 64'b0000000000000010000000000000000000000000000000000000000000000000; + 6'b110010 : out = 64'b0000000000000100000000000000000000000000000000000000000000000000; + 6'b110011 : out = 64'b0000000000001000000000000000000000000000000000000000000000000000; + 6'b110100 : out = 64'b0000000000010000000000000000000000000000000000000000000000000000; + 6'b110101 : out = 64'b0000000000100000000000000000000000000000000000000000000000000000; + 6'b110110 : out = 64'b0000000001000000000000000000000000000000000000000000000000000000; + 6'b110111 : out = 64'b0000000010000000000000000000000000000000000000000000000000000000; + 6'b111000 : out = 64'b0000000100000000000000000000000000000000000000000000000000000000; + 6'b111001 : out = 64'b0000001000000000000000000000000000000000000000000000000000000000; + 6'b111010 : out = 64'b0000010000000000000000000000000000000000000000000000000000000000; + 6'b111011 : out = 64'b0000100000000000000000000000000000000000000000000000000000000000; + 6'b111100 : out = 64'b0001000000000000000000000000000000000000000000000000000000000000; + 6'b111101 : out = 64'b0010000000000000000000000000000000000000000000000000000000000000; + 6'b111110 : out = 64'b0100000000000000000000000000000000000000000000000000000000000000; + 6'b111111 : out = 64'b1000000000000000000000000000000000000000000000000000000000000000; + endcase + end +endmodule + diff --git a/tests/hana/test_simulation_inc_16_test.v b/tests/hana/test_simulation_inc_16_test.v new file mode 100644 index 00000000..7ff42ff5 --- /dev/null +++ b/tests/hana/test_simulation_inc_16_test.v @@ -0,0 +1,5 @@ +module test(input [15:0] in, output [15:0] out); + +assign out = -in; + +endmodule diff --git a/tests/hana/test_simulation_inc_1_test.v b/tests/hana/test_simulation_inc_1_test.v new file mode 100644 index 00000000..02bec2c2 --- /dev/null +++ b/tests/hana/test_simulation_inc_1_test.v @@ -0,0 +1,5 @@ +module test(input in, output out); + +assign out = -in; + +endmodule diff --git a/tests/hana/test_simulation_inc_2_test.v b/tests/hana/test_simulation_inc_2_test.v new file mode 100644 index 00000000..b96e05a2 --- /dev/null +++ b/tests/hana/test_simulation_inc_2_test.v @@ -0,0 +1,5 @@ +module test(input [1:0] in, output [1:0] out); + +assign out = -in; + +endmodule diff --git a/tests/hana/test_simulation_inc_32_test.v b/tests/hana/test_simulation_inc_32_test.v new file mode 100644 index 00000000..5700d0ce --- /dev/null +++ b/tests/hana/test_simulation_inc_32_test.v @@ -0,0 +1,5 @@ +module test(input [31:0] in, output [31:0] out); + +assign out = -in; + +endmodule diff --git a/tests/hana/test_simulation_inc_4_test.v b/tests/hana/test_simulation_inc_4_test.v new file mode 100644 index 00000000..34940d63 --- /dev/null +++ b/tests/hana/test_simulation_inc_4_test.v @@ -0,0 +1,5 @@ +module test(input [3:0] in, output [3:0] out); + +assign out = -in; + +endmodule diff --git a/tests/hana/test_simulation_inc_8_test.v b/tests/hana/test_simulation_inc_8_test.v new file mode 100644 index 00000000..c36d69f0 --- /dev/null +++ b/tests/hana/test_simulation_inc_8_test.v @@ -0,0 +1,5 @@ +module test(input [7:0] in, output [7:0] out); + +assign out = -in; + +endmodule diff --git a/tests/hana/test_simulation_mod_1_xx.v b/tests/hana/test_simulation_mod_1_xx.v new file mode 100644 index 00000000..75144a8e --- /dev/null +++ b/tests/hana/test_simulation_mod_1_xx.v @@ -0,0 +1,13 @@ +module test(in1, in2, out); +input in1; +input in2; +output out; + +wire synth_net_0; +wire synth_net_1; +BUF synth_BUF_0(.in(synth_net_1), .out(out + )); +DIV1 synth_DIV(.in1(in1), .in2(in2), .rem(synth_net_0), .out(synth_net_1 + )); +endmodule + diff --git a/tests/hana/test_simulation_mux_16_test.v b/tests/hana/test_simulation_mux_16_test.v new file mode 100644 index 00000000..de4b6f8e --- /dev/null +++ b/tests/hana/test_simulation_mux_16_test.v @@ -0,0 +1,22 @@ +module test(input [15:0] in, input [3:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + 8: out = in[8]; + 9: out = in[9]; + 10: out = in[10]; + 11: out = in[11]; + 12: out = in[12]; + 13: out = in[13]; + 14: out = in[14]; + 15: out = in[15]; + endcase +endmodule diff --git a/tests/hana/test_simulation_mux_2_test.v b/tests/hana/test_simulation_mux_2_test.v new file mode 100644 index 00000000..bc676c70 --- /dev/null +++ b/tests/hana/test_simulation_mux_2_test.v @@ -0,0 +1,8 @@ +module test(input [1:0] in, input select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + endcase +endmodule diff --git a/tests/hana/test_simulation_mux_32_test.v b/tests/hana/test_simulation_mux_32_test.v new file mode 100644 index 00000000..16de4d7f --- /dev/null +++ b/tests/hana/test_simulation_mux_32_test.v @@ -0,0 +1,39 @@ +module test(input [31:0] in, input [4:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + 8: out = in[8]; + 9: out = in[9]; + 10: out = in[10]; + 11: out = in[11]; + 12: out = in[12]; + 13: out = in[13]; + 14: out = in[14]; + 15: out = in[15]; + 16: out = in[16]; + 17: out = in[17]; + 18: out = in[18]; + 19: out = in[19]; + 20: out = in[20]; + 21: out = in[21]; + 22: out = in[22]; + 23: out = in[23]; + 24: out = in[24]; + 25: out = in[25]; + 26: out = in[26]; + 27: out = in[27]; + 28: out = in[28]; + 29: out = in[29]; + 30: out = in[30]; + 31: out = in[31]; + endcase +endmodule + diff --git a/tests/hana/test_simulation_mux_4_test.v b/tests/hana/test_simulation_mux_4_test.v new file mode 100644 index 00000000..6a112c6a --- /dev/null +++ b/tests/hana/test_simulation_mux_4_test.v @@ -0,0 +1,10 @@ +module test(input [3:0] in, input [1:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + endcase +endmodule diff --git a/tests/hana/test_simulation_mux_64_test.v b/tests/hana/test_simulation_mux_64_test.v new file mode 100644 index 00000000..420239c6 --- /dev/null +++ b/tests/hana/test_simulation_mux_64_test.v @@ -0,0 +1,71 @@ +module test(input [63:0] in, input [5:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + 8: out = in[8]; + 9: out = in[9]; + 10: out = in[10]; + 11: out = in[11]; + 12: out = in[12]; + 13: out = in[13]; + 14: out = in[14]; + 15: out = in[15]; + 16: out = in[16]; + 17: out = in[17]; + 18: out = in[18]; + 19: out = in[19]; + 20: out = in[20]; + 21: out = in[21]; + 22: out = in[22]; + 23: out = in[23]; + 24: out = in[24]; + 25: out = in[25]; + 26: out = in[26]; + 27: out = in[27]; + 28: out = in[28]; + 29: out = in[29]; + 30: out = in[30]; + 31: out = in[31]; + 32: out = in[32]; + 33: out = in[33]; + 34: out = in[34]; + 35: out = in[35]; + 36: out = in[36]; + 37: out = in[37]; + 38: out = in[38]; + 39: out = in[39]; + 40: out = in[40]; + 41: out = in[41]; + 42: out = in[42]; + 43: out = in[43]; + 44: out = in[44]; + 45: out = in[45]; + 46: out = in[46]; + 47: out = in[47]; + 48: out = in[48]; + 49: out = in[49]; + 50: out = in[50]; + 51: out = in[51]; + 52: out = in[52]; + 53: out = in[53]; + 54: out = in[54]; + 55: out = in[55]; + 56: out = in[56]; + 57: out = in[57]; + 58: out = in[58]; + 59: out = in[59]; + 60: out = in[60]; + 61: out = in[61]; + 62: out = in[62]; + 63: out = in[63]; + endcase +endmodule + diff --git a/tests/hana/test_simulation_mux_8_test.v b/tests/hana/test_simulation_mux_8_test.v new file mode 100644 index 00000000..f53a2c57 --- /dev/null +++ b/tests/hana/test_simulation_mux_8_test.v @@ -0,0 +1,14 @@ +module test(input [7:0] in, input [2:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + endcase +endmodule diff --git a/tests/hana/test_simulation_nand_1_test.v b/tests/hana/test_simulation_nand_1_test.v new file mode 100644 index 00000000..d8f34ee1 --- /dev/null +++ b/tests/hana/test_simulation_nand_1_test.v @@ -0,0 +1,3 @@ +module test(input [1:0] in, output out); +assign out = ~(in[0] & in[1]); +endmodule diff --git a/tests/hana/test_simulation_nand_3_test.v b/tests/hana/test_simulation_nand_3_test.v new file mode 100644 index 00000000..8926cebb --- /dev/null +++ b/tests/hana/test_simulation_nand_3_test.v @@ -0,0 +1,3 @@ +module test(input [2:0] in, output out); +assign out = !(in[0] & in[1] & in[2]); +endmodule diff --git a/tests/hana/test_simulation_nand_4_test.v b/tests/hana/test_simulation_nand_4_test.v new file mode 100644 index 00000000..703a2de4 --- /dev/null +++ b/tests/hana/test_simulation_nand_4_test.v @@ -0,0 +1,3 @@ +module test(input [2:0] in, output out); +assign out = ~(in[0] && in[1] && in[2]); +endmodule diff --git a/tests/hana/test_simulation_nand_5_test.v b/tests/hana/test_simulation_nand_5_test.v new file mode 100644 index 00000000..adef3c90 --- /dev/null +++ b/tests/hana/test_simulation_nand_5_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +assign out = !(in[0] & in[1] & in[2] & in[3]); +endmodule diff --git a/tests/hana/test_simulation_nand_6_test.v b/tests/hana/test_simulation_nand_6_test.v new file mode 100644 index 00000000..a2136f21 --- /dev/null +++ b/tests/hana/test_simulation_nand_6_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +assign out = !(in[0] && in[1] && in[2] && in[3]); +endmodule diff --git a/tests/hana/test_simulation_nor_1_test.v b/tests/hana/test_simulation_nor_1_test.v new file mode 100644 index 00000000..df4e8bfa --- /dev/null +++ b/tests/hana/test_simulation_nor_1_test.v @@ -0,0 +1,3 @@ +module test(input [1:0] in, output out); +assign out = ~(in[0] | in[1]); +endmodule diff --git a/tests/hana/test_simulation_nor_2_test.v b/tests/hana/test_simulation_nor_2_test.v new file mode 100644 index 00000000..2cfffc45 --- /dev/null +++ b/tests/hana/test_simulation_nor_2_test.v @@ -0,0 +1,3 @@ +module test(input [2:0] in, output out); +assign out = ~(in[0] | in[1] | in[2]); +endmodule diff --git a/tests/hana/test_simulation_nor_3_test.v b/tests/hana/test_simulation_nor_3_test.v new file mode 100644 index 00000000..9f1ef8fe --- /dev/null +++ b/tests/hana/test_simulation_nor_3_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +assign out = ~(in[0] | in[1] | in[2] | in[3]); +endmodule diff --git a/tests/hana/test_simulation_nor_4_test.v b/tests/hana/test_simulation_nor_4_test.v new file mode 100644 index 00000000..d8e68504 --- /dev/null +++ b/tests/hana/test_simulation_nor_4_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +nor mynor(out, in[0], in[1], in[2], in[3]); +endmodule diff --git a/tests/hana/test_simulation_opt_constprop_contassign_1_test.v b/tests/hana/test_simulation_opt_constprop_contassign_1_test.v new file mode 100644 index 00000000..a39b58b4 --- /dev/null +++ b/tests/hana/test_simulation_opt_constprop_contassign_1_test.v @@ -0,0 +1,3 @@ +module test(input in, output out); +assign out = 1'b1; +endmodule diff --git a/tests/hana/test_simulation_or_1_test.v b/tests/hana/test_simulation_or_1_test.v new file mode 100644 index 00000000..bdfffd3d --- /dev/null +++ b/tests/hana/test_simulation_or_1_test.v @@ -0,0 +1,3 @@ +module test(input [1:0] in, output out); +assign out = in[0] | in[1]; +endmodule diff --git a/tests/hana/test_simulation_or_2_test.v b/tests/hana/test_simulation_or_2_test.v new file mode 100644 index 00000000..291c8c76 --- /dev/null +++ b/tests/hana/test_simulation_or_2_test.v @@ -0,0 +1,3 @@ +module test(input [1:0] in, output out); +assign out = in[0] || in[1]; +endmodule diff --git a/tests/hana/test_simulation_or_3_test.v b/tests/hana/test_simulation_or_3_test.v new file mode 100644 index 00000000..ad00c708 --- /dev/null +++ b/tests/hana/test_simulation_or_3_test.v @@ -0,0 +1,3 @@ +module test(input [2:0] in, output out); +assign out = in[0] | in[1] | in[2]; +endmodule diff --git a/tests/hana/test_simulation_or_4_test.v b/tests/hana/test_simulation_or_4_test.v new file mode 100644 index 00000000..2ec57fa9 --- /dev/null +++ b/tests/hana/test_simulation_or_4_test.v @@ -0,0 +1,3 @@ +module test(input [2:0] in, output out); +assign out = in[0] || in[1] || in[2]; +endmodule diff --git a/tests/hana/test_simulation_or_5_test.v b/tests/hana/test_simulation_or_5_test.v new file mode 100644 index 00000000..f6a2d14d --- /dev/null +++ b/tests/hana/test_simulation_or_5_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +assign out = in[0] | in[1] | in[2] | in[3]; +endmodule diff --git a/tests/hana/test_simulation_or_6_test.v b/tests/hana/test_simulation_or_6_test.v new file mode 100644 index 00000000..ecd85c36 --- /dev/null +++ b/tests/hana/test_simulation_or_6_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +assign out = in[0] || in[1] || in[2] || in[3]; +endmodule diff --git a/tests/hana/test_simulation_seq_ff_1_test.v b/tests/hana/test_simulation_seq_ff_1_test.v new file mode 100644 index 00000000..5aac49c0 --- /dev/null +++ b/tests/hana/test_simulation_seq_ff_1_test.v @@ -0,0 +1,4 @@ +module test(input in, input clk, output reg out); +always @(posedge clk) + out <= in; +endmodule diff --git a/tests/hana/test_simulation_seq_ff_2_test.v b/tests/hana/test_simulation_seq_ff_2_test.v new file mode 100644 index 00000000..f1d2b7b4 --- /dev/null +++ b/tests/hana/test_simulation_seq_ff_2_test.v @@ -0,0 +1,4 @@ +module test(input in, input clk, output reg out); +always @(negedge clk) + out <= in; +endmodule diff --git a/tests/hana/test_simulation_shifter_left_16_test.v b/tests/hana/test_simulation_shifter_left_16_test.v new file mode 100644 index 00000000..a57dac49 --- /dev/null +++ b/tests/hana/test_simulation_shifter_left_16_test.v @@ -0,0 +1,4 @@ +module test(input [15:0] IN, input [4:0] SHIFT, output [15:0] OUT); + +assign OUT = IN << SHIFT; +endmodule diff --git a/tests/hana/test_simulation_shifter_left_32_test.v b/tests/hana/test_simulation_shifter_left_32_test.v new file mode 100644 index 00000000..672938ac --- /dev/null +++ b/tests/hana/test_simulation_shifter_left_32_test.v @@ -0,0 +1,4 @@ +module test(input [31:0] IN, input [5:0] SHIFT, output [31:0] OUT); + +assign OUT = IN << SHIFT; +endmodule diff --git a/tests/hana/test_simulation_shifter_left_4_test.v b/tests/hana/test_simulation_shifter_left_4_test.v new file mode 100644 index 00000000..c525401f --- /dev/null +++ b/tests/hana/test_simulation_shifter_left_4_test.v @@ -0,0 +1,4 @@ +module test(input [3:0] IN, input [2:0] SHIFT, output [3:0] OUT); + +assign OUT = IN << SHIFT; +endmodule diff --git a/tests/hana/test_simulation_shifter_left_64_test.v b/tests/hana/test_simulation_shifter_left_64_test.v new file mode 100644 index 00000000..276a7c5a --- /dev/null +++ b/tests/hana/test_simulation_shifter_left_64_test.v @@ -0,0 +1,4 @@ +module test(input [63:0] IN, input [6:0] SHIFT, output [63:0] OUT); + +assign OUT = IN << SHIFT; +endmodule diff --git a/tests/hana/test_simulation_shifter_left_8_test.v b/tests/hana/test_simulation_shifter_left_8_test.v new file mode 100644 index 00000000..c1727700 --- /dev/null +++ b/tests/hana/test_simulation_shifter_left_8_test.v @@ -0,0 +1,4 @@ +module test(input [7:0] IN, input [3:0] SHIFT, output [7:0] OUT); + +assign OUT = IN << SHIFT; +endmodule diff --git a/tests/hana/test_simulation_shifter_right_16_test.v b/tests/hana/test_simulation_shifter_right_16_test.v new file mode 100644 index 00000000..6152adc0 --- /dev/null +++ b/tests/hana/test_simulation_shifter_right_16_test.v @@ -0,0 +1,4 @@ +module test(input [15:0] IN, input [4:0] SHIFT, output [15:0] OUT); + +assign OUT = IN >> SHIFT; +endmodule diff --git a/tests/hana/test_simulation_shifter_right_32_test.v b/tests/hana/test_simulation_shifter_right_32_test.v new file mode 100644 index 00000000..e910cdd6 --- /dev/null +++ b/tests/hana/test_simulation_shifter_right_32_test.v @@ -0,0 +1,4 @@ +module test(input [31:0] IN, input [5:0] SHIFT, output [31:0] OUT); + +assign OUT = IN >> SHIFT; +endmodule diff --git a/tests/hana/test_simulation_shifter_right_4_test.v b/tests/hana/test_simulation_shifter_right_4_test.v new file mode 100644 index 00000000..608c196d --- /dev/null +++ b/tests/hana/test_simulation_shifter_right_4_test.v @@ -0,0 +1,4 @@ +module test(input [3:0] IN, input [2:0] SHIFT, output [3:0] OUT); + +assign OUT = IN >> SHIFT; +endmodule diff --git a/tests/hana/test_simulation_shifter_right_64_test.v b/tests/hana/test_simulation_shifter_right_64_test.v new file mode 100644 index 00000000..c26d5938 --- /dev/null +++ b/tests/hana/test_simulation_shifter_right_64_test.v @@ -0,0 +1,4 @@ +module test(input [63:0] IN, input [6:0] SHIFT, output [63:0] OUT); + +assign OUT = IN >> SHIFT; +endmodule diff --git a/tests/hana/test_simulation_shifter_right_8_test.v b/tests/hana/test_simulation_shifter_right_8_test.v new file mode 100644 index 00000000..a91c594e --- /dev/null +++ b/tests/hana/test_simulation_shifter_right_8_test.v @@ -0,0 +1,4 @@ +module test(input [7:0] IN, input [3:0] SHIFT, output [7:0] OUT); + +assign OUT = IN >> SHIFT; +endmodule diff --git a/tests/hana/test_simulation_sop_basic_10_test.v b/tests/hana/test_simulation_sop_basic_10_test.v new file mode 100644 index 00000000..bc676c70 --- /dev/null +++ b/tests/hana/test_simulation_sop_basic_10_test.v @@ -0,0 +1,8 @@ +module test(input [1:0] in, input select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + endcase +endmodule diff --git a/tests/hana/test_simulation_sop_basic_11_test.v b/tests/hana/test_simulation_sop_basic_11_test.v new file mode 100644 index 00000000..6a112c6a --- /dev/null +++ b/tests/hana/test_simulation_sop_basic_11_test.v @@ -0,0 +1,10 @@ +module test(input [3:0] in, input [1:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + endcase +endmodule diff --git a/tests/hana/test_simulation_sop_basic_12_test.v b/tests/hana/test_simulation_sop_basic_12_test.v new file mode 100644 index 00000000..f53a2c57 --- /dev/null +++ b/tests/hana/test_simulation_sop_basic_12_test.v @@ -0,0 +1,14 @@ +module test(input [7:0] in, input [2:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + endcase +endmodule diff --git a/tests/hana/test_simulation_sop_basic_18_test.v b/tests/hana/test_simulation_sop_basic_18_test.v new file mode 100644 index 00000000..03fc35b3 --- /dev/null +++ b/tests/hana/test_simulation_sop_basic_18_test.v @@ -0,0 +1,5 @@ +module test(input [7:0] in, output out); + +assign out = ~^in; + +endmodule diff --git a/tests/hana/test_simulation_sop_basic_3_test.v b/tests/hana/test_simulation_sop_basic_3_test.v new file mode 100644 index 00000000..81759c25 --- /dev/null +++ b/tests/hana/test_simulation_sop_basic_3_test.v @@ -0,0 +1,3 @@ +module test(input in, output out); +assign out = ~in; +endmodule diff --git a/tests/hana/test_simulation_sop_basic_7_test.v b/tests/hana/test_simulation_sop_basic_7_test.v new file mode 100644 index 00000000..e9bb7f61 --- /dev/null +++ b/tests/hana/test_simulation_sop_basic_7_test.v @@ -0,0 +1,3 @@ +module test(input in, output out); +assign out = in; +endmodule diff --git a/tests/hana/test_simulation_sop_basic_8_test.v b/tests/hana/test_simulation_sop_basic_8_test.v new file mode 100644 index 00000000..a51ead0b --- /dev/null +++ b/tests/hana/test_simulation_sop_basic_8_test.v @@ -0,0 +1,3 @@ +module test(output out); +assign out = 1'b0; +endmodule diff --git a/tests/hana/test_simulation_sop_basic_9_test.v b/tests/hana/test_simulation_sop_basic_9_test.v new file mode 100644 index 00000000..81759c25 --- /dev/null +++ b/tests/hana/test_simulation_sop_basic_9_test.v @@ -0,0 +1,3 @@ +module test(input in, output out); +assign out = ~in; +endmodule diff --git a/tests/hana/test_simulation_techmap_and_19_tech.v b/tests/hana/test_simulation_techmap_and_19_tech.v new file mode 100644 index 00000000..2491087c --- /dev/null +++ b/tests/hana/test_simulation_techmap_and_19_tech.v @@ -0,0 +1,7 @@ +module TECH_AND18(input [17:0] in, output out); +assign out = ∈ +endmodule + +module TECH_AND4(input [3:0] in, output out); +assign out = ∈ +endmodule diff --git a/tests/hana/test_simulation_techmap_and_5_tech.v b/tests/hana/test_simulation_techmap_and_5_tech.v new file mode 100644 index 00000000..6ec6a61c --- /dev/null +++ b/tests/hana/test_simulation_techmap_and_5_tech.v @@ -0,0 +1,3 @@ +module TECH_AND5(input [4:0] in, output out); +assign out = ∈ +endmodule diff --git a/tests/hana/test_simulation_techmap_buf_test.v b/tests/hana/test_simulation_techmap_buf_test.v new file mode 100644 index 00000000..e9bb7f61 --- /dev/null +++ b/tests/hana/test_simulation_techmap_buf_test.v @@ -0,0 +1,3 @@ +module test(input in, output out); +assign out = in; +endmodule diff --git a/tests/hana/test_simulation_techmap_inv_test.v b/tests/hana/test_simulation_techmap_inv_test.v new file mode 100644 index 00000000..81759c25 --- /dev/null +++ b/tests/hana/test_simulation_techmap_inv_test.v @@ -0,0 +1,3 @@ +module test(input in, output out); +assign out = ~in; +endmodule diff --git a/tests/hana/test_simulation_techmap_mux_0_test.v b/tests/hana/test_simulation_techmap_mux_0_test.v new file mode 100644 index 00000000..bc676c70 --- /dev/null +++ b/tests/hana/test_simulation_techmap_mux_0_test.v @@ -0,0 +1,8 @@ +module test(input [1:0] in, input select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + endcase +endmodule diff --git a/tests/hana/test_simulation_techmap_mux_128_test.v b/tests/hana/test_simulation_techmap_mux_128_test.v new file mode 100644 index 00000000..544c016a --- /dev/null +++ b/tests/hana/test_simulation_techmap_mux_128_test.v @@ -0,0 +1,134 @@ +module test(input [127:0] in, input [6:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + 8: out = in[8]; + 9: out = in[9]; + 10: out = in[10]; + 11: out = in[11]; + 12: out = in[12]; + 13: out = in[13]; + 14: out = in[14]; + 15: out = in[15]; + 16: out = in[16]; + 17: out = in[17]; + 18: out = in[18]; + 19: out = in[19]; + 20: out = in[20]; + 21: out = in[21]; + 22: out = in[22]; + 23: out = in[23]; + 24: out = in[24]; + 25: out = in[25]; + 26: out = in[26]; + 27: out = in[27]; + 28: out = in[28]; + 29: out = in[29]; + 30: out = in[30]; + 31: out = in[31]; + 32: out = in[32]; + 33: out = in[33]; + 34: out = in[34]; + 35: out = in[35]; + 36: out = in[36]; + 37: out = in[37]; + 38: out = in[38]; + 39: out = in[39]; + 40: out = in[40]; + 41: out = in[41]; + 42: out = in[42]; + 43: out = in[43]; + 44: out = in[44]; + 45: out = in[45]; + 46: out = in[46]; + 47: out = in[47]; + 48: out = in[48]; + 49: out = in[49]; + 50: out = in[50]; + 51: out = in[51]; + 52: out = in[52]; + 53: out = in[53]; + 54: out = in[54]; + 55: out = in[55]; + 56: out = in[56]; + 57: out = in[57]; + 58: out = in[58]; + 59: out = in[59]; + 60: out = in[60]; + 61: out = in[61]; + 62: out = in[62]; + 63: out = in[63]; + 64: out = in[64]; + 65: out = in[65]; + 66: out = in[66]; + 67: out = in[67]; + 68: out = in[68]; + 69: out = in[69]; + 70: out = in[70]; + 71: out = in[71]; + 72: out = in[72]; + 73: out = in[73]; + 74: out = in[74]; + 75: out = in[75]; + 76: out = in[76]; + 77: out = in[77]; + 78: out = in[78]; + 79: out = in[79]; + 80: out = in[80]; + 81: out = in[81]; + 82: out = in[82]; + 83: out = in[83]; + 84: out = in[84]; + 85: out = in[85]; + 86: out = in[86]; + 87: out = in[87]; + 88: out = in[88]; + 89: out = in[89]; + 90: out = in[90]; + 91: out = in[91]; + 92: out = in[92]; + 93: out = in[93]; + 94: out = in[94]; + 95: out = in[95]; + 96: out = in[96]; + 97: out = in[97]; + 98: out = in[98]; + 99: out = in[99]; + 100: out = in[100]; + 101: out = in[101]; + 102: out = in[102]; + 103: out = in[103]; + 104: out = in[104]; + 105: out = in[105]; + 106: out = in[106]; + 107: out = in[107]; + 108: out = in[108]; + 109: out = in[109]; + 110: out = in[110]; + 111: out = in[111]; + 112: out = in[112]; + 113: out = in[113]; + 114: out = in[114]; + 115: out = in[115]; + 116: out = in[116]; + 117: out = in[117]; + 118: out = in[118]; + 119: out = in[119]; + 120: out = in[120]; + 121: out = in[121]; + 122: out = in[122]; + 123: out = in[123]; + 124: out = in[124]; + 125: out = in[125]; + 126: out = in[126]; + 127: out = in[127]; + endcase +endmodule diff --git a/tests/hana/test_simulation_techmap_mux_8_test.v b/tests/hana/test_simulation_techmap_mux_8_test.v new file mode 100644 index 00000000..f53a2c57 --- /dev/null +++ b/tests/hana/test_simulation_techmap_mux_8_test.v @@ -0,0 +1,14 @@ +module test(input [7:0] in, input [2:0] select, output reg out); + +always @( in or select) + case (select) + 0: out = in[0]; + 1: out = in[1]; + 2: out = in[2]; + 3: out = in[3]; + 4: out = in[4]; + 5: out = in[5]; + 6: out = in[6]; + 7: out = in[7]; + endcase +endmodule diff --git a/tests/hana/test_simulation_techmap_nand_19_tech.v b/tests/hana/test_simulation_techmap_nand_19_tech.v new file mode 100644 index 00000000..6a119e1e --- /dev/null +++ b/tests/hana/test_simulation_techmap_nand_19_tech.v @@ -0,0 +1,11 @@ +module TECH_NAND18(input [17:0] in, output out); +assign out = ~(&in); +endmodule + +module TECH_NAND4(input [3:0] in, output out); +assign out = ~(&in); +endmodule + +module TECH_NAND2(input [1:0] in, output out); +assign out = ~(&in); +endmodule diff --git a/tests/hana/test_simulation_techmap_nand_2_tech.v b/tests/hana/test_simulation_techmap_nand_2_tech.v new file mode 100644 index 00000000..6a119e1e --- /dev/null +++ b/tests/hana/test_simulation_techmap_nand_2_tech.v @@ -0,0 +1,11 @@ +module TECH_NAND18(input [17:0] in, output out); +assign out = ~(&in); +endmodule + +module TECH_NAND4(input [3:0] in, output out); +assign out = ~(&in); +endmodule + +module TECH_NAND2(input [1:0] in, output out); +assign out = ~(&in); +endmodule diff --git a/tests/hana/test_simulation_techmap_nand_5_tech.v b/tests/hana/test_simulation_techmap_nand_5_tech.v new file mode 100644 index 00000000..6a119e1e --- /dev/null +++ b/tests/hana/test_simulation_techmap_nand_5_tech.v @@ -0,0 +1,11 @@ +module TECH_NAND18(input [17:0] in, output out); +assign out = ~(&in); +endmodule + +module TECH_NAND4(input [3:0] in, output out); +assign out = ~(&in); +endmodule + +module TECH_NAND2(input [1:0] in, output out); +assign out = ~(&in); +endmodule diff --git a/tests/hana/test_simulation_techmap_nor_19_tech.v b/tests/hana/test_simulation_techmap_nor_19_tech.v new file mode 100644 index 00000000..89fb2c7e --- /dev/null +++ b/tests/hana/test_simulation_techmap_nor_19_tech.v @@ -0,0 +1,11 @@ +module TECH_NOR18(input [17:0] in, output out); +assign out = ~(|in); +endmodule + +module TECH_NOR4(input [3:0] in, output out); +assign out = ~(|in); +endmodule + +module TECH_NOR2(input [1:0] in, output out); +assign out = ~(|in); +endmodule diff --git a/tests/hana/test_simulation_techmap_nor_2_tech.v b/tests/hana/test_simulation_techmap_nor_2_tech.v new file mode 100644 index 00000000..89fb2c7e --- /dev/null +++ b/tests/hana/test_simulation_techmap_nor_2_tech.v @@ -0,0 +1,11 @@ +module TECH_NOR18(input [17:0] in, output out); +assign out = ~(|in); +endmodule + +module TECH_NOR4(input [3:0] in, output out); +assign out = ~(|in); +endmodule + +module TECH_NOR2(input [1:0] in, output out); +assign out = ~(|in); +endmodule diff --git a/tests/hana/test_simulation_techmap_nor_5_tech.v b/tests/hana/test_simulation_techmap_nor_5_tech.v new file mode 100644 index 00000000..89fb2c7e --- /dev/null +++ b/tests/hana/test_simulation_techmap_nor_5_tech.v @@ -0,0 +1,11 @@ +module TECH_NOR18(input [17:0] in, output out); +assign out = ~(|in); +endmodule + +module TECH_NOR4(input [3:0] in, output out); +assign out = ~(|in); +endmodule + +module TECH_NOR2(input [1:0] in, output out); +assign out = ~(|in); +endmodule diff --git a/tests/hana/test_simulation_techmap_or_19_tech.v b/tests/hana/test_simulation_techmap_or_19_tech.v new file mode 100644 index 00000000..745d7b71 --- /dev/null +++ b/tests/hana/test_simulation_techmap_or_19_tech.v @@ -0,0 +1,7 @@ +module TECH_OR18(input [17:0] in, output out); +assign out = |in; +endmodule + +module TECH_OR4(input [3:0] in, output out); +assign out = |in; +endmodule diff --git a/tests/hana/test_simulation_techmap_or_5_tech.v b/tests/hana/test_simulation_techmap_or_5_tech.v new file mode 100644 index 00000000..05c38b67 --- /dev/null +++ b/tests/hana/test_simulation_techmap_or_5_tech.v @@ -0,0 +1,3 @@ +module TECH_OR5(input [4:0] in, output out); +assign out = |in; +endmodule diff --git a/tests/hana/test_simulation_techmap_xnor_2_tech.v b/tests/hana/test_simulation_techmap_xnor_2_tech.v new file mode 100644 index 00000000..4eb05683 --- /dev/null +++ b/tests/hana/test_simulation_techmap_xnor_2_tech.v @@ -0,0 +1,6 @@ +module TECH_XOR5(input [4:0] in, output out); +assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4]; +endmodule +module TECH_XOR2(input [1:0] in, output out); +assign out = in[0] ^ in[1]; +endmodule diff --git a/tests/hana/test_simulation_techmap_xnor_5_tech.v b/tests/hana/test_simulation_techmap_xnor_5_tech.v new file mode 100644 index 00000000..4eb05683 --- /dev/null +++ b/tests/hana/test_simulation_techmap_xnor_5_tech.v @@ -0,0 +1,6 @@ +module TECH_XOR5(input [4:0] in, output out); +assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4]; +endmodule +module TECH_XOR2(input [1:0] in, output out); +assign out = in[0] ^ in[1]; +endmodule diff --git a/tests/hana/test_simulation_techmap_xor_19_tech.v b/tests/hana/test_simulation_techmap_xor_19_tech.v new file mode 100644 index 00000000..2042a0ad --- /dev/null +++ b/tests/hana/test_simulation_techmap_xor_19_tech.v @@ -0,0 +1,3 @@ +module TECH_XOR2(input [1:0] in, output out); +assign out = in[0] ^ in[1]; +endmodule diff --git a/tests/hana/test_simulation_techmap_xor_2_tech.v b/tests/hana/test_simulation_techmap_xor_2_tech.v new file mode 100644 index 00000000..4eb05683 --- /dev/null +++ b/tests/hana/test_simulation_techmap_xor_2_tech.v @@ -0,0 +1,6 @@ +module TECH_XOR5(input [4:0] in, output out); +assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4]; +endmodule +module TECH_XOR2(input [1:0] in, output out); +assign out = in[0] ^ in[1]; +endmodule diff --git a/tests/hana/test_simulation_techmap_xor_5_tech.v b/tests/hana/test_simulation_techmap_xor_5_tech.v new file mode 100644 index 00000000..4eb05683 --- /dev/null +++ b/tests/hana/test_simulation_techmap_xor_5_tech.v @@ -0,0 +1,6 @@ +module TECH_XOR5(input [4:0] in, output out); +assign out = in[0] ^ in[1] ^ in[2] ^ in[3] ^ in[4]; +endmodule +module TECH_XOR2(input [1:0] in, output out); +assign out = in[0] ^ in[1]; +endmodule diff --git a/tests/hana/test_simulation_tribuf_2_test.v b/tests/hana/test_simulation_tribuf_2_test.v new file mode 100644 index 00000000..1e82aaf0 --- /dev/null +++ b/tests/hana/test_simulation_tribuf_2_test.v @@ -0,0 +1,3 @@ +module test(input [1:0] in, input enable, output [1:0] out); +assign out = enable ? in : 2'bzz; +endmodule diff --git a/tests/hana/test_simulation_xnor_1_test.v b/tests/hana/test_simulation_xnor_1_test.v new file mode 100644 index 00000000..adc6ae5c --- /dev/null +++ b/tests/hana/test_simulation_xnor_1_test.v @@ -0,0 +1,3 @@ +module test(input [1:0] in, output out); +assign out = ~(in[0] ^ in[1]); +endmodule diff --git a/tests/hana/test_simulation_xnor_2_test.v b/tests/hana/test_simulation_xnor_2_test.v new file mode 100644 index 00000000..701bcc77 --- /dev/null +++ b/tests/hana/test_simulation_xnor_2_test.v @@ -0,0 +1,3 @@ +module test(input [2:0] in, output out); +assign out = ~(in[0] ^ in[1] ^ in[2]); +endmodule diff --git a/tests/hana/test_simulation_xnor_3_test.v b/tests/hana/test_simulation_xnor_3_test.v new file mode 100644 index 00000000..a8c87cc6 --- /dev/null +++ b/tests/hana/test_simulation_xnor_3_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +assign out = ~(in[0] ^ in[1] ^ in[2] ^ in[3]); +endmodule diff --git a/tests/hana/test_simulation_xnor_4_test.v b/tests/hana/test_simulation_xnor_4_test.v new file mode 100644 index 00000000..fa671ff9 --- /dev/null +++ b/tests/hana/test_simulation_xnor_4_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +xnor myxnor(out, in[0], in[1], in[2], in[3]); +endmodule diff --git a/tests/hana/test_simulation_xor_1_test.v b/tests/hana/test_simulation_xor_1_test.v new file mode 100644 index 00000000..f6447f81 --- /dev/null +++ b/tests/hana/test_simulation_xor_1_test.v @@ -0,0 +1,3 @@ +module test(input [1:0] in, output out); +assign out = (in[0] ^ in[1]); +endmodule diff --git a/tests/hana/test_simulation_xor_2_test.v b/tests/hana/test_simulation_xor_2_test.v new file mode 100644 index 00000000..d94081df --- /dev/null +++ b/tests/hana/test_simulation_xor_2_test.v @@ -0,0 +1,3 @@ +module test(input [2:0] in, output out); +assign out = (in[0] ^ in[1] ^ in[2]); +endmodule diff --git a/tests/hana/test_simulation_xor_3_test.v b/tests/hana/test_simulation_xor_3_test.v new file mode 100644 index 00000000..cfa13187 --- /dev/null +++ b/tests/hana/test_simulation_xor_3_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +assign out = (in[0] ^ in[1] ^ in[2] ^ in[3]); +endmodule diff --git a/tests/hana/test_simulation_xor_4_test.v b/tests/hana/test_simulation_xor_4_test.v new file mode 100644 index 00000000..be6cab63 --- /dev/null +++ b/tests/hana/test_simulation_xor_4_test.v @@ -0,0 +1,3 @@ +module test(input [3:0] in, output out); +xor myxor(out, in[0], in[1], in[2], in[3]); +endmodule diff --git a/tests/i2c_bench/i2c_master_bit_ctrl.v b/tests/i2c_bench/i2c_master_bit_ctrl.v new file mode 100644 index 00000000..6594fd60 --- /dev/null +++ b/tests/i2c_bench/i2c_master_bit_ctrl.v @@ -0,0 +1,576 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE rev.B2 compliant I2C Master bit-controller //// +//// //// +//// //// +//// Author: Richard Herveille //// +//// richard@asics.ws //// +//// www.asics.ws //// +//// //// +//// Downloaded from: http://www.opencores.org/projects/i2c/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: i2c_master_bit_ctrl.v,v 1.14 2009-01-20 10:25:29 rherveille Exp $ +// +// $Date: 2009-01-20 10:25:29 $ +// $Revision: 1.14 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: $ +// Revision 1.14 2009/01/20 10:25:29 rherveille +// Added clock synchronization logic +// Fixed slave_wait signal +// +// Revision 1.13 2009/01/19 20:29:26 rherveille +// Fixed synopsys miss spell (synopsis) +// Fixed cr[0] register width +// Fixed ! usage instead of ~ +// Fixed bit controller parameter width to 18bits +// +// Revision 1.12 2006/09/04 09:08:13 rherveille +// fixed short scl high pulse after clock stretch +// fixed slave model not returning correct '(n)ack' signal +// +// Revision 1.11 2004/05/07 11:02:26 rherveille +// Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit. +// +// Revision 1.10 2003/08/09 07:01:33 rherveille +// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line. +// Fixed a potential bug in the byte controller's host-acknowledge generation. +// +// Revision 1.9 2003/03/10 14:26:37 rherveille +// Fixed cmd_ack generation item (no bug). +// +// Revision 1.8 2003/02/05 00:06:10 rherveille +// Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles. +// +// Revision 1.7 2002/12/26 16:05:12 rherveille +// Small code simplifications +// +// Revision 1.6 2002/12/26 15:02:32 rherveille +// Core is now a Multimaster I2C controller +// +// Revision 1.5 2002/11/30 22:24:40 rherveille +// Cleaned up code +// +// Revision 1.4 2002/10/30 18:10:07 rherveille +// Fixed some reported minor start/stop generation timing issuess. +// +// Revision 1.3 2002/06/15 07:37:03 rherveille +// Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment. +// +// Revision 1.2 2001/11/05 11:59:25 rherveille +// Fixed wb_ack_o generation bug. +// Fixed bug in the byte_controller statemachine. +// Added headers. +// + +// +///////////////////////////////////// +// Bit controller section +///////////////////////////////////// +// +// Translate simple commands into SCL/SDA transitions +// Each command has 5 states, A/B/C/D/idle +// +// start: SCL ~~~~~~~~~~\____ +// SDA ~~~~~~~~\______ +// x | A | B | C | D | i +// +// repstart SCL ____/~~~~\___ +// SDA __/~~~\______ +// x | A | B | C | D | i +// +// stop SCL ____/~~~~~~~~ +// SDA ==\____/~~~~~ +// x | A | B | C | D | i +// +//- write SCL ____/~~~~\____ +// SDA ==X=========X= +// x | A | B | C | D | i +// +//- read SCL ____/~~~~\____ +// SDA XXXX=====XXXX +// x | A | B | C | D | i +// + +// Timing: Normal mode Fast mode +/////////////////////////////////////////////////////////////////////// +// Fscl 100KHz 400KHz +// Th_scl 4.0us 0.6us High period of SCL +// Tl_scl 4.7us 1.3us Low period of SCL +// Tsu:sta 4.7us 0.6us setup time for a repeated start condition +// Tsu:sto 4.0us 0.6us setup time for a stop conditon +// Tbuf 4.7us 1.3us Bus free time between a stop and start condition +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +`include "i2c_master_defines.v" + +module i2c_master_bit_ctrl ( + input clk, // system clock + input rst, // synchronous active high reset + input nReset, // asynchronous active low reset + input ena, // core enable signal + + input [15:0] clk_cnt, // clock prescale value + + input [ 3:0] cmd, // command (from byte controller) + output reg cmd_ack, // command complete acknowledge + output reg busy, // i2c bus busy + output reg al, // i2c bus arbitration lost + + input din, + output reg dout, + + input scl_i, // i2c clock line input + output scl_o, // i2c clock line output + output reg scl_oen, // i2c clock line output enable (active low) + input sda_i, // i2c data line input + output sda_o, // i2c data line output + output reg sda_oen // i2c data line output enable (active low) +); + + + // + // variable declarations + // + + reg [ 1:0] cSCL, cSDA; // capture SCL and SDA + reg [ 2:0] fSCL, fSDA; // SCL and SDA filter inputs + reg sSCL, sSDA; // filtered and synchronized SCL and SDA inputs + reg dSCL, dSDA; // delayed versions of sSCL and sSDA + reg dscl_oen; // delayed scl_oen + reg sda_chk; // check SDA output (Multi-master arbitration) + reg clk_en; // clock generation signals + reg slave_wait; // slave inserts wait states + reg [15:0] cnt; // clock divider counter (synthesis) + reg [13:0] filter_cnt; // clock divider for filter + + + // state machine variable + reg [17:0] c_state; // synopsys enum_state + + // + // module body + // + + // whenever the slave is not ready it can delay the cycle by pulling SCL low + // delay scl_oen + always @(posedge clk) + dscl_oen <= scl_oen; + + // slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low + // slave_wait remains asserted until the slave releases SCL + always @(posedge clk or negedge nReset) + if (!nReset) slave_wait <= 1'b0; + else slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) | (slave_wait & ~sSCL); + + // master drives SCL high, but another master pulls it low + // master start counting down its low cycle now (clock synchronization) + wire scl_sync = dSCL & ~sSCL & scl_oen; + + + // generate clk enable signal + always @(posedge clk or negedge nReset) + if (~nReset) + begin + cnt <= 16'h0; + clk_en <= 1'b1; + end + else if (rst || ~|cnt || !ena || scl_sync) + begin + cnt <= clk_cnt; + clk_en <= 1'b1; + end + else if (slave_wait) + begin + cnt <= cnt; + clk_en <= 1'b0; + end + else + begin + cnt <= cnt - 16'h1; + clk_en <= 1'b0; + end + + + // generate bus status controller + + // capture SDA and SCL + // reduce metastability risk + always @(posedge clk or negedge nReset) + if (!nReset) + begin + cSCL <= 2'b00; + cSDA <= 2'b00; + end + else if (rst) + begin + cSCL <= 2'b00; + cSDA <= 2'b00; + end + else + begin + cSCL <= {cSCL[0],scl_i}; + cSDA <= {cSDA[0],sda_i}; + end + + + // filter SCL and SDA signals; (attempt to) remove glitches + always @(posedge clk or negedge nReset) + if (!nReset ) filter_cnt <= 14'h0; + else if (rst || !ena ) filter_cnt <= 14'h0; + else if (~|filter_cnt) filter_cnt <= clk_cnt[15:2]; //16x I2C bus frequency + else filter_cnt <= filter_cnt -1; + + + always @(posedge clk or negedge nReset) + if (!nReset) + begin + fSCL <= 3'b111; + fSDA <= 3'b111; + end + else if (rst) + begin + fSCL <= 3'b111; + fSDA <= 3'b111; + end + else if (~|filter_cnt) + begin + fSCL <= {fSCL[1:0],cSCL[1]}; + fSDA <= {fSDA[1:0],cSDA[1]}; + end + + + // generate filtered SCL and SDA signals + always @(posedge clk or negedge nReset) + if (~nReset) + begin + sSCL <= 1'b1; + sSDA <= 1'b1; + + dSCL <= 1'b1; + dSDA <= 1'b1; + end + else if (rst) + begin + sSCL <= 1'b1; + sSDA <= 1'b1; + + dSCL <= 1'b1; + dSDA <= 1'b1; + end + else + begin + sSCL <= &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]); + sSDA <= &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]); + + dSCL <= sSCL; + dSDA <= sSDA; + end + + // detect start condition => detect falling edge on SDA while SCL is high + // detect stop condition => detect rising edge on SDA while SCL is high + reg sta_condition; + reg sto_condition; + always @(posedge clk or negedge nReset) + if (~nReset) + begin + sta_condition <= 1'b0; + sto_condition <= 1'b0; + end + else if (rst) + begin + sta_condition <= 1'b0; + sto_condition <= 1'b0; + end + else + begin + sta_condition <= ~sSDA & dSDA & sSCL; + sto_condition <= sSDA & ~dSDA & sSCL; + end + + + // generate i2c bus busy signal + always @(posedge clk or negedge nReset) + if (!nReset) busy <= 1'b0; + else if (rst ) busy <= 1'b0; + else busy <= (sta_condition | busy) & ~sto_condition; + + + // generate arbitration lost signal + // aribitration lost when: + // 1) master drives SDA high, but the i2c bus is low + // 2) stop detected while not requested + reg cmd_stop; + always @(posedge clk or negedge nReset) + if (~nReset) + cmd_stop <= 1'b0; + else if (rst) + cmd_stop <= 1'b0; + else if (clk_en) + cmd_stop <= cmd == `I2C_CMD_STOP; + + always @(posedge clk or negedge nReset) + if (~nReset) + al <= 1'b0; + else if (rst) + al <= 1'b0; + else + al <= (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop); + + + // generate dout signal (store SDA on rising edge of SCL) + always @(posedge clk) + if (sSCL & ~dSCL) dout <= sSDA; + + + // generate statemachine + + // nxt_state decoder + parameter [17:0] idle = 18'b0_0000_0000_0000_0000; + parameter [17:0] start_a = 18'b0_0000_0000_0000_0001; + parameter [17:0] start_b = 18'b0_0000_0000_0000_0010; + parameter [17:0] start_c = 18'b0_0000_0000_0000_0100; + parameter [17:0] start_d = 18'b0_0000_0000_0000_1000; + parameter [17:0] start_e = 18'b0_0000_0000_0001_0000; + parameter [17:0] stop_a = 18'b0_0000_0000_0010_0000; + parameter [17:0] stop_b = 18'b0_0000_0000_0100_0000; + parameter [17:0] stop_c = 18'b0_0000_0000_1000_0000; + parameter [17:0] stop_d = 18'b0_0000_0001_0000_0000; + parameter [17:0] rd_a = 18'b0_0000_0010_0000_0000; + parameter [17:0] rd_b = 18'b0_0000_0100_0000_0000; + parameter [17:0] rd_c = 18'b0_0000_1000_0000_0000; + parameter [17:0] rd_d = 18'b0_0001_0000_0000_0000; + parameter [17:0] wr_a = 18'b0_0010_0000_0000_0000; + parameter [17:0] wr_b = 18'b0_0100_0000_0000_0000; + parameter [17:0] wr_c = 18'b0_1000_0000_0000_0000; + parameter [17:0] wr_d = 18'b1_0000_0000_0000_0000; + + always @(posedge clk or negedge nReset) + if (!nReset) + begin + c_state <= idle; + cmd_ack <= 1'b0; + scl_oen <= 1'b1; + sda_oen <= 1'b1; + sda_chk <= 1'b0; + end + else if (rst | al) + begin + c_state <= idle; + cmd_ack <= 1'b0; + scl_oen <= 1'b1; + sda_oen <= 1'b1; + sda_chk <= 1'b0; + end + else + begin + cmd_ack <= 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle + + if (clk_en) + case (c_state) // synopsys full_case parallel_case + // idle state + idle: + begin + case (cmd) // synopsys full_case parallel_case + `I2C_CMD_START: c_state <= start_a; + `I2C_CMD_STOP: c_state <= stop_a; + `I2C_CMD_WRITE: c_state <= wr_a; + `I2C_CMD_READ: c_state <= rd_a; + default: c_state <= idle; + endcase + + scl_oen <= scl_oen; // keep SCL in same state + sda_oen <= sda_oen; // keep SDA in same state + sda_chk <= 1'b0; // don't check SDA output + end + + // start + start_a: + begin + c_state <= start_b; + scl_oen <= scl_oen; // keep SCL in same state + sda_oen <= 1'b1; // set SDA high + sda_chk <= 1'b0; // don't check SDA output + end + + start_b: + begin + c_state <= start_c; + scl_oen <= 1'b1; // set SCL high + sda_oen <= 1'b1; // keep SDA high + sda_chk <= 1'b0; // don't check SDA output + end + + start_c: + begin + c_state <= start_d; + scl_oen <= 1'b1; // keep SCL high + sda_oen <= 1'b0; // set SDA low + sda_chk <= 1'b0; // don't check SDA output + end + + start_d: + begin + c_state <= start_e; + scl_oen <= 1'b1; // keep SCL high + sda_oen <= 1'b0; // keep SDA low + sda_chk <= 1'b0; // don't check SDA output + end + + start_e: + begin + c_state <= idle; + cmd_ack <= 1'b1; + scl_oen <= 1'b0; // set SCL low + sda_oen <= 1'b0; // keep SDA low + sda_chk <= 1'b0; // don't check SDA output + end + + // stop + stop_a: + begin + c_state <= stop_b; + scl_oen <= 1'b0; // keep SCL low + sda_oen <= 1'b0; // set SDA low + sda_chk <= 1'b0; // don't check SDA output + end + + stop_b: + begin + c_state <= stop_c; + scl_oen <= 1'b1; // set SCL high + sda_oen <= 1'b0; // keep SDA low + sda_chk <= 1'b0; // don't check SDA output + end + + stop_c: + begin + c_state <= stop_d; + scl_oen <= 1'b1; // keep SCL high + sda_oen <= 1'b0; // keep SDA low + sda_chk <= 1'b0; // don't check SDA output + end + + stop_d: + begin + c_state <= idle; + cmd_ack <= 1'b1; + scl_oen <= 1'b1; // keep SCL high + sda_oen <= 1'b1; // set SDA high + sda_chk <= 1'b0; // don't check SDA output + end + + // read + rd_a: + begin + c_state <= rd_b; + scl_oen <= 1'b0; // keep SCL low + sda_oen <= 1'b1; // tri-state SDA + sda_chk <= 1'b0; // don't check SDA output + end + + rd_b: + begin + c_state <= rd_c; + scl_oen <= 1'b1; // set SCL high + sda_oen <= 1'b1; // keep SDA tri-stated + sda_chk <= 1'b0; // don't check SDA output + end + + rd_c: + begin + c_state <= rd_d; + scl_oen <= 1'b1; // keep SCL high + sda_oen <= 1'b1; // keep SDA tri-stated + sda_chk <= 1'b0; // don't check SDA output + end + + rd_d: + begin + c_state <= idle; + cmd_ack <= 1'b1; + scl_oen <= 1'b0; // set SCL low + sda_oen <= 1'b1; // keep SDA tri-stated + sda_chk <= 1'b0; // don't check SDA output + end + + // write + wr_a: + begin + c_state <= wr_b; + scl_oen <= 1'b0; // keep SCL low + sda_oen <= din; // set SDA + sda_chk <= 1'b0; // don't check SDA output (SCL low) + end + + wr_b: + begin + c_state <= wr_c; + scl_oen <= 1'b1; // set SCL high + sda_oen <= din; // keep SDA + sda_chk <= 1'b0; // don't check SDA output yet + // allow some time for SDA and SCL to settle + end + + wr_c: + begin + c_state <= wr_d; + scl_oen <= 1'b1; // keep SCL high + sda_oen <= din; + sda_chk <= 1'b1; // check SDA output + end + + wr_d: + begin + c_state <= idle; + cmd_ack <= 1'b1; + scl_oen <= 1'b0; // set SCL low + sda_oen <= din; + sda_chk <= 1'b0; // don't check SDA output (SCL low) + end + + endcase + end + + + // assign scl and sda output (always gnd) + assign scl_o = 1'b0; + assign sda_o = 1'b0; + +endmodule diff --git a/tests/i2c_bench/i2c_master_byte_ctrl.v b/tests/i2c_bench/i2c_master_byte_ctrl.v new file mode 100644 index 00000000..513953a8 --- /dev/null +++ b/tests/i2c_bench/i2c_master_byte_ctrl.v @@ -0,0 +1,344 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE rev.B2 compliant I2C Master byte-controller //// +//// //// +//// //// +//// Author: Richard Herveille //// +//// richard@asics.ws //// +//// www.asics.ws //// +//// //// +//// Downloaded from: http://www.opencores.org/projects/i2c/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: i2c_master_byte_ctrl.v,v 1.8 2009-01-19 20:29:26 rherveille Exp $ +// +// $Date: 2009-01-19 20:29:26 $ +// $Revision: 1.8 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: not supported by cvs2svn $ +// Revision 1.7 2004/02/18 11:40:46 rherveille +// Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command. +// +// Revision 1.6 2003/08/09 07:01:33 rherveille +// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line. +// Fixed a potential bug in the byte controller's host-acknowledge generation. +// +// Revision 1.5 2002/12/26 15:02:32 rherveille +// Core is now a Multimaster I2C controller +// +// Revision 1.4 2002/11/30 22:24:40 rherveille +// Cleaned up code +// +// Revision 1.3 2001/11/05 11:59:25 rherveille +// Fixed wb_ack_o generation bug. +// Fixed bug in the byte_controller statemachine. +// Added headers. +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +`include "i2c_master_defines.v" + +module i2c_master_byte_ctrl ( + clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, din, + cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen ); + + // + // inputs & outputs + // + input clk; // master clock + input rst; // synchronous active high reset + input nReset; // asynchronous active low reset + input ena; // core enable signal + + input [15:0] clk_cnt; // 4x SCL + + // control inputs + input start; + input stop; + input read; + input write; + input ack_in; + input [7:0] din; + + // status outputs + output cmd_ack; + reg cmd_ack; + output ack_out; + reg ack_out; + output i2c_busy; + output i2c_al; + output [7:0] dout; + + // I2C signals + input scl_i; + output scl_o; + output scl_oen; + input sda_i; + output sda_o; + output sda_oen; + + + // + // Variable declarations + // + + // statemachine + parameter [4:0] ST_IDLE = 5'b0_0000; + parameter [4:0] ST_START = 5'b0_0001; + parameter [4:0] ST_READ = 5'b0_0010; + parameter [4:0] ST_WRITE = 5'b0_0100; + parameter [4:0] ST_ACK = 5'b0_1000; + parameter [4:0] ST_STOP = 5'b1_0000; + + // signals for bit_controller + reg [3:0] core_cmd; + reg core_txd; + wire core_ack, core_rxd; + + // signals for shift register + reg [7:0] sr; //8bit shift register + reg shift, ld; + + // signals for state machine + wire go; + reg [2:0] dcnt; + wire cnt_done; + + // + // Module body + // + + // hookup bit_controller + i2c_master_bit_ctrl bit_controller ( + .clk ( clk ), + .rst ( rst ), + .nReset ( nReset ), + .ena ( ena ), + .clk_cnt ( clk_cnt ), + .cmd ( core_cmd ), + .cmd_ack ( core_ack ), + .busy ( i2c_busy ), + .al ( i2c_al ), + .din ( core_txd ), + .dout ( core_rxd ), + .scl_i ( scl_i ), + .scl_o ( scl_o ), + .scl_oen ( scl_oen ), + .sda_i ( sda_i ), + .sda_o ( sda_o ), + .sda_oen ( sda_oen ) + ); + + // generate go-signal + assign go = (read | write | stop) & ~cmd_ack; + + // assign dout output to shift-register + assign dout = sr; + + // generate shift register + always @(posedge clk or negedge nReset) + if (!nReset) + sr <= 8'h0; + else if (rst) + sr <= 8'h0; + else if (ld) + sr <= din; + else if (shift) + sr <= {sr[6:0], core_rxd}; + + // generate counter + always @(posedge clk or negedge nReset) + if (!nReset) + dcnt <= 3'h0; + else if (rst) + dcnt <= 3'h0; + else if (ld) + dcnt <= 3'h7; + else if (shift) + dcnt <= dcnt - 3'h1; + + assign cnt_done = ~(|dcnt); + + // + // state machine + // + reg [4:0] c_state; // synopsys enum_state + + always @(posedge clk or negedge nReset) + if (!nReset) + begin + core_cmd <= `I2C_CMD_NOP; + core_txd <= 1'b0; + shift <= 1'b0; + ld <= 1'b0; + cmd_ack <= 1'b0; + c_state <= ST_IDLE; + ack_out <= 1'b0; + end + else if (rst | i2c_al) + begin + core_cmd <= `I2C_CMD_NOP; + core_txd <= 1'b0; + shift <= 1'b0; + ld <= 1'b0; + cmd_ack <= 1'b0; + c_state <= ST_IDLE; + ack_out <= 1'b0; + end + else + begin + // initially reset all signals + core_txd <= sr[7]; + shift <= 1'b0; + ld <= 1'b0; + cmd_ack <= 1'b0; + + case (c_state) // synopsys full_case parallel_case + ST_IDLE: + if (go) + begin + if (start) + begin + c_state <= ST_START; + core_cmd <= `I2C_CMD_START; + end + else if (read) + begin + c_state <= ST_READ; + core_cmd <= `I2C_CMD_READ; + end + else if (write) + begin + c_state <= ST_WRITE; + core_cmd <= `I2C_CMD_WRITE; + end + else // stop + begin + c_state <= ST_STOP; + core_cmd <= `I2C_CMD_STOP; + end + + ld <= 1'b1; + end + + ST_START: + if (core_ack) + begin + if (read) + begin + c_state <= ST_READ; + core_cmd <= `I2C_CMD_READ; + end + else + begin + c_state <= ST_WRITE; + core_cmd <= `I2C_CMD_WRITE; + end + + ld <= 1'b1; + end + + ST_WRITE: + if (core_ack) + if (cnt_done) + begin + c_state <= ST_ACK; + core_cmd <= `I2C_CMD_READ; + end + else + begin + c_state <= ST_WRITE; // stay in same state + core_cmd <= `I2C_CMD_WRITE; // write next bit + shift <= 1'b1; + end + + ST_READ: + if (core_ack) + begin + if (cnt_done) + begin + c_state <= ST_ACK; + core_cmd <= `I2C_CMD_WRITE; + end + else + begin + c_state <= ST_READ; // stay in same state + core_cmd <= `I2C_CMD_READ; // read next bit + end + + shift <= 1'b1; + core_txd <= ack_in; + end + + ST_ACK: + if (core_ack) + begin + if (stop) + begin + c_state <= ST_STOP; + core_cmd <= `I2C_CMD_STOP; + end + else + begin + c_state <= ST_IDLE; + core_cmd <= `I2C_CMD_NOP; + + // generate command acknowledge signal + cmd_ack <= 1'b1; + end + + // assign ack_out output to bit_controller_rxd (contains last received bit) + ack_out <= core_rxd; + + core_txd <= 1'b1; + end + else + core_txd <= ack_in; + + ST_STOP: + if (core_ack) + begin + c_state <= ST_IDLE; + core_cmd <= `I2C_CMD_NOP; + + // generate command acknowledge signal + cmd_ack <= 1'b1; + end + + endcase + end +endmodule diff --git a/tests/i2c_bench/i2c_master_defines.v b/tests/i2c_bench/i2c_master_defines.v new file mode 100644 index 00000000..e81c546a --- /dev/null +++ b/tests/i2c_bench/i2c_master_defines.v @@ -0,0 +1,59 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE rev.B2 compliant I2C Master controller defines //// +//// //// +//// //// +//// Author: Richard Herveille //// +//// richard@asics.ws //// +//// www.asics.ws //// +//// //// +//// Downloaded from: http://www.opencores.org/projects/i2c/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: i2c_master_defines.v,v 1.3 2001-11-05 11:59:25 rherveille Exp $ +// +// $Date: 2001-11-05 11:59:25 $ +// $Revision: 1.3 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: not supported by cvs2svn $ + + +// I2C registers wishbone addresses + +// bitcontroller states +`define I2C_CMD_NOP 4'b0000 +`define I2C_CMD_START 4'b0001 +`define I2C_CMD_STOP 4'b0010 +`define I2C_CMD_WRITE 4'b0100 +`define I2C_CMD_READ 4'b1000 diff --git a/tests/i2c_bench/i2c_master_top.v b/tests/i2c_bench/i2c_master_top.v new file mode 100644 index 00000000..5e9cde7e --- /dev/null +++ b/tests/i2c_bench/i2c_master_top.v @@ -0,0 +1,301 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE revB.2 compliant I2C Master controller Top-level //// +//// //// +//// //// +//// Author: Richard Herveille //// +//// richard@asics.ws //// +//// www.asics.ws //// +//// //// +//// Downloaded from: http://www.opencores.org/projects/i2c/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: i2c_master_top.v,v 1.12 2009-01-19 20:29:26 rherveille Exp $ +// +// $Date: 2009-01-19 20:29:26 $ +// $Revision: 1.12 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// Revision 1.11 2005/02/27 09:26:24 rherveille +// Fixed register overwrite issue. +// Removed full_case pragma, replaced it by a default statement. +// +// Revision 1.10 2003/09/01 10:34:38 rherveille +// Fix a blocking vs. non-blocking error in the wb_dat output mux. +// +// Revision 1.9 2003/01/09 16:44:45 rherveille +// Fixed a bug in the Command Register declaration. +// +// Revision 1.8 2002/12/26 16:05:12 rherveille +// Small code simplifications +// +// Revision 1.7 2002/12/26 15:02:32 rherveille +// Core is now a Multimaster I2C controller +// +// Revision 1.6 2002/11/30 22:24:40 rherveille +// Cleaned up code +// +// Revision 1.5 2001/11/10 10:52:55 rherveille +// Changed PRER reset value from 0x0000 to 0xffff, conform specs. +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +`include "i2c_master_defines.v" + +module i2c_master_top( + wb_clk_i, wb_rst_i, arst_i, wb_adr_i, wb_dat_i, wb_dat_o, + wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_inta_o, + scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o ); + + // parameters + parameter ARST_LVL = 1'b0; // asynchronous reset level + + // + // inputs & outputs + // + + // wishbone signals + input wb_clk_i; // master clock input + input wb_rst_i; // synchronous active high reset + input arst_i; // asynchronous reset + input [2:0] wb_adr_i; // lower address bits + input [7:0] wb_dat_i; // databus input + output [7:0] wb_dat_o; // databus output + input wb_we_i; // write enable input + input wb_stb_i; // stobe/core select signal + input wb_cyc_i; // valid bus cycle input + output wb_ack_o; // bus cycle acknowledge output + output wb_inta_o; // interrupt request signal output + + reg [7:0] wb_dat_o; + reg wb_ack_o; + reg wb_inta_o; + + // I2C signals + // i2c clock line + input scl_pad_i; // SCL-line input + output scl_pad_o; // SCL-line output (always 1'b0) + output scl_padoen_o; // SCL-line output enable (active low) + + // i2c data line + input sda_pad_i; // SDA-line input + output sda_pad_o; // SDA-line output (always 1'b0) + output sda_padoen_o; // SDA-line output enable (active low) + + + // + // variable declarations + // + + // registers + reg [15:0] prer; // clock prescale register + reg [ 7:0] ctr; // control register + reg [ 7:0] txr; // transmit register + wire [ 7:0] rxr; // receive register + reg [ 7:0] cr; // command register + wire [ 7:0] sr; // status register + + // done signal: command completed, clear command register + wire done; + + // core enable signal + wire core_en; + wire ien; + + // status register signals + wire irxack; + reg rxack; // received aknowledge from slave + reg tip; // transfer in progress + reg irq_flag; // interrupt pending flag + wire i2c_busy; // bus busy (start signal detected) + wire i2c_al; // i2c bus arbitration lost + reg al; // status register arbitration lost bit + + // + // module body + // + + // generate internal reset + wire rst_i = arst_i ^ ARST_LVL; + + // generate wishbone signals + wire wb_wacc = wb_we_i & wb_ack_o; + + // generate acknowledge output signal + always @(posedge wb_clk_i) + wb_ack_o <= wb_cyc_i & wb_stb_i & ~wb_ack_o; // because timing is always honored + + // assign DAT_O + always @(posedge wb_clk_i) + begin + case (wb_adr_i) // synopsys parallel_case + 3'b000: wb_dat_o <= prer[ 7:0]; + 3'b001: wb_dat_o <= prer[15:8]; + 3'b010: wb_dat_o <= ctr; + 3'b011: wb_dat_o <= rxr; // write is transmit register (txr) + 3'b100: wb_dat_o <= sr; // write is command register (cr) + 3'b101: wb_dat_o <= txr; + 3'b110: wb_dat_o <= cr; + 3'b111: wb_dat_o <= 0; // reserved + default: wb_dat_o <= 16'bx; + endcase + end + + // generate registers + always @(posedge wb_clk_i or negedge rst_i) + if (!rst_i) + begin + prer <= 16'hffff; + ctr <= 8'h0; + txr <= 8'h0; + end + else if (wb_rst_i) + begin + prer <= 16'hffff; + ctr <= 8'h0; + txr <= 8'h0; + end + else + if (wb_wacc) + case (wb_adr_i) // synopsys parallel_case + 3'b000 : prer [ 7:0] <= wb_dat_i; + 3'b001 : prer [15:8] <= wb_dat_i; + 3'b010 : ctr <= wb_dat_i; + 3'b011 : txr <= wb_dat_i; + default: ; + endcase + + // generate command register (special case) + always @(posedge wb_clk_i or negedge rst_i) + if (!rst_i) + cr <= 8'h0; + else if (wb_rst_i) + cr <= 8'h0; + else if (wb_wacc) + begin + if (core_en & (wb_adr_i == 3'b100) ) + cr <= wb_dat_i; + end + else + begin + if (done | i2c_al) + cr[7:4] <= 4'h0; // clear command bits when done + // or when aribitration lost + cr[2:1] <= 2'b0; // reserved bits + cr[0] <= 1'b0; // clear IRQ_ACK bit + end + + + // decode command register + wire sta = cr[7]; + wire sto = cr[6]; + wire rd = cr[5]; + wire wr = cr[4]; + wire ack = cr[3]; + wire iack = cr[0]; + + // decode control register + assign core_en = ctr[7]; + assign ien = ctr[6]; + + // hookup byte controller block + i2c_master_byte_ctrl byte_controller ( + .clk ( wb_clk_i ), + .rst ( wb_rst_i ), + .nReset ( rst_i ), + .ena ( core_en ), + .clk_cnt ( prer ), + .start ( sta ), + .stop ( sto ), + .read ( rd ), + .write ( wr ), + .ack_in ( ack ), + .din ( txr ), + .cmd_ack ( done ), + .ack_out ( irxack ), + .dout ( rxr ), + .i2c_busy ( i2c_busy ), + .i2c_al ( i2c_al ), + .scl_i ( scl_pad_i ), + .scl_o ( scl_pad_o ), + .scl_oen ( scl_padoen_o ), + .sda_i ( sda_pad_i ), + .sda_o ( sda_pad_o ), + .sda_oen ( sda_padoen_o ) + ); + + // status register block + interrupt request signal + always @(posedge wb_clk_i or negedge rst_i) + if (!rst_i) + begin + al <= 1'b0; + rxack <= 1'b0; + tip <= 1'b0; + irq_flag <= 1'b0; + end + else if (wb_rst_i) + begin + al <= 1'b0; + rxack <= 1'b0; + tip <= 1'b0; + irq_flag <= 1'b0; + end + else + begin + al <= i2c_al | (al & ~sta); + rxack <= irxack; + tip <= (rd | wr); + irq_flag <= (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated + end + + // generate interrupt request signals + always @(posedge wb_clk_i or negedge rst_i) + if (!rst_i) + wb_inta_o <= 1'b0; + else if (wb_rst_i) + wb_inta_o <= 1'b0; + else + wb_inta_o <= irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set) + + // assign status register bits + assign sr[7] = rxack; + assign sr[6] = i2c_busy; + assign sr[5] = al; + assign sr[4:2] = 3'h0; // reserved + assign sr[1] = tip; + assign sr[0] = irq_flag; + +endmodule diff --git a/tests/i2c_bench/i2c_slave_model.v b/tests/i2c_bench/i2c_slave_model.v new file mode 100644 index 00000000..02b7572c --- /dev/null +++ b/tests/i2c_bench/i2c_slave_model.v @@ -0,0 +1,361 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE rev.B2 compliant synthesizable I2C Slave model //// +//// //// +//// //// +//// Authors: Richard Herveille (richard@asics.ws) www.asics.ws //// +//// John Sheahan (jrsheahan@optushome.com.au) //// +//// //// +//// Downloaded from: http://www.opencores.org/projects/i2c/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001,2002 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: i2c_slave_model.v,v 1.7 2006-09-04 09:08:51 rherveille Exp $ +// +// $Date: 2006-09-04 09:08:51 $ +// $Revision: 1.7 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: not supported by cvs2svn $ +// Revision 1.6 2005/02/28 11:33:48 rherveille +// Fixed Tsu:sta timing check. +// Added Thd:sta timing check. +// +// Revision 1.5 2003/12/05 11:05:19 rherveille +// Fixed slave address MSB='1' bug +// +// Revision 1.4 2003/09/11 08:25:37 rherveille +// Fixed a bug in the timing section. Changed 'tst_scl' into 'tst_sto'. +// +// Revision 1.3 2002/10/30 18:11:06 rherveille +// Added timing tests to i2c_model. +// Updated testbench. +// +// Revision 1.2 2002/03/17 10:26:38 rherveille +// Fixed some race conditions in the i2c-slave model. +// Added debug information. +// Added headers. +// + +`include "timescale.v" + +module i2c_slave_model (scl, sda); + + // + // parameters + // + parameter I2C_ADR = 7'b001_0000; + + // + // input && outpus + // + input scl; + inout sda; + + // + // Variable declaration + // + wire debug = 1'b1; + + reg [7:0] mem [3:0]; // initiate memory + reg [7:0] mem_adr; // memory address + reg [7:0] mem_do; // memory data output + + reg sta, d_sta; + reg sto, d_sto; + + reg [7:0] sr; // 8bit shift register + reg rw; // read/write direction + + wire my_adr; // my address called ?? + wire i2c_reset; // i2c-statemachine reset + reg [2:0] bit_cnt; // 3bit downcounter + wire acc_done; // 8bits transfered + reg ld; // load downcounter + + reg sda_o; // sda-drive level + wire sda_dly; // delayed version of sda + + // statemachine declaration + parameter idle = 3'b000; + parameter slave_ack = 3'b001; + parameter get_mem_adr = 3'b010; + parameter gma_ack = 3'b011; + parameter data = 3'b100; + parameter data_ack = 3'b101; + + reg [2:0] state; // synopsys enum_state + + // + // module body + // + + initial + begin + sda_o = 1'b1; + state = idle; + mem[0] = 0; + mem[1] = 0; + mem[2] = 0; + mem[3] = 0; + end + + // generate shift register + always @(posedge scl) + sr <= #1 {sr[6:0],sda}; + + //detect my_address + assign my_adr = (sr[7:1] == I2C_ADR); + // FIXME: This should not be a generic assign, but rather + // qualified on address transfer phase and probably reset by stop + + //generate bit-counter + always @(posedge scl) + if(ld) + bit_cnt <= #1 3'b111; + else + bit_cnt <= #1 bit_cnt - 3'h1; + + //generate access done signal + assign acc_done = !(|bit_cnt); + + // generate delayed version of sda + // this model assumes a hold time for sda after the falling edge of scl. + // According to the Phillips i2c spec, there s/b a 0 ns hold time for sda + // with regards to scl. If the data changes coincident with the clock, the + // acknowledge is missed + // Fix by Michael Sosnoski + assign #1 sda_dly = sda; + + + //detect start condition + always @(negedge sda) + if(scl) + begin + sta <= #1 1'b1; + d_sta <= #1 1'b0; + sto <= #1 1'b0; + + if(debug) + $display("DEBUG i2c_slave; start condition detected at %t", $time); + end + else + sta <= #1 1'b0; + + always @(posedge scl) + d_sta <= #1 sta; + + // detect stop condition + always @(posedge sda) + if(scl) + begin + sta <= #1 1'b0; + sto <= #1 1'b1; + + if(debug) + $display("DEBUG i2c_slave; stop condition detected at %t", $time); + end + else + sto <= #1 1'b0; + + //generate i2c_reset signal + assign i2c_reset = sta || sto; + + // generate statemachine + always @(negedge scl or posedge sto) + if (sto || (sta && !d_sta) ) + begin + state <= #1 idle; // reset statemachine + + sda_o <= #1 1'b1; + ld <= #1 1'b1; + end + else + begin + // initial settings + sda_o <= #1 1'b1; + ld <= #1 1'b0; + + case(state) // synopsys full_case parallel_case + idle: // idle state + if (acc_done && my_adr) + begin + state <= #1 slave_ack; + rw <= #1 sr[0]; + sda_o <= #1 1'b0; // generate i2c_ack + + #2; + if(debug && rw) + $display("DEBUG i2c_slave; command byte received (read) at %t", $time); + if(debug && !rw) + $display("DEBUG i2c_slave; command byte received (write) at %t", $time); + + if(rw) + begin + mem_do <= #1 mem[mem_adr % 4]; + + if(debug) + begin + #2 $display("DEBUG i2c_slave; data block read %x from address %x (1)", mem_do, mem_adr); + #2 $display("DEBUG i2c_slave; memcheck [0]=%x, [1]=%x, [2]=%x", mem[4'h0], mem[4'h1], mem[4'h2]); + end + end + end + + slave_ack: + begin + if(rw) + begin + state <= #1 data; + sda_o <= #1 mem_do[7]; + end + else + state <= #1 get_mem_adr; + + ld <= #1 1'b1; + end + + get_mem_adr: // wait for memory address + if(acc_done) + begin + state <= #1 gma_ack; + mem_adr <= #1 sr; // store memory address + sda_o <= #1 !(sr <= 15); // generate i2c_ack, for valid address + + if(debug) + #1 $display("DEBUG i2c_slave; address received. adr=%x, ack=%b", sr, sda_o); + end + + gma_ack: + begin + state <= #1 data; + ld <= #1 1'b1; + end + + data: // receive or drive data + begin + if(rw) + sda_o <= #1 mem_do[7]; + + if(acc_done) + begin + state <= #1 data_ack; + mem_adr <= #2 mem_adr + 8'h1; + sda_o <= #1 (rw && (mem_adr <= 15) ); // send ack on write, receive ack on read + + if(rw) + begin + #3 mem_do <= mem[mem_adr % 4]; + + if(debug) + #5 $display("DEBUG i2c_slave; data block read %x from address %x (2)", mem_do, mem_adr); + end + + if(!rw) + begin + mem[ mem_adr[3:0] ] <= #1 sr; // store data in memory + + if(debug) + #2 $display("DEBUG i2c_slave; data block write %x to address %x", sr, mem_adr); + end + end + end + + data_ack: + begin + ld <= #1 1'b1; + + if(rw) + if(sr[0]) // read operation && master send NACK + begin + state <= #1 idle; + sda_o <= #1 1'b1; + end + else + begin + state <= #1 data; + sda_o <= #1 mem_do[7]; + end + else + begin + state <= #1 data; + sda_o <= #1 1'b1; + end + end + + endcase + end + + // read data from memory + always @(posedge scl) + if(!acc_done && rw) + mem_do <= #1 {mem_do[6:0], 1'b1}; // insert 1'b1 for host ack generation + + // generate tri-states + assign sda = sda_o ? 1'bz : 1'b0; + + + // + // Timing checks + // + + wire tst_sto = sto; + wire tst_sta = sta; + + specify + specparam normal_scl_low = 4700, + normal_scl_high = 4000, + normal_tsu_sta = 4700, + normal_thd_sta = 4000, + normal_tsu_sto = 4000, + normal_tbuf = 4700, + + fast_scl_low = 1300, + fast_scl_high = 600, + fast_tsu_sta = 1300, + fast_thd_sta = 600, + fast_tsu_sto = 600, + fast_tbuf = 1300; + + $width(negedge scl, normal_scl_low); // scl low time + $width(posedge scl, normal_scl_high); // scl high time + + $setup(posedge scl, negedge sda &&& scl, normal_tsu_sta); // setup start + $setup(negedge sda &&& scl, negedge scl, normal_thd_sta); // hold start + $setup(posedge scl, posedge sda &&& scl, normal_tsu_sto); // setup stop + + $setup(posedge tst_sta, posedge tst_sto, normal_tbuf); // stop to start time + endspecify + +endmodule + + diff --git a/tests/i2c_bench/run-test.sh b/tests/i2c_bench/run-test.sh new file mode 100755 index 00000000..5fdbb059 --- /dev/null +++ b/tests/i2c_bench/run-test.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +set -e +make -C ../.. +../../yosys -l i2c_master_syn.log -o i2c_master_syn.v \ + -p hierarchy -p proc -p memory -p techmap -p opt -p abc -p opt \ + i2c_master_top.v i2c_master_bit_ctrl.v i2c_master_byte_ctrl.v +. /opt/Xilinx/13.4/ISE_DS/settings64.sh + +vlogcomp --work ref i2c_master_bit_ctrl.v +vlogcomp --work ref i2c_master_byte_ctrl.v +vlogcomp --work ref i2c_master_top.v +vlogcomp --work ref i2c_slave_model.v +vlogcomp --work ref spi_slave_model.v +vlogcomp --work ref tst_bench_top.v +vlogcomp --work ref wb_master_model.v +fuse --work ref -o testbench_ref --top tst_bench_top + +cat > testbench_ref.tcl << EOT +vcd dumpfile testbench_ref.vcd +vcd dumpvars -m tst_bench_top -l 0 +vcd dumpon +run 2 ms +exit +EOT + +./testbench_ref -tclbatch testbench_ref.tcl + +vlogcomp --work syn i2c_master_syn.v +vlogcomp --work syn ../../techlibs/simlib.v +vlogcomp --work syn ../../techlibs/stdcells_sim.v +vlogcomp --work syn i2c_slave_model.v +vlogcomp --work syn spi_slave_model.v +vlogcomp --work syn tst_bench_top.v +vlogcomp --work syn wb_master_model.v +fuse --work syn -o testbench_syn --top tst_bench_top + +cat > testbench_syn.tcl << EOT +vcd dumpfile testbench_syn.vcd +vcd dumpvars -m tst_bench_top -l 0 +vcd dumpon +run 2 ms +exit +EOT + +./testbench_syn -tclbatch testbench_syn.tcl + +perl ../tools/vcdcd.pl testbench_ref.vcd testbench_syn.vcd | tee testbench_diff.txt +echo READY. + diff --git a/tests/i2c_bench/spi_slave_model.v b/tests/i2c_bench/spi_slave_model.v new file mode 100644 index 00000000..d49347b0 --- /dev/null +++ b/tests/i2c_bench/spi_slave_model.v @@ -0,0 +1,125 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// SPI Slave Model //// +//// //// +//// //// +//// Authors: Richard Herveille (richard@asics.ws) www.asics.ws //// +//// //// +//// http://www.opencores.org/projects/simple_spi/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2004 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: spi_slave_model.v,v 1.1 2004-02-28 15:32:54 rherveille Exp $ +// +// $Date: 2004-02-28 15:32:54 $ +// $Revision: 1.1 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: not supported by cvs2svn $ +// +// + + +// Requires: Verilog2001 + +`include "timescale.v" + +module spi_slave_model ( + input wire csn, + input wire sc, + input wire di, + output wire do +); + + // + // Variable declaration + // + wire debug = 1'b1; + + wire cpol = 1'b0; + wire cpha = 1'b0; + + reg [7:0] mem [7:0]; // initiate memory + reg [2:0] mem_adr; // memory address + reg [7:0] mem_do; // memory data output + + reg [7:0] sri, sro; // 8bit shift register + + reg [2:0] bit_cnt; + reg ld; + + wire clk; + + // + // module body + // + + assign clk = cpol ^ cpha ^ sc; + + // generate shift registers + always @(posedge clk) + sri <= #1 {sri[6:0],di}; + + always @(posedge clk) + if (&bit_cnt) + sro <= #1 mem[mem_adr]; + else + sro <= #1 {sro[6:0],1'bx}; + + assign do = sro[7]; + + //generate bit-counter + always @(posedge clk, posedge csn) + if(csn) + bit_cnt <= #1 3'b111; + else + bit_cnt <= #1 bit_cnt - 3'h1; + + //generate access done signal + always @(posedge clk) + ld <= #1 ~(|bit_cnt); + + always @(negedge clk) + if (ld) begin + mem[mem_adr] <= #1 sri; + mem_adr <= #1 mem_adr + 1'b1; + end + + initial + begin + bit_cnt=3'b111; + mem_adr = 0; + sro = mem[mem_adr]; + end +endmodule + + diff --git a/tests/i2c_bench/timescale.v b/tests/i2c_bench/timescale.v new file mode 100644 index 00000000..60d4ecbd --- /dev/null +++ b/tests/i2c_bench/timescale.v @@ -0,0 +1,2 @@ +`timescale 1ns / 10ps + diff --git a/tests/i2c_bench/tst_bench_top.v b/tests/i2c_bench/tst_bench_top.v new file mode 100644 index 00000000..9458de05 --- /dev/null +++ b/tests/i2c_bench/tst_bench_top.v @@ -0,0 +1,468 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE rev.B2 compliant I2C Master controller Testbench //// +//// //// +//// //// +//// Author: Richard Herveille //// +//// richard@asics.ws //// +//// www.asics.ws //// +//// //// +//// Downloaded from: http://www.opencores.org/projects/i2c/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: tst_bench_top.v,v 1.8 2006-09-04 09:08:51 rherveille Exp $ +// +// $Date: 2006-09-04 09:08:51 $ +// $Revision: 1.8 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: not supported by cvs2svn $ +// Revision 1.7 2005/02/27 09:24:18 rherveille +// Fixed scl, sda delay. +// +// Revision 1.6 2004/02/28 15:40:42 rherveille +// *** empty log message *** +// +// Revision 1.4 2003/12/05 11:04:38 rherveille +// Added slave address configurability +// +// Revision 1.3 2002/10/30 18:11:06 rherveille +// Added timing tests to i2c_model. +// Updated testbench. +// +// Revision 1.2 2002/03/17 10:26:38 rherveille +// Fixed some race conditions in the i2c-slave model. +// Added debug information. +// Added headers. +// + +`include "timescale.v" + +module tst_bench_top(); + + // + // wires && regs + // + reg clk; + reg rstn; + + wire [31:0] adr; + wire [ 7:0] dat_i, dat_o, dat0_i, dat1_i; + wire we; + wire stb; + wire cyc; + wire ack0, ack1; + wire inta; + + reg [7:0] q, qq; + + wire scl, scl0_o, scl0_oen, scl1_o, scl1_oen; + wire sda, sda0_o, sda0_oen, sda1_o, sda1_oen; + + parameter PRER_LO = 3'b000; + parameter PRER_HI = 3'b001; + parameter CTR = 3'b010; + parameter RXR = 3'b011; + parameter TXR = 3'b011; + parameter CR = 3'b100; + parameter SR = 3'b100; + + parameter TXR_R = 3'b101; // undocumented / reserved output + parameter CR_R = 3'b110; // undocumented / reserved output + + parameter RD = 1'b1; + parameter WR = 1'b0; + parameter SADR = 7'b0010_000; + + // + // Module body + // + + // generate clock + always #5 clk = ~clk; + + // hookup wishbone master model + wb_master_model #(8, 32) u0 ( + .clk(clk), + .rst(rstn), + .adr(adr), + .din(dat_i), + .dout(dat_o), + .cyc(cyc), + .stb(stb), + .we(we), + .sel(), + .ack(ack0 || ack1), + .err(1'b0), + .rty(1'b0) + ); + + wire stb0 = stb & ~adr[3]; + wire stb1 = stb & adr[3]; + + assign dat_i = ({{8'd8}{stb0}} & dat0_i) | ({{8'd8}{stb1}} & dat1_i); + + // hookup wishbone_i2c_master core + i2c_master_top i2c_top ( + + // wishbone interface + .wb_clk_i(clk), + .wb_rst_i(1'b0), + .arst_i(rstn), + .wb_adr_i(adr[2:0]), + .wb_dat_i(dat_o), + .wb_dat_o(dat0_i), + .wb_we_i(we), + .wb_stb_i(stb0), + .wb_cyc_i(cyc), + .wb_ack_o(ack0), + .wb_inta_o(inta), + + // i2c signals + .scl_pad_i(scl), + .scl_pad_o(scl0_o), + .scl_padoen_o(scl0_oen), + .sda_pad_i(sda), + .sda_pad_o(sda0_o), + .sda_padoen_o(sda0_oen) + ), + i2c_top2 ( + + // wishbone interface + .wb_clk_i(clk), + .wb_rst_i(1'b0), + .arst_i(rstn), + .wb_adr_i(adr[2:0]), + .wb_dat_i(dat_o), + .wb_dat_o(dat1_i), + .wb_we_i(we), + .wb_stb_i(stb1), + .wb_cyc_i(cyc), + .wb_ack_o(ack1), + .wb_inta_o(inta), + + // i2c signals + .scl_pad_i(scl), + .scl_pad_o(scl1_o), + .scl_padoen_o(scl1_oen), + .sda_pad_i(sda), + .sda_pad_o(sda1_o), + .sda_padoen_o(sda1_oen) + ); + + + // hookup i2c slave model + i2c_slave_model #(SADR) i2c_slave ( + .scl(scl), + .sda(sda) + ); + + //assign scl = ~((!scl0_oen && !scl0_o) || (!scl1_oen && !scl1_o)); + //assign sda = ~((!sda0_oen && !sda0_o) || (!sda1_oen && !sda1_o)); + + // create i2c lines + delay m0_scl (scl0_oen ? 1'bz : scl0_o, scl), + m1_scl (scl1_oen ? 1'bz : scl1_o, scl), + m0_sda (sda0_oen ? 1'bz : sda0_o, sda), + m1_sda (sda1_oen ? 1'bz : sda1_o, sda); + + pullup p1(scl); // pullup scl line + pullup p2(sda); // pullup sda line + + initial + begin + `ifdef WAVES + $shm_open("waves"); + $shm_probe("AS",tst_bench_top,"AS"); + $display("INFO: Signal dump enabled ...\n\n"); + `endif + +// force i2c_slave.debug = 1'b1; // enable i2c_slave debug information + force i2c_slave.debug = 1'b0; // disable i2c_slave debug information + + $display("\nstatus: %t Testbench started\n\n", $time); + +// $dumpfile("bench.vcd"); +// $dumpvars(1, tst_bench_top); +// $dumpvars(1, tst_bench_top.i2c_slave); + + // initially values + clk = 0; + + // reset system + rstn = 1'b1; // negate reset + #2; + rstn = 1'b0; // assert reset + #1000; + repeat(1) @(posedge clk); + rstn = 1'b1; // negate reset + + $display("status: %t done reset", $time); + + @(posedge clk); + + // + // program core + // + + // program internal registers + u0.wb_write(1, PRER_LO, 8'hfa); // load prescaler lo-byte + u0.wb_write(1, PRER_LO, 8'hc8); // load prescaler lo-byte + u0.wb_write(1, PRER_HI, 8'h00); // load prescaler hi-byte + $display("status: %t programmed registers", $time); + + u0.wb_cmp(0, PRER_LO, 8'hc8); // verify prescaler lo-byte + u0.wb_cmp(0, PRER_HI, 8'h00); // verify prescaler hi-byte + $display("status: %t verified registers", $time); + + u0.wb_write(1, CTR, 8'h80); // enable core + $display("status: %t core enabled", $time); + + // + // access slave (write) + // + + // drive slave address + u0.wb_write(1, TXR, {SADR,WR} ); // present slave address, set write-bit + u0.wb_write(0, CR, 8'h90 ); // set command (start, write) + $display("status: %t generate 'start', write cmd %0h (slave address+write)", $time, {SADR,WR} ); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(0, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // send memory address + u0.wb_write(1, TXR, 8'h01); // present slave's memory address + u0.wb_write(0, CR, 8'h10); // set command (write) + $display("status: %t write slave memory address 01", $time); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(0, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // send memory contents + u0.wb_write(1, TXR, 8'ha5); // present data + u0.wb_write(0, CR, 8'h10); // set command (write) + $display("status: %t write data a5", $time); + +while (scl) #1; +force scl= 1'b0; +#100000; +release scl; + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(1, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // send memory contents for next memory address (auto_inc) + u0.wb_write(1, TXR, 8'h5a); // present data + u0.wb_write(0, CR, 8'h50); // set command (stop, write) + $display("status: %t write next data 5a, generate 'stop'", $time); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(1, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // + // delay + // +// #100000; // wait for 100us. +// $display("status: %t wait 100us", $time); + + // + // access slave (read) + // + + // drive slave address + u0.wb_write(1, TXR,{SADR,WR} ); // present slave address, set write-bit + u0.wb_write(0, CR, 8'h90 ); // set command (start, write) + $display("status: %t generate 'start', write cmd %0h (slave address+write)", $time, {SADR,WR} ); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(1, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // send memory address + u0.wb_write(1, TXR, 8'h01); // present slave's memory address + u0.wb_write(0, CR, 8'h10); // set command (write) + $display("status: %t write slave address 01", $time); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(1, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // drive slave address + u0.wb_write(1, TXR, {SADR,RD} ); // present slave's address, set read-bit + u0.wb_write(0, CR, 8'h90 ); // set command (start, write) + $display("status: %t generate 'repeated start', write cmd %0h (slave address+read)", $time, {SADR,RD} ); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(1, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // read data from slave + u0.wb_write(1, CR, 8'h20); // set command (read, ack_read) + $display("status: %t read + ack", $time); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(1, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // check data just received + u0.wb_read(1, RXR, qq); + if(qq !== 8'ha5) + $display("\nERROR: Expected a5, received %x at time %t", qq, $time); + else + $display("status: %t received %x", $time, qq); + + // read data from slave + u0.wb_write(1, CR, 8'h20); // set command (read, ack_read) + $display("status: %t read + ack", $time); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(1, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // check data just received + u0.wb_read(1, RXR, qq); + if(qq !== 8'h5a) + $display("\nERROR: Expected 5a, received %x at time %t", qq, $time); + else + $display("status: %t received %x", $time, qq); + + // read data from slave + u0.wb_write(1, CR, 8'h20); // set command (read, ack_read) + $display("status: %t read + ack", $time); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(1, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // check data just received + u0.wb_read(1, RXR, qq); + $display("status: %t received %x from 3rd read address", $time, qq); + + // read data from slave + u0.wb_write(1, CR, 8'h28); // set command (read, nack_read) + $display("status: %t read + nack", $time); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(1, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // check data just received + u0.wb_read(1, RXR, qq); + $display("status: %t received %x from 4th read address", $time, qq); + + // + // check invalid slave memory address + // + + // drive slave address + u0.wb_write(1, TXR, {SADR,WR} ); // present slave address, set write-bit + u0.wb_write(0, CR, 8'h90 ); // set command (start, write) + $display("status: %t generate 'start', write cmd %0h (slave address+write). Check invalid address", $time, {SADR,WR} ); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(1, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // send memory address + u0.wb_write(1, TXR, 8'h10); // present slave's memory address + u0.wb_write(0, CR, 8'h10); // set command (write) + $display("status: %t write slave memory address 10", $time); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(1, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + // slave should have send NACK + $display("status: %t Check for nack", $time); + if(!q[7]) + $display("\nERROR: Expected NACK, received ACK\n"); + + // read data from slave + u0.wb_write(1, CR, 8'h40); // set command (stop) + $display("status: %t generate 'stop'", $time); + + // check tip bit + u0.wb_read(1, SR, q); + while(q[1]) + u0.wb_read(1, SR, q); // poll it until it is zero + $display("status: %t tip==0", $time); + + #250000; // wait 250us + $display("\n\nstatus: %t Testbench done", $time); + $finish; + end + +endmodule + +module delay (in, out); + input in; + output out; + + assign out = in; + + specify + (in => out) = (599,599); + endspecify +endmodule + + diff --git a/tests/i2c_bench/wb_master_model.v b/tests/i2c_bench/wb_master_model.v new file mode 100644 index 00000000..65a9b798 --- /dev/null +++ b/tests/i2c_bench/wb_master_model.v @@ -0,0 +1,205 @@ +/////////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE rev.B2 Wishbone Master model //// +//// //// +//// //// +//// Author: Richard Herveille //// +//// richard@asics.ws //// +//// www.asics.ws //// +//// //// +//// Downloaded from: http://www.opencores.org/projects/mem_ctrl //// +//// //// +/////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +/////////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: wb_master_model.v,v 1.4 2004-02-28 15:40:42 rherveille Exp $ +// +// $Date: 2004-02-28 15:40:42 $ +// $Revision: 1.4 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// +`include "timescale.v" + +module wb_master_model(clk, rst, adr, din, dout, cyc, stb, we, sel, ack, err, rty); + +parameter dwidth = 32; +parameter awidth = 32; + +input clk, rst; +output [awidth -1:0] adr; +input [dwidth -1:0] din; +output [dwidth -1:0] dout; +output cyc, stb; +output we; +output [dwidth/8 -1:0] sel; +input ack, err, rty; + +//////////////////////////////////////////////////////////////////// +// +// Local Wires +// + +reg [awidth -1:0] adr; +reg [dwidth -1:0] dout; +reg cyc, stb; +reg we; +reg [dwidth/8 -1:0] sel; + +reg [dwidth -1:0] q; + +//////////////////////////////////////////////////////////////////// +// +// Memory Logic +// + +initial + begin + //adr = 32'hxxxx_xxxx; + //adr = 0; + adr = {awidth{1'bx}}; + dout = {dwidth{1'bx}}; + cyc = 1'b0; + stb = 1'bx; + we = 1'hx; + sel = {dwidth/8{1'bx}}; + #1; + $display("\nINFO: WISHBONE MASTER MODEL INSTANTIATED (%m)\n"); + end + +//////////////////////////////////////////////////////////////////// +// +// Wishbone write cycle +// + +task wb_write; + input delay; + integer delay; + + input [awidth -1:0] a; + input [dwidth -1:0] d; + + begin + + // wait initial delay + repeat(delay) @(posedge clk); + + // assert wishbone signal + #1; + adr = a; + dout = d; + cyc = 1'b1; + stb = 1'b1; + we = 1'b1; + sel = {dwidth/8{1'b1}}; + @(posedge clk); + + // wait for acknowledge from slave + while(~ack) @(posedge clk); + + // negate wishbone signals + #1; + cyc = 1'b0; + stb = 1'bx; + adr = {awidth{1'bx}}; + dout = {dwidth{1'bx}}; + we = 1'hx; + sel = {dwidth/8{1'bx}}; + + end +endtask + +//////////////////////////////////////////////////////////////////// +// +// Wishbone read cycle +// + +task wb_read; + input delay; + integer delay; + + input [awidth -1:0] a; + output [dwidth -1:0] d; + + begin + + // wait initial delay + repeat(delay) @(posedge clk); + + // assert wishbone signals + #1; + adr = a; + dout = {dwidth{1'bx}}; + cyc = 1'b1; + stb = 1'b1; + we = 1'b0; + sel = {dwidth/8{1'b1}}; + @(posedge clk); + + // wait for acknowledge from slave + while(~ack) @(posedge clk); + + // negate wishbone signals + #1; + cyc = 1'b0; + stb = 1'bx; + adr = {awidth{1'bx}}; + dout = {dwidth{1'bx}}; + we = 1'hx; + sel = {dwidth/8{1'bx}}; + d = din; + + end +endtask + +//////////////////////////////////////////////////////////////////// +// +// Wishbone compare cycle (read data from location and compare with expected data) +// + +task wb_cmp; + input delay; + integer delay; + + input [awidth -1:0] a; + input [dwidth -1:0] d_exp; + + begin + wb_read (delay, a, q); + + if (d_exp !== q) + $display("Data compare error. Received %h, expected %h at time %t", q, d_exp, $time); + end +endtask + +endmodule + + diff --git a/tests/iwls2005/README b/tests/iwls2005/README new file mode 100644 index 00000000..f44a89d9 --- /dev/null +++ b/tests/iwls2005/README @@ -0,0 +1,7 @@ + +A collection of smaller rtl examples from the IWLS 2005 benchmark [1]. +We have no testbenches for these but we can check if we can +parse and synthesize them. + +[1] http://iwls.org/iwls2005/benchmarks.html + diff --git a/tests/iwls2005/aes_core/aes_cipher_top.v b/tests/iwls2005/aes_core/aes_cipher_top.v new file mode 100644 index 00000000..a0acaeb4 --- /dev/null +++ b/tests/iwls2005/aes_core/aes_cipher_top.v @@ -0,0 +1,256 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// AES Cipher Top Level //// +//// //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// //// +//// Downloaded from: http://www.opencores.org/cores/aes_core/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000-2002 Rudolf Usselmann //// +//// www.asics.ws //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: aes_cipher_top.v,v 1.1.1.1 2002/11/09 11:22:48 rudi Exp $ +// +// $Date: 2002/11/09 11:22:48 $ +// $Revision: 1.1.1.1 $ +// $Author: rudi $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: aes_cipher_top.v,v $ +// Revision 1.1.1.1 2002/11/09 11:22:48 rudi +// Initial Checkin +// +// +// +// +// +// + +`include "timescale.v" + +module aes_cipher_top(clk, rst, ld, done, key, text_in, text_out ); +input clk, rst; +input ld; +output done; +input [127:0] key; +input [127:0] text_in; +output [127:0] text_out; + +//////////////////////////////////////////////////////////////////// +// +// Local Wires +// + +wire [31:0] w0, w1, w2, w3; +reg [127:0] text_in_r; +reg [127:0] text_out; +reg [7:0] sa00, sa01, sa02, sa03; +reg [7:0] sa10, sa11, sa12, sa13; +reg [7:0] sa20, sa21, sa22, sa23; +reg [7:0] sa30, sa31, sa32, sa33; +wire [7:0] sa00_next, sa01_next, sa02_next, sa03_next; +wire [7:0] sa10_next, sa11_next, sa12_next, sa13_next; +wire [7:0] sa20_next, sa21_next, sa22_next, sa23_next; +wire [7:0] sa30_next, sa31_next, sa32_next, sa33_next; +wire [7:0] sa00_sub, sa01_sub, sa02_sub, sa03_sub; +wire [7:0] sa10_sub, sa11_sub, sa12_sub, sa13_sub; +wire [7:0] sa20_sub, sa21_sub, sa22_sub, sa23_sub; +wire [7:0] sa30_sub, sa31_sub, sa32_sub, sa33_sub; +wire [7:0] sa00_sr, sa01_sr, sa02_sr, sa03_sr; +wire [7:0] sa10_sr, sa11_sr, sa12_sr, sa13_sr; +wire [7:0] sa20_sr, sa21_sr, sa22_sr, sa23_sr; +wire [7:0] sa30_sr, sa31_sr, sa32_sr, sa33_sr; +wire [7:0] sa00_mc, sa01_mc, sa02_mc, sa03_mc; +wire [7:0] sa10_mc, sa11_mc, sa12_mc, sa13_mc; +wire [7:0] sa20_mc, sa21_mc, sa22_mc, sa23_mc; +wire [7:0] sa30_mc, sa31_mc, sa32_mc, sa33_mc; +reg done, ld_r; +reg [3:0] dcnt; + +//////////////////////////////////////////////////////////////////// +// +// Misc Logic +// + +always @(posedge clk) + if(!rst) dcnt <= #1 4'h0; + else + if(ld) dcnt <= #1 4'hb; + else + if(|dcnt) dcnt <= #1 dcnt - 4'h1; + +always @(posedge clk) done <= #1 !(|dcnt[3:1]) & dcnt[0] & !ld; +always @(posedge clk) if(ld) text_in_r <= #1 text_in; +always @(posedge clk) ld_r <= #1 ld; + +//////////////////////////////////////////////////////////////////// +// +// Initial Permutation (AddRoundKey) +// + +always @(posedge clk) sa33 <= #1 ld_r ? text_in_r[007:000] ^ w3[07:00] : sa33_next; +always @(posedge clk) sa23 <= #1 ld_r ? text_in_r[015:008] ^ w3[15:08] : sa23_next; +always @(posedge clk) sa13 <= #1 ld_r ? text_in_r[023:016] ^ w3[23:16] : sa13_next; +always @(posedge clk) sa03 <= #1 ld_r ? text_in_r[031:024] ^ w3[31:24] : sa03_next; +always @(posedge clk) sa32 <= #1 ld_r ? text_in_r[039:032] ^ w2[07:00] : sa32_next; +always @(posedge clk) sa22 <= #1 ld_r ? text_in_r[047:040] ^ w2[15:08] : sa22_next; +always @(posedge clk) sa12 <= #1 ld_r ? text_in_r[055:048] ^ w2[23:16] : sa12_next; +always @(posedge clk) sa02 <= #1 ld_r ? text_in_r[063:056] ^ w2[31:24] : sa02_next; +always @(posedge clk) sa31 <= #1 ld_r ? text_in_r[071:064] ^ w1[07:00] : sa31_next; +always @(posedge clk) sa21 <= #1 ld_r ? text_in_r[079:072] ^ w1[15:08] : sa21_next; +always @(posedge clk) sa11 <= #1 ld_r ? text_in_r[087:080] ^ w1[23:16] : sa11_next; +always @(posedge clk) sa01 <= #1 ld_r ? text_in_r[095:088] ^ w1[31:24] : sa01_next; +always @(posedge clk) sa30 <= #1 ld_r ? text_in_r[103:096] ^ w0[07:00] : sa30_next; +always @(posedge clk) sa20 <= #1 ld_r ? text_in_r[111:104] ^ w0[15:08] : sa20_next; +always @(posedge clk) sa10 <= #1 ld_r ? text_in_r[119:112] ^ w0[23:16] : sa10_next; +always @(posedge clk) sa00 <= #1 ld_r ? text_in_r[127:120] ^ w0[31:24] : sa00_next; + +//////////////////////////////////////////////////////////////////// +// +// Round Permutations +// + +assign sa00_sr = sa00_sub; +assign sa01_sr = sa01_sub; +assign sa02_sr = sa02_sub; +assign sa03_sr = sa03_sub; +assign sa10_sr = sa11_sub; +assign sa11_sr = sa12_sub; +assign sa12_sr = sa13_sub; +assign sa13_sr = sa10_sub; +assign sa20_sr = sa22_sub; +assign sa21_sr = sa23_sub; +assign sa22_sr = sa20_sub; +assign sa23_sr = sa21_sub; +assign sa30_sr = sa33_sub; +assign sa31_sr = sa30_sub; +assign sa32_sr = sa31_sub; +assign sa33_sr = sa32_sub; +assign {sa00_mc, sa10_mc, sa20_mc, sa30_mc} = mix_col(sa00_sr,sa10_sr,sa20_sr,sa30_sr); +assign {sa01_mc, sa11_mc, sa21_mc, sa31_mc} = mix_col(sa01_sr,sa11_sr,sa21_sr,sa31_sr); +assign {sa02_mc, sa12_mc, sa22_mc, sa32_mc} = mix_col(sa02_sr,sa12_sr,sa22_sr,sa32_sr); +assign {sa03_mc, sa13_mc, sa23_mc, sa33_mc} = mix_col(sa03_sr,sa13_sr,sa23_sr,sa33_sr); +assign sa00_next = sa00_mc ^ w0[31:24]; +assign sa01_next = sa01_mc ^ w1[31:24]; +assign sa02_next = sa02_mc ^ w2[31:24]; +assign sa03_next = sa03_mc ^ w3[31:24]; +assign sa10_next = sa10_mc ^ w0[23:16]; +assign sa11_next = sa11_mc ^ w1[23:16]; +assign sa12_next = sa12_mc ^ w2[23:16]; +assign sa13_next = sa13_mc ^ w3[23:16]; +assign sa20_next = sa20_mc ^ w0[15:08]; +assign sa21_next = sa21_mc ^ w1[15:08]; +assign sa22_next = sa22_mc ^ w2[15:08]; +assign sa23_next = sa23_mc ^ w3[15:08]; +assign sa30_next = sa30_mc ^ w0[07:00]; +assign sa31_next = sa31_mc ^ w1[07:00]; +assign sa32_next = sa32_mc ^ w2[07:00]; +assign sa33_next = sa33_mc ^ w3[07:00]; + +//////////////////////////////////////////////////////////////////// +// +// Final text output +// + +always @(posedge clk) text_out[127:120] <= #1 sa00_sr ^ w0[31:24]; +always @(posedge clk) text_out[095:088] <= #1 sa01_sr ^ w1[31:24]; +always @(posedge clk) text_out[063:056] <= #1 sa02_sr ^ w2[31:24]; +always @(posedge clk) text_out[031:024] <= #1 sa03_sr ^ w3[31:24]; +always @(posedge clk) text_out[119:112] <= #1 sa10_sr ^ w0[23:16]; +always @(posedge clk) text_out[087:080] <= #1 sa11_sr ^ w1[23:16]; +always @(posedge clk) text_out[055:048] <= #1 sa12_sr ^ w2[23:16]; +always @(posedge clk) text_out[023:016] <= #1 sa13_sr ^ w3[23:16]; +always @(posedge clk) text_out[111:104] <= #1 sa20_sr ^ w0[15:08]; +always @(posedge clk) text_out[079:072] <= #1 sa21_sr ^ w1[15:08]; +always @(posedge clk) text_out[047:040] <= #1 sa22_sr ^ w2[15:08]; +always @(posedge clk) text_out[015:008] <= #1 sa23_sr ^ w3[15:08]; +always @(posedge clk) text_out[103:096] <= #1 sa30_sr ^ w0[07:00]; +always @(posedge clk) text_out[071:064] <= #1 sa31_sr ^ w1[07:00]; +always @(posedge clk) text_out[039:032] <= #1 sa32_sr ^ w2[07:00]; +always @(posedge clk) text_out[007:000] <= #1 sa33_sr ^ w3[07:00]; + +//////////////////////////////////////////////////////////////////// +// +// Generic Functions +// + +function [31:0] mix_col; +input [7:0] s0,s1,s2,s3; +reg [7:0] s0_o,s1_o,s2_o,s3_o; +begin +mix_col[31:24]=xtime(s0)^xtime(s1)^s1^s2^s3; +mix_col[23:16]=s0^xtime(s1)^xtime(s2)^s2^s3; +mix_col[15:08]=s0^s1^xtime(s2)^xtime(s3)^s3; +mix_col[07:00]=xtime(s0)^s0^s1^s2^xtime(s3); +end +endfunction + +function [7:0] xtime; +input [7:0] b; xtime={b[6:0],1'b0}^(8'h1b&{8{b[7]}}); +endfunction + +//////////////////////////////////////////////////////////////////// +// +// Modules +// + +aes_key_expand_128 u0( + .clk( clk ), + .kld( ld ), + .key( key ), + .wo_0( w0 ), + .wo_1( w1 ), + .wo_2( w2 ), + .wo_3( w3 )); + +aes_sbox us00( .a( sa00 ), .d( sa00_sub )); +aes_sbox us01( .a( sa01 ), .d( sa01_sub )); +aes_sbox us02( .a( sa02 ), .d( sa02_sub )); +aes_sbox us03( .a( sa03 ), .d( sa03_sub )); +aes_sbox us10( .a( sa10 ), .d( sa10_sub )); +aes_sbox us11( .a( sa11 ), .d( sa11_sub )); +aes_sbox us12( .a( sa12 ), .d( sa12_sub )); +aes_sbox us13( .a( sa13 ), .d( sa13_sub )); +aes_sbox us20( .a( sa20 ), .d( sa20_sub )); +aes_sbox us21( .a( sa21 ), .d( sa21_sub )); +aes_sbox us22( .a( sa22 ), .d( sa22_sub )); +aes_sbox us23( .a( sa23 ), .d( sa23_sub )); +aes_sbox us30( .a( sa30 ), .d( sa30_sub )); +aes_sbox us31( .a( sa31 ), .d( sa31_sub )); +aes_sbox us32( .a( sa32 ), .d( sa32_sub )); +aes_sbox us33( .a( sa33 ), .d( sa33_sub )); + +endmodule + + diff --git a/tests/iwls2005/aes_core/aes_inv_cipher_top.v b/tests/iwls2005/aes_core/aes_inv_cipher_top.v new file mode 100644 index 00000000..51b3525a --- /dev/null +++ b/tests/iwls2005/aes_core/aes_inv_cipher_top.v @@ -0,0 +1,327 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// AES Inverse Cipher Top Level //// +//// //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// //// +//// Downloaded from: http://www.opencores.org/cores/aes_core/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000-2002 Rudolf Usselmann //// +//// www.asics.ws //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: aes_inv_cipher_top.v,v 1.1.1.1 2002/11/09 11:22:53 rudi Exp $ +// +// $Date: 2002/11/09 11:22:53 $ +// $Revision: 1.1.1.1 $ +// $Author: rudi $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: aes_inv_cipher_top.v,v $ +// Revision 1.1.1.1 2002/11/09 11:22:53 rudi +// Initial Checkin +// +// +// +// +// +// + +`include "timescale.v" + +module aes_inv_cipher_top(clk, rst, kld, ld, done, key, text_in, text_out ); +input clk, rst; +input kld, ld; +output done; +input [127:0] key; +input [127:0] text_in; +output [127:0] text_out; + +//////////////////////////////////////////////////////////////////// +// +// Local Wires +// + +wire [31:0] wk0, wk1, wk2, wk3; +reg [31:0] w0, w1, w2, w3; +reg [127:0] text_in_r; +reg [127:0] text_out; +reg [7:0] sa00, sa01, sa02, sa03; +reg [7:0] sa10, sa11, sa12, sa13; +reg [7:0] sa20, sa21, sa22, sa23; +reg [7:0] sa30, sa31, sa32, sa33; +wire [7:0] sa00_next, sa01_next, sa02_next, sa03_next; +wire [7:0] sa10_next, sa11_next, sa12_next, sa13_next; +wire [7:0] sa20_next, sa21_next, sa22_next, sa23_next; +wire [7:0] sa30_next, sa31_next, sa32_next, sa33_next; +wire [7:0] sa00_sub, sa01_sub, sa02_sub, sa03_sub; +wire [7:0] sa10_sub, sa11_sub, sa12_sub, sa13_sub; +wire [7:0] sa20_sub, sa21_sub, sa22_sub, sa23_sub; +wire [7:0] sa30_sub, sa31_sub, sa32_sub, sa33_sub; +wire [7:0] sa00_sr, sa01_sr, sa02_sr, sa03_sr; +wire [7:0] sa10_sr, sa11_sr, sa12_sr, sa13_sr; +wire [7:0] sa20_sr, sa21_sr, sa22_sr, sa23_sr; +wire [7:0] sa30_sr, sa31_sr, sa32_sr, sa33_sr; +wire [7:0] sa00_ark, sa01_ark, sa02_ark, sa03_ark; +wire [7:0] sa10_ark, sa11_ark, sa12_ark, sa13_ark; +wire [7:0] sa20_ark, sa21_ark, sa22_ark, sa23_ark; +wire [7:0] sa30_ark, sa31_ark, sa32_ark, sa33_ark; +reg ld_r, go, done; +reg [3:0] dcnt; + +//////////////////////////////////////////////////////////////////// +// +// Misc Logic +// + +always @(posedge clk) + if(!rst) dcnt <= #1 4'h0; + else + if(done) dcnt <= #1 4'h0; + else + if(ld) dcnt <= #1 4'h1; + else + if(go) dcnt <= #1 dcnt + 4'h1; + +always @(posedge clk) done <= #1 (dcnt==4'hb) & !ld; + +always @(posedge clk) + if(!rst) go <= #1 1'b0; + else + if(ld) go <= #1 1'b1; + else + if(done) go <= #1 1'b0; + +always @(posedge clk) if(ld) text_in_r <= #1 text_in; + +always @(posedge clk) ld_r <= #1 ld; + +//////////////////////////////////////////////////////////////////// +// +// Initial Permutation +// + +always @(posedge clk) sa33 <= #1 ld_r ? text_in_r[007:000] ^ w3[07:00] : sa33_next; +always @(posedge clk) sa23 <= #1 ld_r ? text_in_r[015:008] ^ w3[15:08] : sa23_next; +always @(posedge clk) sa13 <= #1 ld_r ? text_in_r[023:016] ^ w3[23:16] : sa13_next; +always @(posedge clk) sa03 <= #1 ld_r ? text_in_r[031:024] ^ w3[31:24] : sa03_next; +always @(posedge clk) sa32 <= #1 ld_r ? text_in_r[039:032] ^ w2[07:00] : sa32_next; +always @(posedge clk) sa22 <= #1 ld_r ? text_in_r[047:040] ^ w2[15:08] : sa22_next; +always @(posedge clk) sa12 <= #1 ld_r ? text_in_r[055:048] ^ w2[23:16] : sa12_next; +always @(posedge clk) sa02 <= #1 ld_r ? text_in_r[063:056] ^ w2[31:24] : sa02_next; +always @(posedge clk) sa31 <= #1 ld_r ? text_in_r[071:064] ^ w1[07:00] : sa31_next; +always @(posedge clk) sa21 <= #1 ld_r ? text_in_r[079:072] ^ w1[15:08] : sa21_next; +always @(posedge clk) sa11 <= #1 ld_r ? text_in_r[087:080] ^ w1[23:16] : sa11_next; +always @(posedge clk) sa01 <= #1 ld_r ? text_in_r[095:088] ^ w1[31:24] : sa01_next; +always @(posedge clk) sa30 <= #1 ld_r ? text_in_r[103:096] ^ w0[07:00] : sa30_next; +always @(posedge clk) sa20 <= #1 ld_r ? text_in_r[111:104] ^ w0[15:08] : sa20_next; +always @(posedge clk) sa10 <= #1 ld_r ? text_in_r[119:112] ^ w0[23:16] : sa10_next; +always @(posedge clk) sa00 <= #1 ld_r ? text_in_r[127:120] ^ w0[31:24] : sa00_next; + +//////////////////////////////////////////////////////////////////// +// +// Round Permutations +// + +assign sa00_sr = sa00; +assign sa01_sr = sa01; +assign sa02_sr = sa02; +assign sa03_sr = sa03; +assign sa10_sr = sa13; +assign sa11_sr = sa10; +assign sa12_sr = sa11; +assign sa13_sr = sa12; +assign sa20_sr = sa22; +assign sa21_sr = sa23; +assign sa22_sr = sa20; +assign sa23_sr = sa21; +assign sa30_sr = sa31; +assign sa31_sr = sa32; +assign sa32_sr = sa33; +assign sa33_sr = sa30; +assign sa00_ark = sa00_sub ^ w0[31:24]; +assign sa01_ark = sa01_sub ^ w1[31:24]; +assign sa02_ark = sa02_sub ^ w2[31:24]; +assign sa03_ark = sa03_sub ^ w3[31:24]; +assign sa10_ark = sa10_sub ^ w0[23:16]; +assign sa11_ark = sa11_sub ^ w1[23:16]; +assign sa12_ark = sa12_sub ^ w2[23:16]; +assign sa13_ark = sa13_sub ^ w3[23:16]; +assign sa20_ark = sa20_sub ^ w0[15:08]; +assign sa21_ark = sa21_sub ^ w1[15:08]; +assign sa22_ark = sa22_sub ^ w2[15:08]; +assign sa23_ark = sa23_sub ^ w3[15:08]; +assign sa30_ark = sa30_sub ^ w0[07:00]; +assign sa31_ark = sa31_sub ^ w1[07:00]; +assign sa32_ark = sa32_sub ^ w2[07:00]; +assign sa33_ark = sa33_sub ^ w3[07:00]; +assign {sa00_next, sa10_next, sa20_next, sa30_next} = inv_mix_col(sa00_ark,sa10_ark,sa20_ark,sa30_ark); +assign {sa01_next, sa11_next, sa21_next, sa31_next} = inv_mix_col(sa01_ark,sa11_ark,sa21_ark,sa31_ark); +assign {sa02_next, sa12_next, sa22_next, sa32_next} = inv_mix_col(sa02_ark,sa12_ark,sa22_ark,sa32_ark); +assign {sa03_next, sa13_next, sa23_next, sa33_next} = inv_mix_col(sa03_ark,sa13_ark,sa23_ark,sa33_ark); + +//////////////////////////////////////////////////////////////////// +// +// Final Text Output +// + +always @(posedge clk) text_out[127:120] <= #1 sa00_ark; +always @(posedge clk) text_out[095:088] <= #1 sa01_ark; +always @(posedge clk) text_out[063:056] <= #1 sa02_ark; +always @(posedge clk) text_out[031:024] <= #1 sa03_ark; +always @(posedge clk) text_out[119:112] <= #1 sa10_ark; +always @(posedge clk) text_out[087:080] <= #1 sa11_ark; +always @(posedge clk) text_out[055:048] <= #1 sa12_ark; +always @(posedge clk) text_out[023:016] <= #1 sa13_ark; +always @(posedge clk) text_out[111:104] <= #1 sa20_ark; +always @(posedge clk) text_out[079:072] <= #1 sa21_ark; +always @(posedge clk) text_out[047:040] <= #1 sa22_ark; +always @(posedge clk) text_out[015:008] <= #1 sa23_ark; +always @(posedge clk) text_out[103:096] <= #1 sa30_ark; +always @(posedge clk) text_out[071:064] <= #1 sa31_ark; +always @(posedge clk) text_out[039:032] <= #1 sa32_ark; +always @(posedge clk) text_out[007:000] <= #1 sa33_ark; + +//////////////////////////////////////////////////////////////////// +// +// Generic Functions +// + +function [31:0] inv_mix_col; +input [7:0] s0,s1,s2,s3; +begin +inv_mix_col[31:24]=pmul_e(s0)^pmul_b(s1)^pmul_d(s2)^pmul_9(s3); +inv_mix_col[23:16]=pmul_9(s0)^pmul_e(s1)^pmul_b(s2)^pmul_d(s3); +inv_mix_col[15:08]=pmul_d(s0)^pmul_9(s1)^pmul_e(s2)^pmul_b(s3); +inv_mix_col[07:00]=pmul_b(s0)^pmul_d(s1)^pmul_9(s2)^pmul_e(s3); +end +endfunction + +// Some synthesis tools don't like xtime being called recursevly ... +function [7:0] pmul_e; +input [7:0] b; +reg [7:0] two,four,eight; +begin +two=xtime(b);four=xtime(two);eight=xtime(four);pmul_e=eight^four^two; +end +endfunction + +function [7:0] pmul_9; +input [7:0] b; +reg [7:0] two,four,eight; +begin +two=xtime(b);four=xtime(two);eight=xtime(four);pmul_9=eight^b; +end +endfunction + +function [7:0] pmul_d; +input [7:0] b; +reg [7:0] two,four,eight; +begin +two=xtime(b);four=xtime(two);eight=xtime(four);pmul_d=eight^four^b; +end +endfunction + +function [7:0] pmul_b; +input [7:0] b; +reg [7:0] two,four,eight; +begin +two=xtime(b);four=xtime(two);eight=xtime(four);pmul_b=eight^two^b; +end +endfunction + +function [7:0] xtime; +input [7:0] b;xtime={b[6:0],1'b0}^(8'h1b&{8{b[7]}}); +endfunction + +//////////////////////////////////////////////////////////////////// +// +// Key Buffer +// + +reg [127:0] kb[10:0]; +reg [3:0] kcnt; +reg kdone; +reg kb_ld; + +always @(posedge clk) + if(!rst) kcnt <= #1 4'ha; + else + if(kld) kcnt <= #1 4'ha; + else + if(kb_ld) kcnt <= #1 kcnt - 4'h1; + +always @(posedge clk) + if(!rst) kb_ld <= #1 1'b0; + else + if(kld) kb_ld <= #1 1'b1; + else + if(kcnt==4'h0) kb_ld <= #1 1'b0; + +always @(posedge clk) kdone <= #1 (kcnt==4'h0) & !kld; +always @(posedge clk) if(kb_ld) kb[kcnt] <= #1 {wk3, wk2, wk1, wk0}; +always @(posedge clk) {w3, w2, w1, w0} <= #1 kb[dcnt]; + +//////////////////////////////////////////////////////////////////// +// +// Modules +// + +aes_key_expand_128 u0( + .clk( clk ), + .kld( kld ), + .key( key ), + .wo_0( wk0 ), + .wo_1( wk1 ), + .wo_2( wk2 ), + .wo_3( wk3 )); + +aes_inv_sbox us00( .a( sa00_sr ), .d( sa00_sub )); +aes_inv_sbox us01( .a( sa01_sr ), .d( sa01_sub )); +aes_inv_sbox us02( .a( sa02_sr ), .d( sa02_sub )); +aes_inv_sbox us03( .a( sa03_sr ), .d( sa03_sub )); +aes_inv_sbox us10( .a( sa10_sr ), .d( sa10_sub )); +aes_inv_sbox us11( .a( sa11_sr ), .d( sa11_sub )); +aes_inv_sbox us12( .a( sa12_sr ), .d( sa12_sub )); +aes_inv_sbox us13( .a( sa13_sr ), .d( sa13_sub )); +aes_inv_sbox us20( .a( sa20_sr ), .d( sa20_sub )); +aes_inv_sbox us21( .a( sa21_sr ), .d( sa21_sub )); +aes_inv_sbox us22( .a( sa22_sr ), .d( sa22_sub )); +aes_inv_sbox us23( .a( sa23_sr ), .d( sa23_sub )); +aes_inv_sbox us30( .a( sa30_sr ), .d( sa30_sub )); +aes_inv_sbox us31( .a( sa31_sr ), .d( sa31_sub )); +aes_inv_sbox us32( .a( sa32_sr ), .d( sa32_sub )); +aes_inv_sbox us33( .a( sa33_sr ), .d( sa33_sub )); + +endmodule + diff --git a/tests/iwls2005/aes_core/aes_inv_sbox.v b/tests/iwls2005/aes_core/aes_inv_sbox.v new file mode 100644 index 00000000..323181eb --- /dev/null +++ b/tests/iwls2005/aes_core/aes_inv_sbox.v @@ -0,0 +1,328 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// AES Inverse SBOX (ROM) //// +//// //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// //// +//// Downloaded from: http://www.opencores.org/cores/aes_core/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000-2002 Rudolf Usselmann //// +//// www.asics.ws //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: aes_inv_sbox.v,v 1.1.1.1 2002/11/09 11:22:55 rudi Exp $ +// +// $Date: 2002/11/09 11:22:55 $ +// $Revision: 1.1.1.1 $ +// $Author: rudi $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: aes_inv_sbox.v,v $ +// Revision 1.1.1.1 2002/11/09 11:22:55 rudi +// Initial Checkin +// +// +// +// +// +// + +`include "timescale.v" + +module aes_inv_sbox(a,d); +input [7:0] a; +output [7:0] d; +reg [7:0] d; + +always @(a) + case(a) // synopsys full_case parallel_case + 8'h00: d=8'h52; + 8'h01: d=8'h09; + 8'h02: d=8'h6a; + 8'h03: d=8'hd5; + 8'h04: d=8'h30; + 8'h05: d=8'h36; + 8'h06: d=8'ha5; + 8'h07: d=8'h38; + 8'h08: d=8'hbf; + 8'h09: d=8'h40; + 8'h0a: d=8'ha3; + 8'h0b: d=8'h9e; + 8'h0c: d=8'h81; + 8'h0d: d=8'hf3; + 8'h0e: d=8'hd7; + 8'h0f: d=8'hfb; + 8'h10: d=8'h7c; + 8'h11: d=8'he3; + 8'h12: d=8'h39; + 8'h13: d=8'h82; + 8'h14: d=8'h9b; + 8'h15: d=8'h2f; + 8'h16: d=8'hff; + 8'h17: d=8'h87; + 8'h18: d=8'h34; + 8'h19: d=8'h8e; + 8'h1a: d=8'h43; + 8'h1b: d=8'h44; + 8'h1c: d=8'hc4; + 8'h1d: d=8'hde; + 8'h1e: d=8'he9; + 8'h1f: d=8'hcb; + 8'h20: d=8'h54; + 8'h21: d=8'h7b; + 8'h22: d=8'h94; + 8'h23: d=8'h32; + 8'h24: d=8'ha6; + 8'h25: d=8'hc2; + 8'h26: d=8'h23; + 8'h27: d=8'h3d; + 8'h28: d=8'hee; + 8'h29: d=8'h4c; + 8'h2a: d=8'h95; + 8'h2b: d=8'h0b; + 8'h2c: d=8'h42; + 8'h2d: d=8'hfa; + 8'h2e: d=8'hc3; + 8'h2f: d=8'h4e; + 8'h30: d=8'h08; + 8'h31: d=8'h2e; + 8'h32: d=8'ha1; + 8'h33: d=8'h66; + 8'h34: d=8'h28; + 8'h35: d=8'hd9; + 8'h36: d=8'h24; + 8'h37: d=8'hb2; + 8'h38: d=8'h76; + 8'h39: d=8'h5b; + 8'h3a: d=8'ha2; + 8'h3b: d=8'h49; + 8'h3c: d=8'h6d; + 8'h3d: d=8'h8b; + 8'h3e: d=8'hd1; + 8'h3f: d=8'h25; + 8'h40: d=8'h72; + 8'h41: d=8'hf8; + 8'h42: d=8'hf6; + 8'h43: d=8'h64; + 8'h44: d=8'h86; + 8'h45: d=8'h68; + 8'h46: d=8'h98; + 8'h47: d=8'h16; + 8'h48: d=8'hd4; + 8'h49: d=8'ha4; + 8'h4a: d=8'h5c; + 8'h4b: d=8'hcc; + 8'h4c: d=8'h5d; + 8'h4d: d=8'h65; + 8'h4e: d=8'hb6; + 8'h4f: d=8'h92; + 8'h50: d=8'h6c; + 8'h51: d=8'h70; + 8'h52: d=8'h48; + 8'h53: d=8'h50; + 8'h54: d=8'hfd; + 8'h55: d=8'hed; + 8'h56: d=8'hb9; + 8'h57: d=8'hda; + 8'h58: d=8'h5e; + 8'h59: d=8'h15; + 8'h5a: d=8'h46; + 8'h5b: d=8'h57; + 8'h5c: d=8'ha7; + 8'h5d: d=8'h8d; + 8'h5e: d=8'h9d; + 8'h5f: d=8'h84; + 8'h60: d=8'h90; + 8'h61: d=8'hd8; + 8'h62: d=8'hab; + 8'h63: d=8'h00; + 8'h64: d=8'h8c; + 8'h65: d=8'hbc; + 8'h66: d=8'hd3; + 8'h67: d=8'h0a; + 8'h68: d=8'hf7; + 8'h69: d=8'he4; + 8'h6a: d=8'h58; + 8'h6b: d=8'h05; + 8'h6c: d=8'hb8; + 8'h6d: d=8'hb3; + 8'h6e: d=8'h45; + 8'h6f: d=8'h06; + 8'h70: d=8'hd0; + 8'h71: d=8'h2c; + 8'h72: d=8'h1e; + 8'h73: d=8'h8f; + 8'h74: d=8'hca; + 8'h75: d=8'h3f; + 8'h76: d=8'h0f; + 8'h77: d=8'h02; + 8'h78: d=8'hc1; + 8'h79: d=8'haf; + 8'h7a: d=8'hbd; + 8'h7b: d=8'h03; + 8'h7c: d=8'h01; + 8'h7d: d=8'h13; + 8'h7e: d=8'h8a; + 8'h7f: d=8'h6b; + 8'h80: d=8'h3a; + 8'h81: d=8'h91; + 8'h82: d=8'h11; + 8'h83: d=8'h41; + 8'h84: d=8'h4f; + 8'h85: d=8'h67; + 8'h86: d=8'hdc; + 8'h87: d=8'hea; + 8'h88: d=8'h97; + 8'h89: d=8'hf2; + 8'h8a: d=8'hcf; + 8'h8b: d=8'hce; + 8'h8c: d=8'hf0; + 8'h8d: d=8'hb4; + 8'h8e: d=8'he6; + 8'h8f: d=8'h73; + 8'h90: d=8'h96; + 8'h91: d=8'hac; + 8'h92: d=8'h74; + 8'h93: d=8'h22; + 8'h94: d=8'he7; + 8'h95: d=8'had; + 8'h96: d=8'h35; + 8'h97: d=8'h85; + 8'h98: d=8'he2; + 8'h99: d=8'hf9; + 8'h9a: d=8'h37; + 8'h9b: d=8'he8; + 8'h9c: d=8'h1c; + 8'h9d: d=8'h75; + 8'h9e: d=8'hdf; + 8'h9f: d=8'h6e; + 8'ha0: d=8'h47; + 8'ha1: d=8'hf1; + 8'ha2: d=8'h1a; + 8'ha3: d=8'h71; + 8'ha4: d=8'h1d; + 8'ha5: d=8'h29; + 8'ha6: d=8'hc5; + 8'ha7: d=8'h89; + 8'ha8: d=8'h6f; + 8'ha9: d=8'hb7; + 8'haa: d=8'h62; + 8'hab: d=8'h0e; + 8'hac: d=8'haa; + 8'had: d=8'h18; + 8'hae: d=8'hbe; + 8'haf: d=8'h1b; + 8'hb0: d=8'hfc; + 8'hb1: d=8'h56; + 8'hb2: d=8'h3e; + 8'hb3: d=8'h4b; + 8'hb4: d=8'hc6; + 8'hb5: d=8'hd2; + 8'hb6: d=8'h79; + 8'hb7: d=8'h20; + 8'hb8: d=8'h9a; + 8'hb9: d=8'hdb; + 8'hba: d=8'hc0; + 8'hbb: d=8'hfe; + 8'hbc: d=8'h78; + 8'hbd: d=8'hcd; + 8'hbe: d=8'h5a; + 8'hbf: d=8'hf4; + 8'hc0: d=8'h1f; + 8'hc1: d=8'hdd; + 8'hc2: d=8'ha8; + 8'hc3: d=8'h33; + 8'hc4: d=8'h88; + 8'hc5: d=8'h07; + 8'hc6: d=8'hc7; + 8'hc7: d=8'h31; + 8'hc8: d=8'hb1; + 8'hc9: d=8'h12; + 8'hca: d=8'h10; + 8'hcb: d=8'h59; + 8'hcc: d=8'h27; + 8'hcd: d=8'h80; + 8'hce: d=8'hec; + 8'hcf: d=8'h5f; + 8'hd0: d=8'h60; + 8'hd1: d=8'h51; + 8'hd2: d=8'h7f; + 8'hd3: d=8'ha9; + 8'hd4: d=8'h19; + 8'hd5: d=8'hb5; + 8'hd6: d=8'h4a; + 8'hd7: d=8'h0d; + 8'hd8: d=8'h2d; + 8'hd9: d=8'he5; + 8'hda: d=8'h7a; + 8'hdb: d=8'h9f; + 8'hdc: d=8'h93; + 8'hdd: d=8'hc9; + 8'hde: d=8'h9c; + 8'hdf: d=8'hef; + 8'he0: d=8'ha0; + 8'he1: d=8'he0; + 8'he2: d=8'h3b; + 8'he3: d=8'h4d; + 8'he4: d=8'hae; + 8'he5: d=8'h2a; + 8'he6: d=8'hf5; + 8'he7: d=8'hb0; + 8'he8: d=8'hc8; + 8'he9: d=8'heb; + 8'hea: d=8'hbb; + 8'heb: d=8'h3c; + 8'hec: d=8'h83; + 8'hed: d=8'h53; + 8'hee: d=8'h99; + 8'hef: d=8'h61; + 8'hf0: d=8'h17; + 8'hf1: d=8'h2b; + 8'hf2: d=8'h04; + 8'hf3: d=8'h7e; + 8'hf4: d=8'hba; + 8'hf5: d=8'h77; + 8'hf6: d=8'hd6; + 8'hf7: d=8'h26; + 8'hf8: d=8'he1; + 8'hf9: d=8'h69; + 8'hfa: d=8'h14; + 8'hfb: d=8'h63; + 8'hfc: d=8'h55; + 8'hfd: d=8'h21; + 8'hfe: d=8'h0c; + 8'hff: d=8'h7d; + endcase +endmodule + + diff --git a/tests/iwls2005/aes_core/aes_key_expand_128.v b/tests/iwls2005/aes_core/aes_key_expand_128.v new file mode 100644 index 00000000..ddc74b73 --- /dev/null +++ b/tests/iwls2005/aes_core/aes_key_expand_128.v @@ -0,0 +1,87 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// AES Key Expand Block (for 128 bit keys) //// +//// //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// //// +//// Downloaded from: http://www.opencores.org/cores/aes_core/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000-2002 Rudolf Usselmann //// +//// www.asics.ws //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: aes_key_expand_128.v,v 1.1.1.1 2002/11/09 11:22:38 rudi Exp $ +// +// $Date: 2002/11/09 11:22:38 $ +// $Revision: 1.1.1.1 $ +// $Author: rudi $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: aes_key_expand_128.v,v $ +// Revision 1.1.1.1 2002/11/09 11:22:38 rudi +// Initial Checkin +// +// +// +// +// +// + +`include "timescale.v" + +module aes_key_expand_128(clk, kld, key, wo_0, wo_1, wo_2, wo_3); +input clk; +input kld; +input [127:0] key; +output [31:0] wo_0, wo_1, wo_2, wo_3; +reg [31:0] w[3:0]; +wire [31:0] tmp_w; +wire [31:0] subword; +wire [31:0] rcon; + +assign wo_0 = w[0]; +assign wo_1 = w[1]; +assign wo_2 = w[2]; +assign wo_3 = w[3]; +always @(posedge clk) w[0] <= #1 kld ? key[127:096] : w[0]^subword^rcon; +always @(posedge clk) w[1] <= #1 kld ? key[095:064] : w[0]^w[1]^subword^rcon; +always @(posedge clk) w[2] <= #1 kld ? key[063:032] : w[0]^w[2]^w[1]^subword^rcon; +always @(posedge clk) w[3] <= #1 kld ? key[031:000] : w[0]^w[3]^w[2]^w[1]^subword^rcon; +assign tmp_w = w[3]; +aes_sbox u0( .a(tmp_w[23:16]), .d(subword[31:24])); +aes_sbox u1( .a(tmp_w[15:08]), .d(subword[23:16])); +aes_sbox u2( .a(tmp_w[07:00]), .d(subword[15:08])); +aes_sbox u3( .a(tmp_w[31:24]), .d(subword[07:00])); +aes_rcon r0( .clk(clk), .kld(kld), .out(rcon)); +endmodule + diff --git a/tests/iwls2005/aes_core/aes_rcon.v b/tests/iwls2005/aes_core/aes_rcon.v new file mode 100644 index 00000000..c2c0a124 --- /dev/null +++ b/tests/iwls2005/aes_core/aes_rcon.v @@ -0,0 +1,96 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// AES RCON Block //// +//// //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// //// +//// Downloaded from: http://www.opencores.org/cores/aes_core/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000-2002 Rudolf Usselmann //// +//// www.asics.ws //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: aes_rcon.v,v 1.1.1.1 2002/11/09 11:22:38 rudi Exp $ +// +// $Date: 2002/11/09 11:22:38 $ +// $Revision: 1.1.1.1 $ +// $Author: rudi $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: aes_rcon.v,v $ +// Revision 1.1.1.1 2002/11/09 11:22:38 rudi +// Initial Checkin +// +// +// +// +// +// + +`include "timescale.v" + +module aes_rcon(clk, kld, out); +input clk; +input kld; +output [31:0] out; +reg [31:0] out; +reg [3:0] rcnt; +wire [3:0] rcnt_next; + +always @(posedge clk) + if(kld) out <= #1 32'h01_00_00_00; + else out <= #1 frcon(rcnt_next); + +assign rcnt_next = rcnt + 4'h1; +always @(posedge clk) + if(kld) rcnt <= #1 4'h0; + else rcnt <= #1 rcnt_next; + +function [31:0] frcon; +input [3:0] i; +case(i) // synopsys parallel_case + 4'h0: frcon=32'h01_00_00_00; + 4'h1: frcon=32'h02_00_00_00; + 4'h2: frcon=32'h04_00_00_00; + 4'h3: frcon=32'h08_00_00_00; + 4'h4: frcon=32'h10_00_00_00; + 4'h5: frcon=32'h20_00_00_00; + 4'h6: frcon=32'h40_00_00_00; + 4'h7: frcon=32'h80_00_00_00; + 4'h8: frcon=32'h1b_00_00_00; + 4'h9: frcon=32'h36_00_00_00; + default: frcon=32'h00_00_00_00; +endcase +endfunction + +endmodule diff --git a/tests/iwls2005/aes_core/aes_sbox.v b/tests/iwls2005/aes_core/aes_sbox.v new file mode 100644 index 00000000..e01d75ef --- /dev/null +++ b/tests/iwls2005/aes_core/aes_sbox.v @@ -0,0 +1,329 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// AES SBOX (ROM) //// +//// //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// //// +//// Downloaded from: http://www.opencores.org/cores/aes_core/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000-2002 Rudolf Usselmann //// +//// www.asics.ws //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: aes_sbox.v,v 1.1.1.1 2002/11/09 11:22:38 rudi Exp $ +// +// $Date: 2002/11/09 11:22:38 $ +// $Revision: 1.1.1.1 $ +// $Author: rudi $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: aes_sbox.v,v $ +// Revision 1.1.1.1 2002/11/09 11:22:38 rudi +// Initial Checkin +// +// +// +// +// +// + +`include "timescale.v" + +module aes_sbox(a,d); +input [7:0] a; +output [7:0] d; +reg [7:0] d; + +always @(a) + case(a) // synopsys full_case parallel_case + 8'h00: d=8'h63; + 8'h01: d=8'h7c; + 8'h02: d=8'h77; + 8'h03: d=8'h7b; + 8'h04: d=8'hf2; + 8'h05: d=8'h6b; + 8'h06: d=8'h6f; + 8'h07: d=8'hc5; + 8'h08: d=8'h30; + 8'h09: d=8'h01; + 8'h0a: d=8'h67; + 8'h0b: d=8'h2b; + 8'h0c: d=8'hfe; + 8'h0d: d=8'hd7; + 8'h0e: d=8'hab; + 8'h0f: d=8'h76; + 8'h10: d=8'hca; + 8'h11: d=8'h82; + 8'h12: d=8'hc9; + 8'h13: d=8'h7d; + 8'h14: d=8'hfa; + 8'h15: d=8'h59; + 8'h16: d=8'h47; + 8'h17: d=8'hf0; + 8'h18: d=8'had; + 8'h19: d=8'hd4; + 8'h1a: d=8'ha2; + 8'h1b: d=8'haf; + 8'h1c: d=8'h9c; + 8'h1d: d=8'ha4; + 8'h1e: d=8'h72; + 8'h1f: d=8'hc0; + 8'h20: d=8'hb7; + 8'h21: d=8'hfd; + 8'h22: d=8'h93; + 8'h23: d=8'h26; + 8'h24: d=8'h36; + 8'h25: d=8'h3f; + 8'h26: d=8'hf7; + 8'h27: d=8'hcc; + 8'h28: d=8'h34; + 8'h29: d=8'ha5; + 8'h2a: d=8'he5; + 8'h2b: d=8'hf1; + 8'h2c: d=8'h71; + 8'h2d: d=8'hd8; + 8'h2e: d=8'h31; + 8'h2f: d=8'h15; + 8'h30: d=8'h04; + 8'h31: d=8'hc7; + 8'h32: d=8'h23; + 8'h33: d=8'hc3; + 8'h34: d=8'h18; + 8'h35: d=8'h96; + 8'h36: d=8'h05; + 8'h37: d=8'h9a; + 8'h38: d=8'h07; + 8'h39: d=8'h12; + 8'h3a: d=8'h80; + 8'h3b: d=8'he2; + 8'h3c: d=8'heb; + 8'h3d: d=8'h27; + 8'h3e: d=8'hb2; + 8'h3f: d=8'h75; + 8'h40: d=8'h09; + 8'h41: d=8'h83; + 8'h42: d=8'h2c; + 8'h43: d=8'h1a; + 8'h44: d=8'h1b; + 8'h45: d=8'h6e; + 8'h46: d=8'h5a; + 8'h47: d=8'ha0; + 8'h48: d=8'h52; + 8'h49: d=8'h3b; + 8'h4a: d=8'hd6; + 8'h4b: d=8'hb3; + 8'h4c: d=8'h29; + 8'h4d: d=8'he3; + 8'h4e: d=8'h2f; + 8'h4f: d=8'h84; + 8'h50: d=8'h53; + 8'h51: d=8'hd1; + 8'h52: d=8'h00; + 8'h53: d=8'hed; + 8'h54: d=8'h20; + 8'h55: d=8'hfc; + 8'h56: d=8'hb1; + 8'h57: d=8'h5b; + 8'h58: d=8'h6a; + 8'h59: d=8'hcb; + 8'h5a: d=8'hbe; + 8'h5b: d=8'h39; + 8'h5c: d=8'h4a; + 8'h5d: d=8'h4c; + 8'h5e: d=8'h58; + 8'h5f: d=8'hcf; + 8'h60: d=8'hd0; + 8'h61: d=8'hef; + 8'h62: d=8'haa; + 8'h63: d=8'hfb; + 8'h64: d=8'h43; + 8'h65: d=8'h4d; + 8'h66: d=8'h33; + 8'h67: d=8'h85; + 8'h68: d=8'h45; + 8'h69: d=8'hf9; + 8'h6a: d=8'h02; + 8'h6b: d=8'h7f; + 8'h6c: d=8'h50; + 8'h6d: d=8'h3c; + 8'h6e: d=8'h9f; + 8'h6f: d=8'ha8; + 8'h70: d=8'h51; + 8'h71: d=8'ha3; + 8'h72: d=8'h40; + 8'h73: d=8'h8f; + 8'h74: d=8'h92; + 8'h75: d=8'h9d; + 8'h76: d=8'h38; + 8'h77: d=8'hf5; + 8'h78: d=8'hbc; + 8'h79: d=8'hb6; + 8'h7a: d=8'hda; + 8'h7b: d=8'h21; + 8'h7c: d=8'h10; + 8'h7d: d=8'hff; + 8'h7e: d=8'hf3; + 8'h7f: d=8'hd2; + 8'h80: d=8'hcd; + 8'h81: d=8'h0c; + 8'h82: d=8'h13; + 8'h83: d=8'hec; + 8'h84: d=8'h5f; + 8'h85: d=8'h97; + 8'h86: d=8'h44; + 8'h87: d=8'h17; + 8'h88: d=8'hc4; + 8'h89: d=8'ha7; + 8'h8a: d=8'h7e; + 8'h8b: d=8'h3d; + 8'h8c: d=8'h64; + 8'h8d: d=8'h5d; + 8'h8e: d=8'h19; + 8'h8f: d=8'h73; + 8'h90: d=8'h60; + 8'h91: d=8'h81; + 8'h92: d=8'h4f; + 8'h93: d=8'hdc; + 8'h94: d=8'h22; + 8'h95: d=8'h2a; + 8'h96: d=8'h90; + 8'h97: d=8'h88; + 8'h98: d=8'h46; + 8'h99: d=8'hee; + 8'h9a: d=8'hb8; + 8'h9b: d=8'h14; + 8'h9c: d=8'hde; + 8'h9d: d=8'h5e; + 8'h9e: d=8'h0b; + 8'h9f: d=8'hdb; + 8'ha0: d=8'he0; + 8'ha1: d=8'h32; + 8'ha2: d=8'h3a; + 8'ha3: d=8'h0a; + 8'ha4: d=8'h49; + 8'ha5: d=8'h06; + 8'ha6: d=8'h24; + 8'ha7: d=8'h5c; + 8'ha8: d=8'hc2; + 8'ha9: d=8'hd3; + 8'haa: d=8'hac; + 8'hab: d=8'h62; + 8'hac: d=8'h91; + 8'had: d=8'h95; + 8'hae: d=8'he4; + 8'haf: d=8'h79; + 8'hb0: d=8'he7; + 8'hb1: d=8'hc8; + 8'hb2: d=8'h37; + 8'hb3: d=8'h6d; + 8'hb4: d=8'h8d; + 8'hb5: d=8'hd5; + 8'hb6: d=8'h4e; + 8'hb7: d=8'ha9; + 8'hb8: d=8'h6c; + 8'hb9: d=8'h56; + 8'hba: d=8'hf4; + 8'hbb: d=8'hea; + 8'hbc: d=8'h65; + 8'hbd: d=8'h7a; + 8'hbe: d=8'hae; + 8'hbf: d=8'h08; + 8'hc0: d=8'hba; + 8'hc1: d=8'h78; + 8'hc2: d=8'h25; + 8'hc3: d=8'h2e; + 8'hc4: d=8'h1c; + 8'hc5: d=8'ha6; + 8'hc6: d=8'hb4; + 8'hc7: d=8'hc6; + 8'hc8: d=8'he8; + 8'hc9: d=8'hdd; + 8'hca: d=8'h74; + 8'hcb: d=8'h1f; + 8'hcc: d=8'h4b; + 8'hcd: d=8'hbd; + 8'hce: d=8'h8b; + 8'hcf: d=8'h8a; + 8'hd0: d=8'h70; + 8'hd1: d=8'h3e; + 8'hd2: d=8'hb5; + 8'hd3: d=8'h66; + 8'hd4: d=8'h48; + 8'hd5: d=8'h03; + 8'hd6: d=8'hf6; + 8'hd7: d=8'h0e; + 8'hd8: d=8'h61; + 8'hd9: d=8'h35; + 8'hda: d=8'h57; + 8'hdb: d=8'hb9; + 8'hdc: d=8'h86; + 8'hdd: d=8'hc1; + 8'hde: d=8'h1d; + 8'hdf: d=8'h9e; + 8'he0: d=8'he1; + 8'he1: d=8'hf8; + 8'he2: d=8'h98; + 8'he3: d=8'h11; + 8'he4: d=8'h69; + 8'he5: d=8'hd9; + 8'he6: d=8'h8e; + 8'he7: d=8'h94; + 8'he8: d=8'h9b; + 8'he9: d=8'h1e; + 8'hea: d=8'h87; + 8'heb: d=8'he9; + 8'hec: d=8'hce; + 8'hed: d=8'h55; + 8'hee: d=8'h28; + 8'hef: d=8'hdf; + 8'hf0: d=8'h8c; + 8'hf1: d=8'ha1; + 8'hf2: d=8'h89; + 8'hf3: d=8'h0d; + 8'hf4: d=8'hbf; + 8'hf5: d=8'he6; + 8'hf6: d=8'h42; + 8'hf7: d=8'h68; + 8'hf8: d=8'h41; + 8'hf9: d=8'h99; + 8'hfa: d=8'h2d; + 8'hfb: d=8'h0f; + 8'hfc: d=8'hb0; + 8'hfd: d=8'h54; + 8'hfe: d=8'hbb; + 8'hff: d=8'h16; + endcase + +endmodule + + diff --git a/tests/iwls2005/aes_core/timescale.v b/tests/iwls2005/aes_core/timescale.v new file mode 100644 index 00000000..ff9e265a --- /dev/null +++ b/tests/iwls2005/aes_core/timescale.v @@ -0,0 +1 @@ +`timescale 1ns / 10ps diff --git a/tests/iwls2005/fpu/except.v b/tests/iwls2005/fpu/except.v new file mode 100644 index 00000000..007099fe --- /dev/null +++ b/tests/iwls2005/fpu/except.v @@ -0,0 +1,153 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// EXCEPT //// +//// Floating Point Exception/Special Numbers Unit //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + + +`timescale 1ns / 100ps + + +module except( clk, opa, opb, inf, ind, qnan, snan, opa_nan, opb_nan, + opa_00, opb_00, opa_inf, opb_inf, opa_dn, opb_dn); +input clk; +input [31:0] opa, opb; +output inf, ind, qnan, snan, opa_nan, opb_nan; +output opa_00, opb_00; +output opa_inf, opb_inf; +output opa_dn; +output opb_dn; + +//////////////////////////////////////////////////////////////////////// +// +// Local Wires and registers +// + +wire [7:0] expa, expb; // alias to opX exponent +wire [22:0] fracta, fractb; // alias to opX fraction +reg expa_ff, infa_f_r, qnan_r_a, snan_r_a; +reg expb_ff, infb_f_r, qnan_r_b, snan_r_b; +reg inf, ind, qnan, snan; // Output registers +reg opa_nan, opb_nan; +reg expa_00, expb_00, fracta_00, fractb_00; +reg opa_00, opb_00; +reg opa_inf, opb_inf; +reg opa_dn, opb_dn; + +//////////////////////////////////////////////////////////////////////// +// +// Aliases +// + +assign expa = opa[30:23]; +assign expb = opb[30:23]; +assign fracta = opa[22:0]; +assign fractb = opb[22:0]; + +//////////////////////////////////////////////////////////////////////// +// +// Determine if any of the input operators is a INF or NAN or any other special number +// + +always @(posedge clk) + expa_ff <= #1 &expa; + +always @(posedge clk) + expb_ff <= #1 &expb; + +always @(posedge clk) + infa_f_r <= #1 !(|fracta); + +always @(posedge clk) + infb_f_r <= #1 !(|fractb); + +always @(posedge clk) + qnan_r_a <= #1 fracta[22]; + +always @(posedge clk) + snan_r_a <= #1 !fracta[22] & |fracta[21:0]; + +always @(posedge clk) + qnan_r_b <= #1 fractb[22]; + +always @(posedge clk) + snan_r_b <= #1 !fractb[22] & |fractb[21:0]; + +always @(posedge clk) + ind <= #1 (expa_ff & infa_f_r) & (expb_ff & infb_f_r); + +always @(posedge clk) + inf <= #1 (expa_ff & infa_f_r) | (expb_ff & infb_f_r); + +always @(posedge clk) + qnan <= #1 (expa_ff & qnan_r_a) | (expb_ff & qnan_r_b); + +always @(posedge clk) + snan <= #1 (expa_ff & snan_r_a) | (expb_ff & snan_r_b); + +always @(posedge clk) + opa_nan <= #1 &expa & (|fracta[22:0]); + +always @(posedge clk) + opb_nan <= #1 &expb & (|fractb[22:0]); + +always @(posedge clk) + opa_inf <= #1 (expa_ff & infa_f_r); + +always @(posedge clk) + opb_inf <= #1 (expb_ff & infb_f_r); + +always @(posedge clk) + expa_00 <= #1 !(|expa); + +always @(posedge clk) + expb_00 <= #1 !(|expb); + +always @(posedge clk) + fracta_00 <= #1 !(|fracta); + +always @(posedge clk) + fractb_00 <= #1 !(|fractb); + +always @(posedge clk) + opa_00 <= #1 expa_00 & fracta_00; + +always @(posedge clk) + opb_00 <= #1 expb_00 & fractb_00; + +always @(posedge clk) + opa_dn <= #1 expa_00; + +always @(posedge clk) + opb_dn <= #1 expb_00; + +endmodule + diff --git a/tests/iwls2005/fpu/fpu.v b/tests/iwls2005/fpu/fpu.v new file mode 100644 index 00000000..165a1d24 --- /dev/null +++ b/tests/iwls2005/fpu/fpu.v @@ -0,0 +1,560 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// FPU //// +//// Floating Point Unit (Single precision) //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +`timescale 1ns / 100ps + +/* + +FPU Operations (fpu_op): +======================== + +0 = add +1 = sub +2 = mul +3 = div +4 = +5 = +6 = +7 = + +Rounding Modes (rmode): +======================= + +0 = round_nearest_even +1 = round_to_zero +2 = round_up +3 = round_down + +*/ + + +module fpu( clk, rmode, fpu_op, opa, opb, out, inf, snan, qnan, ine, overflow, underflow, zero, div_by_zero); +input clk; +input [1:0] rmode; +input [2:0] fpu_op; +input [31:0] opa, opb; +output [31:0] out; +output inf, snan, qnan; +output ine; +output overflow, underflow; +output zero; +output div_by_zero; + +parameter INF = 31'h7f800000, + QNAN = 31'h7fc00001, + SNAN = 31'h7f800001; + +//////////////////////////////////////////////////////////////////////// +// +// Local Wires +// +reg zero; +reg [31:0] opa_r, opb_r; // Input operand registers +reg [31:0] out; // Output register +reg div_by_zero; // Divide by zero output register +wire signa, signb; // alias to opX sign +wire sign_fasu; // sign output +wire [26:0] fracta, fractb; // Fraction Outputs from EQU block +wire [7:0] exp_fasu; // Exponent output from EQU block +reg [7:0] exp_r; // Exponent output (registerd) +wire [26:0] fract_out_d; // fraction output +wire co; // carry output +reg [27:0] fract_out_q; // fraction output (registerd) +wire [30:0] out_d; // Intermediate final result output +wire overflow_d, underflow_d;// Overflow/Underflow Indicators +reg overflow, underflow; // Output registers for Overflow & Underflow +reg inf, snan, qnan; // Output Registers for INF, SNAN and QNAN +reg ine; // Output Registers for INE +reg [1:0] rmode_r1, rmode_r2, // Pipeline registers for rounding mode + rmode_r3; +reg [2:0] fpu_op_r1, fpu_op_r2, // Pipeline registers for fp opration + fpu_op_r3; +wire mul_inf, div_inf; +wire mul_00, div_00; + +//////////////////////////////////////////////////////////////////////// +// +// Input Registers +// + +always @(posedge clk) + opa_r <= #1 opa; + +always @(posedge clk) + opb_r <= #1 opb; + +always @(posedge clk) + rmode_r1 <= #1 rmode; + +always @(posedge clk) + rmode_r2 <= #1 rmode_r1; + +always @(posedge clk) + rmode_r3 <= #1 rmode_r2; + +always @(posedge clk) + fpu_op_r1 <= #1 fpu_op; + +always @(posedge clk) + fpu_op_r2 <= #1 fpu_op_r1; + +always @(posedge clk) + fpu_op_r3 <= #1 fpu_op_r2; + +//////////////////////////////////////////////////////////////////////// +// +// Exceptions block +// +wire inf_d, ind_d, qnan_d, snan_d, opa_nan, opb_nan; +wire opa_00, opb_00; +wire opa_inf, opb_inf; +wire opa_dn, opb_dn; + +except u0( .clk(clk), + .opa(opa_r), .opb(opb_r), + .inf(inf_d), .ind(ind_d), + .qnan(qnan_d), .snan(snan_d), + .opa_nan(opa_nan), .opb_nan(opb_nan), + .opa_00(opa_00), .opb_00(opb_00), + .opa_inf(opa_inf), .opb_inf(opb_inf), + .opa_dn(opa_dn), .opb_dn(opb_dn) + ); + +//////////////////////////////////////////////////////////////////////// +// +// Pre-Normalize block +// - Adjusts the numbers to equal exponents and sorts them +// - determine result sign +// - determine actual operation to perform (add or sub) +// + +wire nan_sign_d, result_zero_sign_d; +reg sign_fasu_r; +wire [7:0] exp_mul; +wire sign_mul; +reg sign_mul_r; +wire [23:0] fracta_mul, fractb_mul; +wire inf_mul; +reg inf_mul_r; +wire [1:0] exp_ovf; +reg [1:0] exp_ovf_r; +wire sign_exe; +reg sign_exe_r; +wire [2:0] underflow_fmul_d; + + +pre_norm u1(.clk(clk), // System Clock + .rmode(rmode_r2), // Roundin Mode + .add(!fpu_op_r1[0]), // Add/Sub Input + .opa(opa_r), .opb(opb_r), // Registered OP Inputs + .opa_nan(opa_nan), // OpA is a NAN indicator + .opb_nan(opb_nan), // OpB is a NAN indicator + .fracta_out(fracta), // Equalized and sorted fraction + .fractb_out(fractb), // outputs (Registered) + .exp_dn_out(exp_fasu), // Selected exponent output (registered); + .sign(sign_fasu), // Encoded output Sign (registered) + .nan_sign(nan_sign_d), // Output Sign for NANs (registered) + .result_zero_sign(result_zero_sign_d), // Output Sign for zero result (registered) + .fasu_op(fasu_op) // Actual fasu operation output (registered) + ); + +always @(posedge clk) + sign_fasu_r <= #1 sign_fasu; + +pre_norm_fmul u2( + .clk(clk), + .fpu_op(fpu_op_r1), + .opa(opa_r), .opb(opb_r), + .fracta(fracta_mul), + .fractb(fractb_mul), + .exp_out(exp_mul), // FMUL exponent output (registered) + .sign(sign_mul), // FMUL sign output (registered) + .sign_exe(sign_exe), // FMUL exception sign output (registered) + .inf(inf_mul), // FMUL inf output (registered) + .exp_ovf(exp_ovf), // FMUL exponnent overflow output (registered) + .underflow(underflow_fmul_d) + ); + + +always @(posedge clk) + sign_mul_r <= #1 sign_mul; + +always @(posedge clk) + sign_exe_r <= #1 sign_exe; + +always @(posedge clk) + inf_mul_r <= #1 inf_mul; + +always @(posedge clk) + exp_ovf_r <= #1 exp_ovf; + + +//////////////////////////////////////////////////////////////////////// +// +// Add/Sub +// + +add_sub27 u3( + .add(fasu_op), // Add/Sub + .opa(fracta), // Fraction A input + .opb(fractb), // Fraction B Input + .sum(fract_out_d), // SUM output + .co(co_d) ); // Carry Output + +always @(posedge clk) + fract_out_q <= #1 {co_d, fract_out_d}; + +//////////////////////////////////////////////////////////////////////// +// +// Mul +// +wire [47:0] prod; + +mul_r2 u5(.clk(clk), .opa(fracta_mul), .opb(fractb_mul), .prod(prod)); + +//////////////////////////////////////////////////////////////////////// +// +// Divide +// +wire [49:0] quo; +wire [49:0] fdiv_opa; +wire [49:0] remainder; +wire remainder_00; +reg [4:0] div_opa_ldz_d, div_opa_ldz_r1, div_opa_ldz_r2; + +always @(fracta_mul) + casex(fracta_mul[22:0]) + 23'b1??????????????????????: div_opa_ldz_d = 1; + 23'b01?????????????????????: div_opa_ldz_d = 2; + 23'b001????????????????????: div_opa_ldz_d = 3; + 23'b0001???????????????????: div_opa_ldz_d = 4; + 23'b00001??????????????????: div_opa_ldz_d = 5; + 23'b000001?????????????????: div_opa_ldz_d = 6; + 23'b0000001????????????????: div_opa_ldz_d = 7; + 23'b00000001???????????????: div_opa_ldz_d = 8; + 23'b000000001??????????????: div_opa_ldz_d = 9; + 23'b0000000001?????????????: div_opa_ldz_d = 10; + 23'b00000000001????????????: div_opa_ldz_d = 11; + 23'b000000000001???????????: div_opa_ldz_d = 12; + 23'b0000000000001??????????: div_opa_ldz_d = 13; + 23'b00000000000001?????????: div_opa_ldz_d = 14; + 23'b000000000000001????????: div_opa_ldz_d = 15; + 23'b0000000000000001???????: div_opa_ldz_d = 16; + 23'b00000000000000001??????: div_opa_ldz_d = 17; + 23'b000000000000000001?????: div_opa_ldz_d = 18; + 23'b0000000000000000001????: div_opa_ldz_d = 19; + 23'b00000000000000000001???: div_opa_ldz_d = 20; + 23'b000000000000000000001??: div_opa_ldz_d = 21; + 23'b0000000000000000000001?: div_opa_ldz_d = 22; + 23'b0000000000000000000000?: div_opa_ldz_d = 23; + endcase + +assign fdiv_opa = !(|opa_r[30:23]) ? {(fracta_mul<<div_opa_ldz_d), 26'h0} : {fracta_mul, 26'h0}; + + +div_r2 u6(.clk(clk), .opa(fdiv_opa), .opb(fractb_mul), .quo(quo), .rem(remainder)); + +assign remainder_00 = !(|remainder); + +always @(posedge clk) + div_opa_ldz_r1 <= #1 div_opa_ldz_d; + +always @(posedge clk) + div_opa_ldz_r2 <= #1 div_opa_ldz_r1; + + +//////////////////////////////////////////////////////////////////////// +// +// Normalize Result +// +wire ine_d; +reg [47:0] fract_denorm; +wire [47:0] fract_div; +wire sign_d; +reg sign; +reg [30:0] opa_r1; +reg [47:0] fract_i2f; +reg opas_r1, opas_r2; +wire f2i_out_sign; + +always @(posedge clk) // Exponent must be once cycle delayed + case(fpu_op_r2) + 0,1: exp_r <= #1 exp_fasu; + 2,3: exp_r <= #1 exp_mul; + 4: exp_r <= #1 0; + 5: exp_r <= #1 opa_r1[30:23]; + endcase + +assign fract_div = (opb_dn ? quo[49:2] : {quo[26:0], 21'h0}); + +always @(posedge clk) + opa_r1 <= #1 opa_r[30:0]; + +always @(posedge clk) + fract_i2f <= #1 (fpu_op_r2==5) ? + (sign_d ? 1-{24'h00, (|opa_r1[30:23]), opa_r1[22:0]}-1 : {24'h0, (|opa_r1[30:23]), opa_r1[22:0]}) : + (sign_d ? 1 - {opa_r1, 17'h01} : {opa_r1, 17'h0}); + +always @(fpu_op_r3 or fract_out_q or prod or fract_div or fract_i2f) + case(fpu_op_r3) + 0,1: fract_denorm = {fract_out_q, 20'h0}; + 2: fract_denorm = prod; + 3: fract_denorm = fract_div; + 4,5: fract_denorm = fract_i2f; + endcase + + +always @(posedge clk) + opas_r1 <= #1 opa_r[31]; + +always @(posedge clk) + opas_r2 <= #1 opas_r1; + +assign sign_d = fpu_op_r2[1] ? sign_mul : sign_fasu; + +always @(posedge clk) + sign <= #1 (rmode_r2==2'h3) ? !sign_d : sign_d; + +post_norm u4(.clk(clk), // System Clock + .fpu_op(fpu_op_r3), // Floating Point Operation + .opas(opas_r2), // OPA Sign + .sign(sign), // Sign of the result + .rmode(rmode_r3), // Rounding mode + .fract_in(fract_denorm), // Fraction Input + .exp_ovf(exp_ovf_r), // Exponent Overflow + .exp_in(exp_r), // Exponent Input + .opa_dn(opa_dn), // Operand A Denormalized + .opb_dn(opb_dn), // Operand A Denormalized + .rem_00(remainder_00), // Diveide Remainder is zero + .div_opa_ldz(div_opa_ldz_r2), // Divide opa leading zeros count + .output_zero(mul_00 | div_00), // Force output to Zero + .out(out_d), // Normalized output (un-registered) + .ine(ine_d), // Result Inexact output (un-registered) + .overflow(overflow_d), // Overflow output (un-registered) + .underflow(underflow_d), // Underflow output (un-registered) + .f2i_out_sign(f2i_out_sign) // F2I Output Sign + ); + +//////////////////////////////////////////////////////////////////////// +// +// FPU Outputs +// +reg fasu_op_r1, fasu_op_r2; +wire [30:0] out_fixed; +wire output_zero_fasu; +wire output_zero_fdiv; +wire output_zero_fmul; +reg inf_mul2; +wire overflow_fasu; +wire overflow_fmul; +wire overflow_fdiv; +wire inf_fmul; +wire sign_mul_final; +wire out_d_00; +wire sign_div_final; +wire ine_mul, ine_mula, ine_div, ine_fasu; +wire underflow_fasu, underflow_fmul, underflow_fdiv; +wire underflow_fmul1; +reg [2:0] underflow_fmul_r; +reg opa_nan_r; + + +always @(posedge clk) + fasu_op_r1 <= #1 fasu_op; + +always @(posedge clk) + fasu_op_r2 <= #1 fasu_op_r1; + +always @(posedge clk) + inf_mul2 <= #1 exp_mul == 8'hff; + + +// Force pre-set values for non numerical output +assign mul_inf = (fpu_op_r3==3'b010) & (inf_mul_r | inf_mul2) & (rmode_r3==2'h0); +assign div_inf = (fpu_op_r3==3'b011) & (opb_00 | opa_inf); + +assign mul_00 = (fpu_op_r3==3'b010) & (opa_00 | opb_00); +assign div_00 = (fpu_op_r3==3'b011) & (opa_00 | opb_inf); + +assign out_fixed = ( (qnan_d | snan_d) | + (ind_d & !fasu_op_r2) | + ((fpu_op_r3==3'b011) & opb_00 & opa_00) | + (((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3==3'b010) + ) ? QNAN : INF; + +always @(posedge clk) + out[30:0] <= #1 (mul_inf | div_inf | (inf_d & (fpu_op_r3!=3'b011) & (fpu_op_r3!=3'b101)) | snan_d | qnan_d) & fpu_op_r3!=3'b100 ? out_fixed : + out_d; + +assign out_d_00 = !(|out_d); + +assign sign_mul_final = (sign_exe_r & ((opa_00 & opb_inf) | (opb_00 & opa_inf))) ? !sign_mul_r : sign_mul_r; +assign sign_div_final = (sign_exe_r & (opa_inf & opb_inf)) ? !sign_mul_r : sign_mul_r | (opa_00 & opb_00); + +always @(posedge clk) + out[31] <= #1 ((fpu_op_r3==3'b101) & out_d_00) ? (f2i_out_sign & !(qnan_d | snan_d) ) : + ((fpu_op_r3==3'b010) & !(snan_d | qnan_d)) ? sign_mul_final : + ((fpu_op_r3==3'b011) & !(snan_d | qnan_d)) ? sign_div_final : + (snan_d | qnan_d | ind_d) ? nan_sign_d : + output_zero_fasu ? result_zero_sign_d : + sign_fasu_r; + +// Exception Outputs +assign ine_mula = ((inf_mul_r | inf_mul2 | opa_inf | opb_inf) & (rmode_r3==2'h1) & + !((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3[1]); + +assign ine_mul = (ine_mula | ine_d | inf_fmul | out_d_00 | overflow_d | underflow_d) & + !opa_00 & !opb_00 & !(snan_d | qnan_d | inf_d); +assign ine_div = (ine_d | overflow_d | underflow_d) & !(opb_00 | snan_d | qnan_d | inf_d); +assign ine_fasu = (ine_d | overflow_d | underflow_d) & !(snan_d | qnan_d | inf_d); + +always @(posedge clk) + ine <= #1 fpu_op_r3[2] ? ine_d : + !fpu_op_r3[1] ? ine_fasu : + fpu_op_r3[0] ? ine_div : ine_mul; + + +assign overflow_fasu = overflow_d & !(snan_d | qnan_d | inf_d); +assign overflow_fmul = !inf_d & (inf_mul_r | inf_mul2 | overflow_d) & !(snan_d | qnan_d); +assign overflow_fdiv = (overflow_d & !(opb_00 | inf_d | snan_d | qnan_d)); + +always @(posedge clk) + overflow <= #1 fpu_op_r3[2] ? 0 : + !fpu_op_r3[1] ? overflow_fasu : + fpu_op_r3[0] ? overflow_fdiv : overflow_fmul; + +always @(posedge clk) + underflow_fmul_r <= #1 underflow_fmul_d; + + +assign underflow_fmul1 = underflow_fmul_r[0] | + (underflow_fmul_r[1] & underflow_d ) | + ((opa_dn | opb_dn) & out_d_00 & (prod!=0) & sign) | + (underflow_fmul_r[2] & ((out_d[30:23]==0) | (out_d[22:0]==0))); + +assign underflow_fasu = underflow_d & !(inf_d | snan_d | qnan_d); +assign underflow_fmul = underflow_fmul1 & !(snan_d | qnan_d | inf_mul_r); +assign underflow_fdiv = underflow_fasu & !opb_00; + +always @(posedge clk) + underflow <= #1 fpu_op_r3[2] ? 0 : + !fpu_op_r3[1] ? underflow_fasu : + fpu_op_r3[0] ? underflow_fdiv : underflow_fmul; + +always @(posedge clk) + snan <= #1 snan_d; + +// synopsys translate_off +wire mul_uf_del; +wire uf2_del, ufb2_del, ufc2_del, underflow_d_del; +wire co_del; +wire [30:0] out_d_del; +wire ov_fasu_del, ov_fmul_del; +wire [2:0] fop; +wire [4:0] ldza_del; +wire [49:0] quo_del; + +delay1 #0 ud000(clk, underflow_fmul1, mul_uf_del); +delay1 #0 ud001(clk, underflow_fmul_r[0], uf2_del); +delay1 #0 ud002(clk, underflow_fmul_r[1], ufb2_del); +delay1 #0 ud003(clk, underflow_d, underflow_d_del); +delay1 #0 ud004(clk, test.u0.u4.exp_out1_co, co_del); +delay1 #0 ud005(clk, underflow_fmul_r[2], ufc2_del); +delay1 #30 ud006(clk, out_d, out_d_del); + +delay1 #0 ud007(clk, overflow_fasu, ov_fasu_del); +delay1 #0 ud008(clk, overflow_fmul, ov_fmul_del); + +delay1 #2 ud009(clk, fpu_op_r3, fop); + +delay3 #4 ud010(clk, div_opa_ldz_d, ldza_del); + +delay1 #49 ud012(clk, quo, quo_del); + +always @(test.error_event) + begin + #0.2 + $display("muf: %b uf0: %b uf1: %b uf2: %b, tx0: %b, co: %b, out_d: %h (%h %h), ov_fasu: %b, ov_fmul: %b, fop: %h", + mul_uf_del, uf2_del, ufb2_del, ufc2_del, underflow_d_del, co_del, out_d_del, out_d_del[30:23], out_d_del[22:0], + ov_fasu_del, ov_fmul_del, fop ); + $display("ldza: %h, quo: %b", + ldza_del, quo_del); + end +// synopsys translate_on + + + +// Status Outputs +always @(posedge clk) + qnan <= #1 fpu_op_r3[2] ? 0 : ( + snan_d | qnan_d | (ind_d & !fasu_op_r2) | + (opa_00 & opb_00 & fpu_op_r3==3'b011) | + (((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3==3'b010) + ); + +assign inf_fmul = (((inf_mul_r | inf_mul2) & (rmode_r3==2'h0)) | opa_inf | opb_inf) & + !((opa_inf & opb_00) | (opb_inf & opa_00 )) & + fpu_op_r3==3'b010; + +always @(posedge clk) + inf <= #1 fpu_op_r3[2] ? 0 : + (!(qnan_d | snan_d) & ( + ((&out_d[30:23]) & !(|out_d[22:0]) & !(opb_00 & fpu_op_r3==3'b011)) | + (inf_d & !(ind_d & !fasu_op_r2) & !fpu_op_r3[1]) | + inf_fmul | + (!opa_00 & opb_00 & fpu_op_r3==3'b011) | + (fpu_op_r3==3'b011 & opa_inf & !opb_inf) + ) + ); + +assign output_zero_fasu = out_d_00 & !(inf_d | snan_d | qnan_d); +assign output_zero_fdiv = (div_00 | (out_d_00 & !opb_00)) & !(opa_inf & opb_inf) & + !(opa_00 & opb_00) & !(qnan_d | snan_d); +assign output_zero_fmul = (out_d_00 | opa_00 | opb_00) & + !(inf_mul_r | inf_mul2 | opa_inf | opb_inf | snan_d | qnan_d) & + !(opa_inf & opb_00) & !(opb_inf & opa_00); + +always @(posedge clk) + zero <= #1 fpu_op_r3==3'b101 ? out_d_00 & !(snan_d | qnan_d): + fpu_op_r3==3'b011 ? output_zero_fdiv : + fpu_op_r3==3'b010 ? output_zero_fmul : + output_zero_fasu ; + +always @(posedge clk) + opa_nan_r <= #1 !opa_nan & fpu_op_r2==3'b011; + +always @(posedge clk) + div_by_zero <= #1 opa_nan_r & !opa_00 & !opa_inf & opb_00; + +endmodule diff --git a/tests/iwls2005/fpu/post_norm.v b/tests/iwls2005/fpu/post_norm.v new file mode 100644 index 00000000..ff9cf6fb --- /dev/null +++ b/tests/iwls2005/fpu/post_norm.v @@ -0,0 +1,676 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// Post Norm //// +//// Floating Point Post Normalisation Unit //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + + +`timescale 1ns / 100ps + +module post_norm( clk, fpu_op, opas, sign, rmode, fract_in, exp_in, exp_ovf, + opa_dn, opb_dn, rem_00, div_opa_ldz, output_zero, out, + ine, overflow, underflow, f2i_out_sign); +input clk; +input [2:0] fpu_op; +input opas; +input sign; +input [1:0] rmode; +input [47:0] fract_in; +input [1:0] exp_ovf; +input [7:0] exp_in; +input opa_dn, opb_dn; +input rem_00; +input [4:0] div_opa_ldz; +input output_zero; +output [30:0] out; +output ine; +output overflow, underflow; +output f2i_out_sign; + +//////////////////////////////////////////////////////////////////////// +// +// Local Wires and registers +// + +wire [22:0] fract_out; +wire [7:0] exp_out; +wire [30:0] out; +wire exp_out1_co, overflow, underflow; +wire [22:0] fract_out_final; +reg [22:0] fract_out_rnd; +wire [8:0] exp_next_mi; +wire dn; +wire exp_rnd_adj; +wire [7:0] exp_out_final; +reg [7:0] exp_out_rnd; +wire op_dn = opa_dn | opb_dn; +wire op_mul = fpu_op[2:0]==3'b010; +wire op_div = fpu_op[2:0]==3'b011; +wire op_i2f = fpu_op[2:0]==3'b100; +wire op_f2i = fpu_op[2:0]==3'b101; +reg [5:0] fi_ldz; + +wire g, r, s; +wire round, round2, round2a, round2_fasu, round2_fmul; +wire [7:0] exp_out_rnd0, exp_out_rnd1, exp_out_rnd2, exp_out_rnd2a; +wire [22:0] fract_out_rnd0, fract_out_rnd1, fract_out_rnd2, fract_out_rnd2a; +wire exp_rnd_adj0, exp_rnd_adj2a; +wire r_sign; +wire ovf0, ovf1; +wire [23:0] fract_out_pl1; +wire [7:0] exp_out_pl1, exp_out_mi1; +wire exp_out_00, exp_out_fe, exp_out_ff, exp_in_00, exp_in_ff; +wire exp_out_final_ff, fract_out_7fffff; +wire [24:0] fract_trunc; +wire [7:0] exp_out1; +wire grs_sel; +wire fract_out_00, fract_in_00; +wire shft_co; +wire [8:0] exp_in_pl1, exp_in_mi1; +wire [47:0] fract_in_shftr; +wire [47:0] fract_in_shftl; + +wire [7:0] exp_div; +wire [7:0] shft2; +wire [7:0] exp_out1_mi1; +wire div_dn; +wire div_nr; +wire grs_sel_div; + +wire div_inf; +wire [6:0] fi_ldz_2a; +wire [7:0] fi_ldz_2; +wire [7:0] div_shft1, div_shft2, div_shft3, div_shft4; +wire div_shft1_co; +wire [8:0] div_exp1; +wire [7:0] div_exp2, div_exp3; +wire left_right, lr_mul, lr_div; +wire [7:0] shift_right, shftr_mul, shftr_div; +wire [7:0] shift_left, shftl_mul, shftl_div; +wire [7:0] fasu_shift; +wire [7:0] exp_fix_div; + +wire [7:0] exp_fix_diva, exp_fix_divb; +wire [5:0] fi_ldz_mi1; +wire [5:0] fi_ldz_mi22; +wire exp_zero; +wire [6:0] ldz_all; +wire [7:0] ldz_dif; + +wire [8:0] div_scht1a; +wire [7:0] f2i_shft; +wire [55:0] exp_f2i_1; +wire f2i_zero, f2i_max; +wire [7:0] f2i_emin; +wire [7:0] conv_shft; +wire [7:0] exp_i2f, exp_f2i, conv_exp; +wire round2_f2i; + +//////////////////////////////////////////////////////////////////////// +// +// Normalize and Round Logic +// + +// --------------------------------------------------------------------- +// Count Leading zeros in fraction + +always @(fract_in) + casex(fract_in) // synopsys full_case parallel_case + 48'b1???????????????????????????????????????????????: fi_ldz = 1; + 48'b01??????????????????????????????????????????????: fi_ldz = 2; + 48'b001?????????????????????????????????????????????: fi_ldz = 3; + 48'b0001????????????????????????????????????????????: fi_ldz = 4; + 48'b00001???????????????????????????????????????????: fi_ldz = 5; + 48'b000001??????????????????????????????????????????: fi_ldz = 6; + 48'b0000001?????????????????????????????????????????: fi_ldz = 7; + 48'b00000001????????????????????????????????????????: fi_ldz = 8; + 48'b000000001???????????????????????????????????????: fi_ldz = 9; + 48'b0000000001??????????????????????????????????????: fi_ldz = 10; + 48'b00000000001?????????????????????????????????????: fi_ldz = 11; + 48'b000000000001????????????????????????????????????: fi_ldz = 12; + 48'b0000000000001???????????????????????????????????: fi_ldz = 13; + 48'b00000000000001??????????????????????????????????: fi_ldz = 14; + 48'b000000000000001?????????????????????????????????: fi_ldz = 15; + 48'b0000000000000001????????????????????????????????: fi_ldz = 16; + 48'b00000000000000001???????????????????????????????: fi_ldz = 17; + 48'b000000000000000001??????????????????????????????: fi_ldz = 18; + 48'b0000000000000000001?????????????????????????????: fi_ldz = 19; + 48'b00000000000000000001????????????????????????????: fi_ldz = 20; + 48'b000000000000000000001???????????????????????????: fi_ldz = 21; + 48'b0000000000000000000001??????????????????????????: fi_ldz = 22; + 48'b00000000000000000000001?????????????????????????: fi_ldz = 23; + 48'b000000000000000000000001????????????????????????: fi_ldz = 24; + 48'b0000000000000000000000001???????????????????????: fi_ldz = 25; + 48'b00000000000000000000000001??????????????????????: fi_ldz = 26; + 48'b000000000000000000000000001?????????????????????: fi_ldz = 27; + 48'b0000000000000000000000000001????????????????????: fi_ldz = 28; + 48'b00000000000000000000000000001???????????????????: fi_ldz = 29; + 48'b000000000000000000000000000001??????????????????: fi_ldz = 30; + 48'b0000000000000000000000000000001?????????????????: fi_ldz = 31; + 48'b00000000000000000000000000000001????????????????: fi_ldz = 32; + 48'b000000000000000000000000000000001???????????????: fi_ldz = 33; + 48'b0000000000000000000000000000000001??????????????: fi_ldz = 34; + 48'b00000000000000000000000000000000001?????????????: fi_ldz = 35; + 48'b000000000000000000000000000000000001????????????: fi_ldz = 36; + 48'b0000000000000000000000000000000000001???????????: fi_ldz = 37; + 48'b00000000000000000000000000000000000001??????????: fi_ldz = 38; + 48'b000000000000000000000000000000000000001?????????: fi_ldz = 39; + 48'b0000000000000000000000000000000000000001????????: fi_ldz = 40; + 48'b00000000000000000000000000000000000000001???????: fi_ldz = 41; + 48'b000000000000000000000000000000000000000001??????: fi_ldz = 42; + 48'b0000000000000000000000000000000000000000001?????: fi_ldz = 43; + 48'b00000000000000000000000000000000000000000001????: fi_ldz = 44; + 48'b000000000000000000000000000000000000000000001???: fi_ldz = 45; + 48'b0000000000000000000000000000000000000000000001??: fi_ldz = 46; + 48'b00000000000000000000000000000000000000000000001?: fi_ldz = 47; + 48'b00000000000000000000000000000000000000000000000?: fi_ldz = 48; + endcase + + +// --------------------------------------------------------------------- +// Normalize + +wire exp_in_80; +wire rmode_00, rmode_01, rmode_10, rmode_11; + +// Misc common signals +assign exp_in_ff = &exp_in; +assign exp_in_00 = !(|exp_in); +assign exp_in_80 = exp_in[7] & !(|exp_in[6:0]); +assign exp_out_ff = &exp_out; +assign exp_out_00 = !(|exp_out); +assign exp_out_fe = &exp_out[7:1] & !exp_out[0]; +assign exp_out_final_ff = &exp_out_final; + +assign fract_out_7fffff = &fract_out; +assign fract_out_00 = !(|fract_out); +assign fract_in_00 = !(|fract_in); + +assign rmode_00 = (rmode==2'b00); +assign rmode_01 = (rmode==2'b01); +assign rmode_10 = (rmode==2'b10); +assign rmode_11 = (rmode==2'b11); + +// Fasu Output will be denormalized ... +assign dn = !op_mul & !op_div & (exp_in_00 | (exp_next_mi[8] & !fract_in[47]) ); + +// --------------------------------------------------------------------- +// Fraction Normalization +parameter f2i_emax = 8'h9d; + +// Incremented fraction for rounding +assign fract_out_pl1 = fract_out + 1; + +// Special Signals for f2i +assign f2i_emin = rmode_00 ? 8'h7e : 8'h7f; +assign f2i_zero = (!opas & (exp_in<f2i_emin)) | (opas & (exp_in>f2i_emax)) | (opas & (exp_in<f2i_emin) & (fract_in_00 | !rmode_11)); +assign f2i_max = (!opas & (exp_in>f2i_emax)) | (opas & (exp_in<f2i_emin) & !fract_in_00 & rmode_11); + +// Claculate various shifting options + +assign {shft_co,shftr_mul} = (!exp_ovf[1] & exp_in_00) ? {1'b0, exp_out} : exp_in_mi1 ; +assign {div_shft1_co, div_shft1} = exp_in_00 ? {1'b0, div_opa_ldz} : div_scht1a; + +assign div_scht1a = exp_in-div_opa_ldz; // 9 bits - includes carry out +assign div_shft2 = exp_in+2; +assign div_shft3 = div_opa_ldz+exp_in; +assign div_shft4 = div_opa_ldz-exp_in; + +assign div_dn = op_dn & div_shft1_co; +assign div_nr = op_dn & exp_ovf[1] & !(|fract_in[46:23]) & (div_shft3>8'h16); + +assign f2i_shft = exp_in-8'h7d; + +// Select shifting direction +assign left_right = op_div ? lr_div : op_mul ? lr_mul : 1; + +assign lr_div = (op_dn & !exp_ovf[1] & exp_ovf[0]) ? 1 : + (op_dn & exp_ovf[1]) ? 0 : + (op_dn & div_shft1_co) ? 0 : + (op_dn & exp_out_00) ? 1 : + (!op_dn & exp_out_00 & !exp_ovf[1]) ? 1 : + exp_ovf[1] ? 0 : + 1; +assign lr_mul = (shft_co | (!exp_ovf[1] & exp_in_00) | + (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00) )) ? 1 : + ( exp_ovf[1] | exp_in_00 ) ? 0 : + 1; + +// Select Left and Right shift value +assign fasu_shift = (dn | exp_out_00) ? (exp_in_00 ? 8'h2 : exp_in_pl1[7:0]) : {2'h0, fi_ldz}; +assign shift_right = op_div ? shftr_div : shftr_mul; + +assign conv_shft = op_f2i ? f2i_shft : {2'h0, fi_ldz}; + +assign shift_left = op_div ? shftl_div : op_mul ? shftl_mul : (op_f2i | op_i2f) ? conv_shft : fasu_shift; + +assign shftl_mul = (shft_co | + (!exp_ovf[1] & exp_in_00) | + (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00))) ? exp_in_pl1[7:0] : {2'h0, fi_ldz}; + +assign shftl_div = ( op_dn & exp_out_00 & !(!exp_ovf[1] & exp_ovf[0])) ? div_shft1[7:0] : + (!op_dn & exp_out_00 & !exp_ovf[1]) ? exp_in[7:0] : + {2'h0, fi_ldz}; +assign shftr_div = (op_dn & exp_ovf[1]) ? div_shft3 : + (op_dn & div_shft1_co) ? div_shft4 : + div_shft2; +// Do the actual shifting +assign fract_in_shftr = (|shift_right[7:6]) ? 0 : fract_in>>shift_right[5:0]; +assign fract_in_shftl = (|shift_left[7:6] | (f2i_zero & op_f2i)) ? 0 : fract_in<<shift_left[5:0]; + +// Chose final fraction output +assign {fract_out,fract_trunc} = left_right ? fract_in_shftl : fract_in_shftr; + +// --------------------------------------------------------------------- +// Exponent Normalization + +assign fi_ldz_mi1 = fi_ldz - 1; +assign fi_ldz_mi22 = fi_ldz - 22; +assign exp_out_pl1 = exp_out + 1; +assign exp_out_mi1 = exp_out - 1; +assign exp_in_pl1 = exp_in + 1; // 9 bits - includes carry out +assign exp_in_mi1 = exp_in - 1; // 9 bits - includes carry out +assign exp_out1_mi1 = exp_out1 - 1; + +assign exp_next_mi = exp_in_pl1 - fi_ldz_mi1; // 9 bits - includes carry out + +assign exp_fix_diva = exp_in - fi_ldz_mi22; +assign exp_fix_divb = exp_in - fi_ldz_mi1; + +assign exp_zero = (exp_ovf[1] & !exp_ovf[0] & op_mul & (!exp_rnd_adj2a | !rmode[1])) | (op_mul & exp_out1_co); +assign {exp_out1_co, exp_out1} = fract_in[47] ? exp_in_pl1 : exp_next_mi; + +assign f2i_out_sign = !opas ? ((exp_in<f2i_emin) ? 0 : (exp_in>f2i_emax) ? 0 : opas) : + ((exp_in<f2i_emin) ? 0 : (exp_in>f2i_emax) ? 1 : opas); + +assign exp_i2f = fract_in_00 ? (opas ? 8'h9e : 0) : (8'h9e-fi_ldz); +assign exp_f2i_1 = {{8{fract_in[47]}}, fract_in }<<f2i_shft; +assign exp_f2i = f2i_zero ? 0 : f2i_max ? 8'hff : exp_f2i_1[55:48]; +assign conv_exp = op_f2i ? exp_f2i : exp_i2f; + +assign exp_out = op_div ? exp_div : (op_f2i | op_i2f) ? conv_exp : exp_zero ? 8'h0 : dn ? {6'h0, fract_in[47:46]} : exp_out1; + +assign ldz_all = div_opa_ldz + fi_ldz; +assign ldz_dif = fi_ldz_2 - div_opa_ldz; +assign fi_ldz_2a = 6'd23 - fi_ldz; +assign fi_ldz_2 = {fi_ldz_2a[6], fi_ldz_2a[6:0]}; + +assign div_exp1 = exp_in_mi1 + fi_ldz_2; // 9 bits - includes carry out + +assign div_exp2 = exp_in_pl1 - ldz_all; +assign div_exp3 = exp_in + ldz_dif; + +assign exp_div =(opa_dn & opb_dn) ? div_exp3 : + opb_dn ? div_exp1[7:0] : + (opa_dn & !( (exp_in<div_opa_ldz) | (div_exp2>9'hfe) )) ? div_exp2 : + (opa_dn | (exp_in_00 & !exp_ovf[1]) ) ? 0 : + exp_out1_mi1; + +assign div_inf = opb_dn & !opa_dn & (div_exp1[7:0] < 8'h7f); + +// --------------------------------------------------------------------- +// Round + +// Extract rounding (GRS) bits +assign grs_sel_div = op_div & (exp_ovf[1] | div_dn | exp_out1_co | exp_out_00); + +assign g = grs_sel_div ? fract_out[0] : fract_out[0]; +assign r = grs_sel_div ? (fract_trunc[24] & !div_nr) : fract_trunc[24]; +assign s = grs_sel_div ? |fract_trunc[24:0] : (|fract_trunc[23:0] | (fract_trunc[24] & op_div)); + +// Round to nearest even +assign round = (g & r) | (r & s) ; +assign {exp_rnd_adj0, fract_out_rnd0} = round ? fract_out_pl1 : {1'b0, fract_out}; +assign exp_out_rnd0 = exp_rnd_adj0 ? exp_out_pl1 : exp_out; +assign ovf0 = exp_out_final_ff & !rmode_01 & !op_f2i; + +// round to zero +assign fract_out_rnd1 = (exp_out_ff & !op_div & !dn & !op_f2i) ? 23'h7fffff : fract_out; +assign exp_fix_div = (fi_ldz>22) ? exp_fix_diva : exp_fix_divb; +assign exp_out_rnd1 = (g & r & s & exp_in_ff) ? (op_div ? exp_fix_div : exp_next_mi[7:0]) : + (exp_out_ff & !op_f2i) ? exp_in : exp_out; +assign ovf1 = exp_out_ff & !dn; + +// round to +inf (UP) and -inf (DOWN) +assign r_sign = sign; + +assign round2a = !exp_out_fe | !fract_out_7fffff | (exp_out_fe & fract_out_7fffff); +assign round2_fasu = ((r | s) & !r_sign) & (!exp_out[7] | (exp_out[7] & round2a)); + +assign round2_fmul = !r_sign & + ( + (exp_ovf[1] & !fract_in_00 & + ( ((!exp_out1_co | op_dn) & (r | s | (!rem_00 & op_div) )) | fract_out_00 | (!op_dn & !op_div)) + ) | + ( + (r | s | (!rem_00 & op_div)) & ( + (!exp_ovf[1] & (exp_in_80 | !exp_ovf[0])) | op_div | + ( exp_ovf[1] & !exp_ovf[0] & exp_out1_co) + ) + ) + ); + +assign round2_f2i = rmode_10 & (( |fract_in[23:0] & !opas & (exp_in<8'h80 )) | (|fract_trunc)); +assign round2 = (op_mul | op_div) ? round2_fmul : op_f2i ? round2_f2i : round2_fasu; + +assign {exp_rnd_adj2a, fract_out_rnd2a} = round2 ? fract_out_pl1 : {1'b0, fract_out}; +assign exp_out_rnd2a = exp_rnd_adj2a ? ((exp_ovf[1] & op_mul) ? exp_out_mi1 : exp_out_pl1) : exp_out; + +assign fract_out_rnd2 = (r_sign & exp_out_ff & !op_div & !dn & !op_f2i) ? 23'h7fffff : fract_out_rnd2a; +assign exp_out_rnd2 = (r_sign & exp_out_ff & !op_f2i) ? 8'hfe : exp_out_rnd2a; + + +// Choose rounding mode +always @(rmode or exp_out_rnd0 or exp_out_rnd1 or exp_out_rnd2) + case(rmode) // synopsys full_case parallel_case + 0: exp_out_rnd = exp_out_rnd0; + 1: exp_out_rnd = exp_out_rnd1; + 2,3: exp_out_rnd = exp_out_rnd2; + endcase + +always @(rmode or fract_out_rnd0 or fract_out_rnd1 or fract_out_rnd2) + case(rmode) // synopsys full_case parallel_case + 0: fract_out_rnd = fract_out_rnd0; + 1: fract_out_rnd = fract_out_rnd1; + 2,3: fract_out_rnd = fract_out_rnd2; + endcase + +// --------------------------------------------------------------------- +// Final Output Mux +// Fix Output for denormalized and special numbers +wire max_num, inf_out; + +assign max_num = ( !rmode_00 & (op_mul | op_div ) & ( + ( exp_ovf[1] & exp_ovf[0]) | + (!exp_ovf[1] & !exp_ovf[0] & exp_in_ff & (fi_ldz_2<24) & (exp_out!=8'hfe) ) + ) + ) | + + ( op_div & ( + ( rmode_01 & ( div_inf | + (exp_out_ff & !exp_ovf[1] ) | + (exp_ovf[1] & exp_ovf[0] ) + ) + ) | + + ( rmode[1] & !exp_ovf[1] & ( + ( exp_ovf[0] & exp_in_ff & r_sign & fract_in[47] + ) | + + ( r_sign & ( + (fract_in[47] & div_inf) | + (exp_in[7] & !exp_out_rnd[7] & !exp_in_80 & exp_out!=8'h7f ) | + (exp_in[7] & exp_out_rnd[7] & r_sign & exp_out_ff & op_dn & + div_exp1>9'h0fe ) + ) + ) | + + ( exp_in_00 & r_sign & ( + div_inf | + (r_sign & exp_out_ff & fi_ldz_2<24) + ) + ) + ) + ) + ) + ); + + +assign inf_out = (rmode[1] & (op_mul | op_div) & !r_sign & ( (exp_in_ff & !op_div) | + (exp_ovf[1] & exp_ovf[0] & (exp_in_00 | exp_in[7]) ) + ) + ) | (div_inf & op_div & ( + rmode_00 | + (rmode[1] & !exp_in_ff & !exp_ovf[1] & !exp_ovf[0] & !r_sign ) | + (rmode[1] & !exp_ovf[1] & exp_ovf[0] & exp_in_00 & !r_sign) + ) + ) | (op_div & rmode[1] & exp_in_ff & op_dn & !r_sign & (fi_ldz_2 < 24) & (exp_out_rnd!=8'hfe) ); + +assign fract_out_final = (inf_out | ovf0 | output_zero ) ? 23'h0 : + (max_num | (f2i_max & op_f2i) ) ? 23'h7fffff : + fract_out_rnd; + +assign exp_out_final = ((op_div & exp_ovf[1] & !exp_ovf[0]) | output_zero ) ? 8'h00 : + ((op_div & exp_ovf[1] & exp_ovf[0] & rmode_00) | inf_out | (f2i_max & op_f2i) ) ? 8'hff : + max_num ? 8'hfe : + exp_out_rnd; + + +// --------------------------------------------------------------------- +// Pack Result + +assign out = {exp_out_final, fract_out_final}; + +// --------------------------------------------------------------------- +// Exceptions +wire underflow_fmul; +wire overflow_fdiv; +wire undeflow_div; + +wire z = shft_co | ( exp_ovf[1] | exp_in_00) | + (!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00)); + +assign underflow_fmul = ( (|fract_trunc) & z & !exp_in_ff ) | + (fract_out_00 & !fract_in_00 & exp_ovf[1]); + +assign undeflow_div = !(exp_ovf[1] & exp_ovf[0] & rmode_00) & !inf_out & !max_num & exp_out_final!=8'hff & ( + + ((|fract_trunc) & !opb_dn & ( + ( op_dn & !exp_ovf[1] & exp_ovf[0]) | + ( op_dn & exp_ovf[1]) | + ( op_dn & div_shft1_co) | + exp_out_00 | + exp_ovf[1] + ) + + ) | + + ( exp_ovf[1] & !exp_ovf[0] & ( + ( op_dn & exp_in>8'h16 & fi_ldz<23) | + ( op_dn & exp_in<23 & fi_ldz<23 & !rem_00) | + ( !op_dn & (exp_in[7]==exp_div[7]) & !rem_00) | + ( !op_dn & exp_in_00 & (exp_div[7:1]==7'h7f) ) | + ( !op_dn & exp_in<8'h7f & exp_in>8'h20 ) + ) + ) | + + (!exp_ovf[1] & !exp_ovf[0] & ( + ( op_dn & fi_ldz<23 & exp_out_00) | + ( exp_in_00 & !rem_00) | + ( !op_dn & ldz_all<23 & exp_in==1 & exp_out_00 & !rem_00) + ) + ) + + ); + +assign underflow = op_div ? undeflow_div : op_mul ? underflow_fmul : (!fract_in[47] & exp_out1_co) & !dn; + +assign overflow_fdiv = inf_out | + (!rmode_00 & max_num) | + (exp_in[7] & op_dn & exp_out_ff) | + (exp_ovf[0] & (exp_ovf[1] | exp_out_ff) ); + +assign overflow = op_div ? overflow_fdiv : (ovf0 | ovf1); + +wire f2i_ine; + +assign f2i_ine = (f2i_zero & !fract_in_00 & !opas) | + (|fract_trunc) | + (f2i_zero & (exp_in<8'h80) & opas & !fract_in_00) | + (f2i_max & rmode_11 & (exp_in<8'h80)); + + + +assign ine = op_f2i ? f2i_ine : + op_i2f ? (|fract_trunc) : + ((r & !dn) | (s & !dn) | max_num | (op_div & !rem_00)); + +// --------------------------------------------------------------------- +// Debugging Stuff + +// synopsys translate_off + +wire [26:0] fracta_del, fractb_del; +wire [2:0] grs_del; +wire dn_del; +wire [7:0] exp_in_del; +wire [7:0] exp_out_del; +wire [22:0] fract_out_del; +wire [47:0] fract_in_del; +wire overflow_del; +wire [1:0] exp_ovf_del; +wire [22:0] fract_out_x_del, fract_out_rnd2a_del; +wire [24:0] trunc_xx_del; +wire exp_rnd_adj2a_del; +wire [22:0] fract_dn_del; +wire [4:0] div_opa_ldz_del; +wire [23:0] fracta_div_del; +wire [23:0] fractb_div_del; +wire div_inf_del; +wire [7:0] fi_ldz_2_del; +wire inf_out_del, max_out_del; +wire [5:0] fi_ldz_del; +wire rx_del; +wire ez_del; +wire lr; +wire [7:0] shr, shl, exp_div_del; + +delay2 #26 ud000(clk, test.u0.fracta, fracta_del); +delay2 #26 ud001(clk, test.u0.fractb, fractb_del); +delay1 #2 ud002(clk, {g,r,s}, grs_del); +delay1 #0 ud004(clk, dn, dn_del); +delay1 #7 ud005(clk, exp_in, exp_in_del); +delay1 #7 ud007(clk, exp_out_rnd, exp_out_del); +delay1 #47 ud009(clk, fract_in, fract_in_del); +delay1 #0 ud010(clk, overflow, overflow_del); +delay1 #1 ud011(clk, exp_ovf, exp_ovf_del); +delay1 #22 ud014(clk, fract_out, fract_out_x_del); +delay1 #24 ud015(clk, fract_trunc, trunc_xx_del); +delay1 #0 ud017(clk, exp_rnd_adj2a, exp_rnd_adj2a_del); +delay1 #4 ud019(clk, div_opa_ldz, div_opa_ldz_del); +delay3 #23 ud020(clk, test.u0.fdiv_opa[49:26], fracta_div_del); +delay3 #23 ud021(clk, test.u0.fractb_mul, fractb_div_del); +delay1 #0 ud023(clk, div_inf, div_inf_del); +delay1 #7 ud024(clk, fi_ldz_2, fi_ldz_2_del); +delay1 #0 ud025(clk, inf_out, inf_out_del); +delay1 #0 ud026(clk, max_num, max_num_del); +delay1 #5 ud027(clk, fi_ldz, fi_ldz_del); +delay1 #0 ud028(clk, rem_00, rx_del); + +delay1 #0 ud029(clk, left_right, lr); +delay1 #7 ud030(clk, shift_right, shr); +delay1 #7 ud031(clk, shift_left, shl); +delay1 #22 ud032(clk, fract_out_rnd2a, fract_out_rnd2a_del); + +delay1 #7 ud033(clk, exp_div, exp_div_del); + +always @(test.error_event) + begin + + $display("\n----------------------------------------------"); + + $display("ERROR: GRS: %b exp_ovf: %b dn: %h exp_in: %h exp_out: %h, exp_rnd_adj2a: %b", + grs_del, exp_ovf_del, dn_del, exp_in_del, exp_out_del, exp_rnd_adj2a_del); + + $display(" div_opa: %b, div_opb: %b, rem_00: %b, exp_div: %h", + fracta_div_del, fractb_div_del, rx_del, exp_div_del); + + $display(" lr: %b, shl: %h, shr: %h", + lr, shl, shr); + + + $display(" overflow: %b, fract_in=%b fa:%h fb:%h", + overflow_del, fract_in_del, fracta_del, fractb_del); + + $display(" div_opa_ldz: %h, div_inf: %b, inf_out: %b, max_num: %b, fi_ldz: %h, fi_ldz_2: %h", + div_opa_ldz_del, div_inf_del, inf_out_del, max_num_del, fi_ldz_del, fi_ldz_2_del); + + $display(" fract_out_x: %b, fract_out_rnd2a_del: %h, fract_trunc: %b\n", + fract_out_x_del, fract_out_rnd2a_del, trunc_xx_del); + end + + +// synopsys translate_on + +endmodule + +// synopsys translate_off + +module delay1(clk, in, out); +parameter N = 1; +input [N:0] in; +output [N:0] out; +input clk; + +reg [N:0] out; + +always @(posedge clk) + out <= #1 in; + +endmodule + + +module delay2(clk, in, out); +parameter N = 1; +input [N:0] in; +output [N:0] out; +input clk; + +reg [N:0] out, r1; + +always @(posedge clk) + r1 <= #1 in; + +always @(posedge clk) + out <= #1 r1; + +endmodule + +module delay3(clk, in, out); +parameter N = 1; +input [N:0] in; +output [N:0] out; +input clk; + +reg [N:0] out, r1, r2; + +always @(posedge clk) + r1 <= #1 in; + +always @(posedge clk) + r2 <= #1 r1; + +always @(posedge clk) + out <= #1 r2; + +endmodule + +// synopsys translate_on
\ No newline at end of file diff --git a/tests/iwls2005/fpu/pre_norm.v b/tests/iwls2005/fpu/pre_norm.v new file mode 100644 index 00000000..c54c71fa --- /dev/null +++ b/tests/iwls2005/fpu/pre_norm.v @@ -0,0 +1,270 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// Pre Normalize //// +//// Pre Normalization Unit for Add/Sub Operations //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +`timescale 1ns / 100ps + + +module pre_norm(clk, rmode, add, opa, opb, opa_nan, opb_nan, fracta_out, + fractb_out, exp_dn_out, sign, nan_sign, result_zero_sign, + fasu_op); +input clk; +input [1:0] rmode; +input add; +input [31:0] opa, opb; +input opa_nan, opb_nan; +output [26:0] fracta_out, fractb_out; +output [7:0] exp_dn_out; +output sign; +output nan_sign, result_zero_sign; +output fasu_op; // Operation Output + +//////////////////////////////////////////////////////////////////////// +// +// Local Wires and registers +// + +wire signa, signb; // alias to opX sign +wire [7:0] expa, expb; // alias to opX exponent +wire [22:0] fracta, fractb; // alias to opX fraction +wire expa_lt_expb; // expa is larger than expb indicator +wire fractb_lt_fracta; // fractb is larger than fracta indicator +reg [7:0] exp_dn_out; // de normalized exponent output +wire [7:0] exp_small, exp_large; +wire [7:0] exp_diff; // Numeric difference of the two exponents +wire [22:0] adj_op; // Fraction adjustment: input +wire [26:0] adj_op_tmp; +wire [26:0] adj_op_out; // Fraction adjustment: output +wire [26:0] fracta_n, fractb_n; // Fraction selection after normalizing +wire [26:0] fracta_s, fractb_s; // Fraction Sorting out +reg [26:0] fracta_out, fractb_out; // Fraction Output +reg sign, sign_d; // Sign Output +reg add_d; // operation (add/sub) +reg fasu_op; // operation (add/sub) register +wire expa_dn, expb_dn; +reg sticky; +reg result_zero_sign; +reg add_r, signa_r, signb_r; +wire [4:0] exp_diff_sft; +wire exp_lt_27; +wire op_dn; +wire [26:0] adj_op_out_sft; +reg fracta_lt_fractb, fracta_eq_fractb; +wire nan_sign1; +reg nan_sign; + +//////////////////////////////////////////////////////////////////////// +// +// Aliases +// + +assign signa = opa[31]; +assign signb = opb[31]; +assign expa = opa[30:23]; +assign expb = opb[30:23]; +assign fracta = opa[22:0]; +assign fractb = opb[22:0]; + +//////////////////////////////////////////////////////////////////////// +// +// Pre-Normalize exponents (and fractions) +// + +assign expa_lt_expb = expa > expb; // expa is larger than expb + +// --------------------------------------------------------------------- +// Normalize + +assign expa_dn = !(|expa); // opa denormalized +assign expb_dn = !(|expb); // opb denormalized + +// --------------------------------------------------------------------- +// Calculate the difference between the smaller and larger exponent + +wire [7:0] exp_diff1, exp_diff1a, exp_diff2; + +assign exp_small = expa_lt_expb ? expb : expa; +assign exp_large = expa_lt_expb ? expa : expb; +assign exp_diff1 = exp_large - exp_small; +assign exp_diff1a = exp_diff1-1; +assign exp_diff2 = (expa_dn | expb_dn) ? exp_diff1a : exp_diff1; +assign exp_diff = (expa_dn & expb_dn) ? 8'h0 : exp_diff2; + +always @(posedge clk) // If numbers are equal we should return zero + exp_dn_out <= #1 (!add_d & expa==expb & fracta==fractb) ? 8'h0 : exp_large; + +// --------------------------------------------------------------------- +// Adjust the smaller fraction + + +assign op_dn = expa_lt_expb ? expb_dn : expa_dn; +assign adj_op = expa_lt_expb ? fractb : fracta; +assign adj_op_tmp = { ~op_dn, adj_op, 3'b0 }; // recover hidden bit (op_dn) + +// adj_op_out is 27 bits wide, so can only be shifted 27 bits to the right +assign exp_lt_27 = exp_diff > 8'd27; +assign exp_diff_sft = exp_lt_27 ? 5'd27 : exp_diff[4:0]; +assign adj_op_out_sft = adj_op_tmp >> exp_diff_sft; +assign adj_op_out = {adj_op_out_sft[26:1], adj_op_out_sft[0] | sticky }; + +// --------------------------------------------------------------------- +// Get truncated portion (sticky bit) + +always @(exp_diff_sft or adj_op_tmp) + case(exp_diff_sft) // synopsys full_case parallel_case + 00: sticky = 1'h0; + 01: sticky = adj_op_tmp[0]; + 02: sticky = |adj_op_tmp[01:0]; + 03: sticky = |adj_op_tmp[02:0]; + 04: sticky = |adj_op_tmp[03:0]; + 05: sticky = |adj_op_tmp[04:0]; + 06: sticky = |adj_op_tmp[05:0]; + 07: sticky = |adj_op_tmp[06:0]; + 08: sticky = |adj_op_tmp[07:0]; + 09: sticky = |adj_op_tmp[08:0]; + 10: sticky = |adj_op_tmp[09:0]; + 11: sticky = |adj_op_tmp[10:0]; + 12: sticky = |adj_op_tmp[11:0]; + 13: sticky = |adj_op_tmp[12:0]; + 14: sticky = |adj_op_tmp[13:0]; + 15: sticky = |adj_op_tmp[14:0]; + 16: sticky = |adj_op_tmp[15:0]; + 17: sticky = |adj_op_tmp[16:0]; + 18: sticky = |adj_op_tmp[17:0]; + 19: sticky = |adj_op_tmp[18:0]; + 20: sticky = |adj_op_tmp[19:0]; + 21: sticky = |adj_op_tmp[20:0]; + 22: sticky = |adj_op_tmp[21:0]; + 23: sticky = |adj_op_tmp[22:0]; + 24: sticky = |adj_op_tmp[23:0]; + 25: sticky = |adj_op_tmp[24:0]; + 26: sticky = |adj_op_tmp[25:0]; + 27: sticky = |adj_op_tmp[26:0]; + endcase + +// --------------------------------------------------------------------- +// Select operands for add/sub (recover hidden bit) + +assign fracta_n = expa_lt_expb ? {~expa_dn, fracta, 3'b0} : adj_op_out; +assign fractb_n = expa_lt_expb ? adj_op_out : {~expb_dn, fractb, 3'b0}; + +// --------------------------------------------------------------------- +// Sort operands (for sub only) + +assign fractb_lt_fracta = fractb_n > fracta_n; // fractb is larger than fracta +assign fracta_s = fractb_lt_fracta ? fractb_n : fracta_n; +assign fractb_s = fractb_lt_fracta ? fracta_n : fractb_n; + +always @(posedge clk) + fracta_out <= #1 fracta_s; + +always @(posedge clk) + fractb_out <= #1 fractb_s; + +// --------------------------------------------------------------------- +// Determine sign for the output + +// sign: 0=Positive Number; 1=Negative Number +always @(signa or signb or add or fractb_lt_fracta) + case({signa, signb, add}) // synopsys full_case parallel_case + + // Add + 3'b0_0_1: sign_d = 0; + 3'b0_1_1: sign_d = fractb_lt_fracta; + 3'b1_0_1: sign_d = !fractb_lt_fracta; + 3'b1_1_1: sign_d = 1; + + // Sub + 3'b0_0_0: sign_d = fractb_lt_fracta; + 3'b0_1_0: sign_d = 0; + 3'b1_0_0: sign_d = 1; + 3'b1_1_0: sign_d = !fractb_lt_fracta; + endcase + +always @(posedge clk) + sign <= #1 sign_d; + +// Fix sign for ZERO result +always @(posedge clk) + signa_r <= #1 signa; + +always @(posedge clk) + signb_r <= #1 signb; + +always @(posedge clk) + add_r <= #1 add; + +always @(posedge clk) + result_zero_sign <= #1 ( add_r & signa_r & signb_r) | + (!add_r & signa_r & !signb_r) | + ( add_r & (signa_r | signb_r) & (rmode==3)) | + (!add_r & (signa_r == signb_r) & (rmode==3)); + +// Fix sign for NAN result +always @(posedge clk) + fracta_lt_fractb <= #1 fracta < fractb; + +always @(posedge clk) + fracta_eq_fractb <= #1 fracta == fractb; + +assign nan_sign1 = fracta_eq_fractb ? (signa_r & signb_r) : fracta_lt_fractb ? signb_r : signa_r; + +always @(posedge clk) + nan_sign <= #1 (opa_nan & opb_nan) ? nan_sign1 : opb_nan ? signb_r : signa_r; + +//////////////////////////////////////////////////////////////////////// +// +// Decode Add/Sub operation +// + +// add: 1=Add; 0=Subtract +always @(signa or signb or add) + case({signa, signb, add}) // synopsys full_case parallel_case + + // Add + 3'b0_0_1: add_d = 1; + 3'b0_1_1: add_d = 0; + 3'b1_0_1: add_d = 0; + 3'b1_1_1: add_d = 1; + + // Sub + 3'b0_0_0: add_d = 0; + 3'b0_1_0: add_d = 1; + 3'b1_0_0: add_d = 1; + 3'b1_1_0: add_d = 0; + endcase + +always @(posedge clk) + fasu_op <= #1 add_d; + +endmodule diff --git a/tests/iwls2005/fpu/pre_norm_fmul.v b/tests/iwls2005/fpu/pre_norm_fmul.v new file mode 100644 index 00000000..26ddfeb7 --- /dev/null +++ b/tests/iwls2005/fpu/pre_norm_fmul.v @@ -0,0 +1,150 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// Pre Normalize //// +//// Floating Point Pre Normalization Unit for FMUL //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +`timescale 1ns / 100ps + +module pre_norm_fmul(clk, fpu_op, opa, opb, fracta, fractb, exp_out, sign, + sign_exe, inf, exp_ovf, underflow); +input clk; +input [2:0] fpu_op; +input [31:0] opa, opb; +output [23:0] fracta, fractb; +output [7:0] exp_out; +output sign, sign_exe; +output inf; +output [1:0] exp_ovf; +output [2:0] underflow; + +//////////////////////////////////////////////////////////////////////// +// +// Local Wires and registers +// + +reg [7:0] exp_out; +wire signa, signb; +reg sign, sign_d; +reg sign_exe; +reg inf; +wire [1:0] exp_ovf_d; +reg [1:0] exp_ovf; +wire [7:0] expa, expb; +wire [7:0] exp_tmp1, exp_tmp2; +wire co1, co2; +wire expa_dn, expb_dn; +wire [7:0] exp_out_a; +wire opa_00, opb_00, fracta_00, fractb_00; +wire [7:0] exp_tmp3, exp_tmp4, exp_tmp5; +wire [2:0] underflow_d; +reg [2:0] underflow; +wire op_div = (fpu_op == 3'b011); +wire [7:0] exp_out_mul, exp_out_div; + +//////////////////////////////////////////////////////////////////////// +// +// Aliases +// + +assign signa = opa[31]; +assign signb = opb[31]; +assign expa = opa[30:23]; +assign expb = opb[30:23]; + +//////////////////////////////////////////////////////////////////////// +// +// Calculate Exponenet +// + +assign expa_dn = !(|expa); +assign expb_dn = !(|expb); +assign opa_00 = !(|opa[30:0]); +assign opb_00 = !(|opb[30:0]); +assign fracta_00 = !(|opa[22:0]); +assign fractb_00 = !(|opb[22:0]); + +assign fracta = {!expa_dn,opa[22:0]}; // Recover hidden bit +assign fractb = {!expb_dn,opb[22:0]}; // Recover hidden bit + +assign {co1,exp_tmp1} = op_div ? (expa - expb) : (expa + expb); +assign {co2,exp_tmp2} = op_div ? ({co1,exp_tmp1} + 8'h7f) : ({co1,exp_tmp1} - 8'h7f); + +assign exp_tmp3 = exp_tmp2 + 1; +assign exp_tmp4 = 8'h7f - exp_tmp1; +assign exp_tmp5 = op_div ? (exp_tmp4+1) : (exp_tmp4-1); + + +always@(posedge clk) + exp_out <= #1 op_div ? exp_out_div : exp_out_mul; + +assign exp_out_div = (expa_dn | expb_dn) ? (co2 ? exp_tmp5 : exp_tmp3 ) : co2 ? exp_tmp4 : exp_tmp2; +assign exp_out_mul = exp_ovf_d[1] ? exp_out_a : (expa_dn | expb_dn) ? exp_tmp3 : exp_tmp2; +assign exp_out_a = (expa_dn | expb_dn) ? exp_tmp5 : exp_tmp4; +assign exp_ovf_d[0] = op_div ? (expa[7] & !expb[7]) : (co2 & expa[7] & expb[7]); +assign exp_ovf_d[1] = op_div ? co2 : ((!expa[7] & !expb[7] & exp_tmp2[7]) | co2); + +always @(posedge clk) + exp_ovf <= #1 exp_ovf_d; + +assign underflow_d[0] = (exp_tmp1 < 8'h7f) & !co1 & !(opa_00 | opb_00 | expa_dn | expb_dn); +assign underflow_d[1] = ((expa[7] | expb[7]) & !opa_00 & !opb_00) | + (expa_dn & !fracta_00) | (expb_dn & !fractb_00); +assign underflow_d[2] = !opa_00 & !opb_00 & (exp_tmp1 == 8'h7f); + +always @(posedge clk) + underflow <= #1 underflow_d; + +always @(posedge clk) + inf <= #1 op_div ? (expb_dn & !expa[7]) : ({co1,exp_tmp1} > 9'h17e) ; + + +//////////////////////////////////////////////////////////////////////// +// +// Determine sign for the output +// + +// sign: 0=Posetive Number; 1=Negative Number +always @(signa or signb) + case({signa, signb}) // synopsys full_case parallel_case + 2'b0_0: sign_d = 0; + 2'b0_1: sign_d = 1; + 2'b1_0: sign_d = 1; + 2'b1_1: sign_d = 0; + endcase + +always @(posedge clk) + sign <= #1 sign_d; + +always @(posedge clk) + sign_exe <= #1 signa & signb; + +endmodule
\ No newline at end of file diff --git a/tests/iwls2005/fpu/primitives.v b/tests/iwls2005/fpu/primitives.v new file mode 100644 index 00000000..2e7f050e --- /dev/null +++ b/tests/iwls2005/fpu/primitives.v @@ -0,0 +1,103 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// Primitives //// +//// FPU Primitives //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + + +`timescale 1ns / 100ps + + +//////////////////////////////////////////////////////////////////////// +// +// Add/Sub +// + +module add_sub27(add, opa, opb, sum, co); +input add; +input [26:0] opa, opb; +output [26:0] sum; +output co; + + + +assign {co, sum} = add ? (opa + opb) : (opa - opb); + +endmodule + +//////////////////////////////////////////////////////////////////////// +// +// Multiply +// + +module mul_r2(clk, opa, opb, prod); +input clk; +input [23:0] opa, opb; +output [47:0] prod; + +reg [47:0] prod1, prod; + +always @(posedge clk) + prod1 <= #1 opa * opb; + +always @(posedge clk) + prod <= #1 prod1; + +endmodule + +//////////////////////////////////////////////////////////////////////// +// +// Divide +// + +module div_r2(clk, opa, opb, quo, rem); +input clk; +input [49:0] opa; +input [23:0] opb; +output [49:0] quo, rem; + +reg [49:0] quo, rem, quo1, remainder; + +always @(posedge clk) + quo1 <= #1 opa / opb; + +always @(posedge clk) + quo <= #1 quo1; + +always @(posedge clk) + remainder <= #1 opa % opb; + +always @(posedge clk) + rem <= #1 remainder; + +endmodule + + diff --git a/tests/iwls2005/i2c/i2c_master_bit_ctrl.v b/tests/iwls2005/i2c/i2c_master_bit_ctrl.v new file mode 100644 index 00000000..17b2c8b1 --- /dev/null +++ b/tests/iwls2005/i2c/i2c_master_bit_ctrl.v @@ -0,0 +1,535 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE rev.B2 compliant I2C Master bit-controller //// +//// //// +//// //// +//// Author: Richard Herveille //// +//// richard@asics.ws //// +//// www.asics.ws //// +//// //// +//// Downloaded from: http://www.opencores.org/projects/i2c/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: i2c_master_bit_ctrl.v,v 1.11 2004/05/07 11:02:26 rherveille Exp $ +// +// $Date: 2004/05/07 11:02:26 $ +// $Revision: 1.11 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: i2c_master_bit_ctrl.v,v $ +// Revision 1.11 2004/05/07 11:02:26 rherveille +// Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit. +// +// Revision 1.10 2003/08/09 07:01:33 rherveille +// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line. +// Fixed a potential bug in the byte controller's host-acknowledge generation. +// +// Revision 1.9 2003/03/10 14:26:37 rherveille +// Fixed cmd_ack generation item (no bug). +// +// Revision 1.8 2003/02/05 00:06:10 rherveille +// Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles. +// +// Revision 1.7 2002/12/26 16:05:12 rherveille +// Small code simplifications +// +// Revision 1.6 2002/12/26 15:02:32 rherveille +// Core is now a Multimaster I2C controller +// +// Revision 1.5 2002/11/30 22:24:40 rherveille +// Cleaned up code +// +// Revision 1.4 2002/10/30 18:10:07 rherveille +// Fixed some reported minor start/stop generation timing issuess. +// +// Revision 1.3 2002/06/15 07:37:03 rherveille +// Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment. +// +// Revision 1.2 2001/11/05 11:59:25 rherveille +// Fixed wb_ack_o generation bug. +// Fixed bug in the byte_controller statemachine. +// Added headers. +// + +// +///////////////////////////////////// +// Bit controller section +///////////////////////////////////// +// +// Translate simple commands into SCL/SDA transitions +// Each command has 5 states, A/B/C/D/idle +// +// start: SCL ~~~~~~~~~~\____ +// SDA ~~~~~~~~\______ +// x | A | B | C | D | i +// +// repstart SCL ____/~~~~\___ +// SDA __/~~~\______ +// x | A | B | C | D | i +// +// stop SCL ____/~~~~~~~~ +// SDA ==\____/~~~~~ +// x | A | B | C | D | i +// +//- write SCL ____/~~~~\____ +// SDA ==X=========X= +// x | A | B | C | D | i +// +//- read SCL ____/~~~~\____ +// SDA XXXX=====XXXX +// x | A | B | C | D | i +// + +// Timing: Normal mode Fast mode +/////////////////////////////////////////////////////////////////////// +// Fscl 100KHz 400KHz +// Th_scl 4.0us 0.6us High period of SCL +// Tl_scl 4.7us 1.3us Low period of SCL +// Tsu:sta 4.7us 0.6us setup time for a repeated start condition +// Tsu:sto 4.0us 0.6us setup time for a stop conditon +// Tbuf 4.7us 1.3us Bus free time between a stop and start condition +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +`include "i2c_master_defines.v" + +module i2c_master_bit_ctrl( + clk, rst, nReset, + clk_cnt, ena, cmd, cmd_ack, busy, al, din, dout, + scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen + ); + + // + // inputs & outputs + // + input clk; + input rst; + input nReset; + input ena; // core enable signal + + input [15:0] clk_cnt; // clock prescale value + + input [3:0] cmd; + output cmd_ack; // command complete acknowledge + reg cmd_ack; + output busy; // i2c bus busy + reg busy; + output al; // i2c bus arbitration lost + reg al; + + input din; + output dout; + reg dout; + + // I2C lines + input scl_i; // i2c clock line input + output scl_o; // i2c clock line output + output scl_oen; // i2c clock line output enable (active low) + reg scl_oen; + input sda_i; // i2c data line input + output sda_o; // i2c data line output + output sda_oen; // i2c data line output enable (active low) + reg sda_oen; + + + // + // variable declarations + // + + reg sSCL, sSDA; // synchronized SCL and SDA inputs + reg dscl_oen; // delayed scl_oen + reg sda_chk; // check SDA output (Multi-master arbitration) + reg clk_en; // clock generation signals + wire slave_wait; +// reg [15:0] cnt = clk_cnt; // clock divider counter (simulation) + reg [15:0] cnt; // clock divider counter (synthesis) + + // state machine variable + reg [16:0] c_state; // synopsys enum_state + + // + // module body + // + + // whenever the slave is not ready it can delay the cycle by pulling SCL low + // delay scl_oen + always @(posedge clk) + dscl_oen <= #1 scl_oen; + + assign slave_wait = dscl_oen && !sSCL; + + + // generate clk enable signal + always @(posedge clk or negedge nReset) + if(~nReset) + begin + cnt <= #1 16'h0; + clk_en <= #1 1'b1; + end + else if (rst) + begin + cnt <= #1 16'h0; + clk_en <= #1 1'b1; + end + else if ( ~|cnt || ~ena) + if (~slave_wait) + begin + cnt <= #1 clk_cnt; + clk_en <= #1 1'b1; + end + else + begin + cnt <= #1 cnt; + clk_en <= #1 1'b0; + end + else + begin + cnt <= #1 cnt - 16'h1; + clk_en <= #1 1'b0; + end + + + // generate bus status controller + reg dSCL, dSDA; + reg sta_condition; + reg sto_condition; + + // synchronize SCL and SDA inputs + // reduce metastability risc + always @(posedge clk or negedge nReset) + if (~nReset) + begin + sSCL <= #1 1'b1; + sSDA <= #1 1'b1; + + dSCL <= #1 1'b1; + dSDA <= #1 1'b1; + end + else if (rst) + begin + sSCL <= #1 1'b1; + sSDA <= #1 1'b1; + + dSCL <= #1 1'b1; + dSDA <= #1 1'b1; + end + else + begin + sSCL <= #1 scl_i; + sSDA <= #1 sda_i; + + dSCL <= #1 sSCL; + dSDA <= #1 sSDA; + end + + // detect start condition => detect falling edge on SDA while SCL is high + // detect stop condition => detect rising edge on SDA while SCL is high + always @(posedge clk or negedge nReset) + if (~nReset) + begin + sta_condition <= #1 1'b0; + sto_condition <= #1 1'b0; + end + else if (rst) + begin + sta_condition <= #1 1'b0; + sto_condition <= #1 1'b0; + end + else + begin + sta_condition <= #1 ~sSDA & dSDA & sSCL; + sto_condition <= #1 sSDA & ~dSDA & sSCL; + end + + // generate i2c bus busy signal + always @(posedge clk or negedge nReset) + if(!nReset) + busy <= #1 1'b0; + else if (rst) + busy <= #1 1'b0; + else + busy <= #1 (sta_condition | busy) & ~sto_condition; + + // generate arbitration lost signal + // aribitration lost when: + // 1) master drives SDA high, but the i2c bus is low + // 2) stop detected while not requested + reg cmd_stop; + always @(posedge clk or negedge nReset) + if (~nReset) + cmd_stop <= #1 1'b0; + else if (rst) + cmd_stop <= #1 1'b0; + else if (clk_en) + cmd_stop <= #1 cmd == `I2C_CMD_STOP; + + always @(posedge clk or negedge nReset) + if (~nReset) + al <= #1 1'b0; + else if (rst) + al <= #1 1'b0; + else + al <= #1 (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop); + + + // generate dout signal (store SDA on rising edge of SCL) + always @(posedge clk) + if(sSCL & ~dSCL) + dout <= #1 sSDA; + + // generate statemachine + + // nxt_state decoder + parameter [16:0] idle = 17'b0_0000_0000_0000_0000; + parameter [16:0] start_a = 17'b0_0000_0000_0000_0001; + parameter [16:0] start_b = 17'b0_0000_0000_0000_0010; + parameter [16:0] start_c = 17'b0_0000_0000_0000_0100; + parameter [16:0] start_d = 17'b0_0000_0000_0000_1000; + parameter [16:0] start_e = 17'b0_0000_0000_0001_0000; + parameter [16:0] stop_a = 17'b0_0000_0000_0010_0000; + parameter [16:0] stop_b = 17'b0_0000_0000_0100_0000; + parameter [16:0] stop_c = 17'b0_0000_0000_1000_0000; + parameter [16:0] stop_d = 17'b0_0000_0001_0000_0000; + parameter [16:0] rd_a = 17'b0_0000_0010_0000_0000; + parameter [16:0] rd_b = 17'b0_0000_0100_0000_0000; + parameter [16:0] rd_c = 17'b0_0000_1000_0000_0000; + parameter [16:0] rd_d = 17'b0_0001_0000_0000_0000; + parameter [16:0] wr_a = 17'b0_0010_0000_0000_0000; + parameter [16:0] wr_b = 17'b0_0100_0000_0000_0000; + parameter [16:0] wr_c = 17'b0_1000_0000_0000_0000; + parameter [16:0] wr_d = 17'b1_0000_0000_0000_0000; + + always @(posedge clk or negedge nReset) + if (!nReset) + begin + c_state <= #1 idle; + cmd_ack <= #1 1'b0; + scl_oen <= #1 1'b1; + sda_oen <= #1 1'b1; + sda_chk <= #1 1'b0; + end + else if (rst | al) + begin + c_state <= #1 idle; + cmd_ack <= #1 1'b0; + scl_oen <= #1 1'b1; + sda_oen <= #1 1'b1; + sda_chk <= #1 1'b0; + end + else + begin + cmd_ack <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle + + if (clk_en) + case (c_state) // synopsys full_case parallel_case + // idle state + idle: + begin + case (cmd) // synopsys full_case parallel_case + `I2C_CMD_START: + c_state <= #1 start_a; + + `I2C_CMD_STOP: + c_state <= #1 stop_a; + + `I2C_CMD_WRITE: + c_state <= #1 wr_a; + + `I2C_CMD_READ: + c_state <= #1 rd_a; + + default: + c_state <= #1 idle; + endcase + + scl_oen <= #1 scl_oen; // keep SCL in same state + sda_oen <= #1 sda_oen; // keep SDA in same state + sda_chk <= #1 1'b0; // don't check SDA output + end + + // start + start_a: + begin + c_state <= #1 start_b; + scl_oen <= #1 scl_oen; // keep SCL in same state + sda_oen <= #1 1'b1; // set SDA high + sda_chk <= #1 1'b0; // don't check SDA output + end + + start_b: + begin + c_state <= #1 start_c; + scl_oen <= #1 1'b1; // set SCL high + sda_oen <= #1 1'b1; // keep SDA high + sda_chk <= #1 1'b0; // don't check SDA output + end + + start_c: + begin + c_state <= #1 start_d; + scl_oen <= #1 1'b1; // keep SCL high + sda_oen <= #1 1'b0; // set SDA low + sda_chk <= #1 1'b0; // don't check SDA output + end + + start_d: + begin + c_state <= #1 start_e; + scl_oen <= #1 1'b1; // keep SCL high + sda_oen <= #1 1'b0; // keep SDA low + sda_chk <= #1 1'b0; // don't check SDA output + end + + start_e: + begin + c_state <= #1 idle; + cmd_ack <= #1 1'b1; + scl_oen <= #1 1'b0; // set SCL low + sda_oen <= #1 1'b0; // keep SDA low + sda_chk <= #1 1'b0; // don't check SDA output + end + + // stop + stop_a: + begin + c_state <= #1 stop_b; + scl_oen <= #1 1'b0; // keep SCL low + sda_oen <= #1 1'b0; // set SDA low + sda_chk <= #1 1'b0; // don't check SDA output + end + + stop_b: + begin + c_state <= #1 stop_c; + scl_oen <= #1 1'b1; // set SCL high + sda_oen <= #1 1'b0; // keep SDA low + sda_chk <= #1 1'b0; // don't check SDA output + end + + stop_c: + begin + c_state <= #1 stop_d; + scl_oen <= #1 1'b1; // keep SCL high + sda_oen <= #1 1'b0; // keep SDA low + sda_chk <= #1 1'b0; // don't check SDA output + end + + stop_d: + begin + c_state <= #1 idle; + cmd_ack <= #1 1'b1; + scl_oen <= #1 1'b1; // keep SCL high + sda_oen <= #1 1'b1; // set SDA high + sda_chk <= #1 1'b0; // don't check SDA output + end + + // read + rd_a: + begin + c_state <= #1 rd_b; + scl_oen <= #1 1'b0; // keep SCL low + sda_oen <= #1 1'b1; // tri-state SDA + sda_chk <= #1 1'b0; // don't check SDA output + end + + rd_b: + begin + c_state <= #1 rd_c; + scl_oen <= #1 1'b1; // set SCL high + sda_oen <= #1 1'b1; // keep SDA tri-stated + sda_chk <= #1 1'b0; // don't check SDA output + end + + rd_c: + begin + c_state <= #1 rd_d; + scl_oen <= #1 1'b1; // keep SCL high + sda_oen <= #1 1'b1; // keep SDA tri-stated + sda_chk <= #1 1'b0; // don't check SDA output + end + + rd_d: + begin + c_state <= #1 idle; + cmd_ack <= #1 1'b1; + scl_oen <= #1 1'b0; // set SCL low + sda_oen <= #1 1'b1; // keep SDA tri-stated + sda_chk <= #1 1'b0; // don't check SDA output + end + + // write + wr_a: + begin + c_state <= #1 wr_b; + scl_oen <= #1 1'b0; // keep SCL low + sda_oen <= #1 din; // set SDA + sda_chk <= #1 1'b0; // don't check SDA output (SCL low) + end + + wr_b: + begin + c_state <= #1 wr_c; + scl_oen <= #1 1'b1; // set SCL high + sda_oen <= #1 din; // keep SDA + sda_chk <= #1 1'b1; // check SDA output + end + + wr_c: + begin + c_state <= #1 wr_d; + scl_oen <= #1 1'b1; // keep SCL high + sda_oen <= #1 din; + sda_chk <= #1 1'b1; // check SDA output + end + + wr_d: + begin + c_state <= #1 idle; + cmd_ack <= #1 1'b1; + scl_oen <= #1 1'b0; // set SCL low + sda_oen <= #1 din; + sda_chk <= #1 1'b0; // don't check SDA output (SCL low) + end + + endcase + end + + + // assign scl and sda output (always gnd) + assign scl_o = 1'b0; + assign sda_o = 1'b0; + +endmodule diff --git a/tests/iwls2005/i2c/i2c_master_byte_ctrl.v b/tests/iwls2005/i2c/i2c_master_byte_ctrl.v new file mode 100644 index 00000000..d091d1e3 --- /dev/null +++ b/tests/iwls2005/i2c/i2c_master_byte_ctrl.v @@ -0,0 +1,344 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE rev.B2 compliant I2C Master byte-controller //// +//// //// +//// //// +//// Author: Richard Herveille //// +//// richard@asics.ws //// +//// www.asics.ws //// +//// //// +//// Downloaded from: http://www.opencores.org/projects/i2c/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: i2c_master_byte_ctrl.v,v 1.7 2004/02/18 11:40:46 rherveille Exp $ +// +// $Date: 2004/02/18 11:40:46 $ +// $Revision: 1.7 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: i2c_master_byte_ctrl.v,v $ +// Revision 1.7 2004/02/18 11:40:46 rherveille +// Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command. +// +// Revision 1.6 2003/08/09 07:01:33 rherveille +// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line. +// Fixed a potential bug in the byte controller's host-acknowledge generation. +// +// Revision 1.5 2002/12/26 15:02:32 rherveille +// Core is now a Multimaster I2C controller +// +// Revision 1.4 2002/11/30 22:24:40 rherveille +// Cleaned up code +// +// Revision 1.3 2001/11/05 11:59:25 rherveille +// Fixed wb_ack_o generation bug. +// Fixed bug in the byte_controller statemachine. +// Added headers. +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +`include "i2c_master_defines.v" + +module i2c_master_byte_ctrl ( + clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, din, + cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen ); + + // + // inputs & outputs + // + input clk; // master clock + input rst; // synchronous active high reset + input nReset; // asynchronous active low reset + input ena; // core enable signal + + input [15:0] clk_cnt; // 4x SCL + + // control inputs + input start; + input stop; + input read; + input write; + input ack_in; + input [7:0] din; + + // status outputs + output cmd_ack; + reg cmd_ack; + output ack_out; + reg ack_out; + output i2c_busy; + output i2c_al; + output [7:0] dout; + + // I2C signals + input scl_i; + output scl_o; + output scl_oen; + input sda_i; + output sda_o; + output sda_oen; + + + // + // Variable declarations + // + + // statemachine + parameter [4:0] ST_IDLE = 5'b0_0000; + parameter [4:0] ST_START = 5'b0_0001; + parameter [4:0] ST_READ = 5'b0_0010; + parameter [4:0] ST_WRITE = 5'b0_0100; + parameter [4:0] ST_ACK = 5'b0_1000; + parameter [4:0] ST_STOP = 5'b1_0000; + + // signals for bit_controller + reg [3:0] core_cmd; + reg core_txd; + wire core_ack, core_rxd; + + // signals for shift register + reg [7:0] sr; //8bit shift register + reg shift, ld; + + // signals for state machine + wire go; + reg [2:0] dcnt; + wire cnt_done; + + // + // Module body + // + + // hookup bit_controller + i2c_master_bit_ctrl bit_controller ( + .clk ( clk ), + .rst ( rst ), + .nReset ( nReset ), + .ena ( ena ), + .clk_cnt ( clk_cnt ), + .cmd ( core_cmd ), + .cmd_ack ( core_ack ), + .busy ( i2c_busy ), + .al ( i2c_al ), + .din ( core_txd ), + .dout ( core_rxd ), + .scl_i ( scl_i ), + .scl_o ( scl_o ), + .scl_oen ( scl_oen ), + .sda_i ( sda_i ), + .sda_o ( sda_o ), + .sda_oen ( sda_oen ) + ); + + // generate go-signal + assign go = (read | write | stop) & ~cmd_ack; + + // assign dout output to shift-register + assign dout = sr; + + // generate shift register + always @(posedge clk or negedge nReset) + if (!nReset) + sr <= #1 8'h0; + else if (rst) + sr <= #1 8'h0; + else if (ld) + sr <= #1 din; + else if (shift) + sr <= #1 {sr[6:0], core_rxd}; + + // generate counter + always @(posedge clk or negedge nReset) + if (!nReset) + dcnt <= #1 3'h0; + else if (rst) + dcnt <= #1 3'h0; + else if (ld) + dcnt <= #1 3'h7; + else if (shift) + dcnt <= #1 dcnt - 3'h1; + + assign cnt_done = ~(|dcnt); + + // + // state machine + // + reg [4:0] c_state; // synopsis enum_state + + always @(posedge clk or negedge nReset) + if (!nReset) + begin + core_cmd <= #1 `I2C_CMD_NOP; + core_txd <= #1 1'b0; + shift <= #1 1'b0; + ld <= #1 1'b0; + cmd_ack <= #1 1'b0; + c_state <= #1 ST_IDLE; + ack_out <= #1 1'b0; + end + else if (rst | i2c_al) + begin + core_cmd <= #1 `I2C_CMD_NOP; + core_txd <= #1 1'b0; + shift <= #1 1'b0; + ld <= #1 1'b0; + cmd_ack <= #1 1'b0; + c_state <= #1 ST_IDLE; + ack_out <= #1 1'b0; + end + else + begin + // initially reset all signals + core_txd <= #1 sr[7]; + shift <= #1 1'b0; + ld <= #1 1'b0; + cmd_ack <= #1 1'b0; + + case (c_state) // synopsys full_case parallel_case + ST_IDLE: + if (go) + begin + if (start) + begin + c_state <= #1 ST_START; + core_cmd <= #1 `I2C_CMD_START; + end + else if (read) + begin + c_state <= #1 ST_READ; + core_cmd <= #1 `I2C_CMD_READ; + end + else if (write) + begin + c_state <= #1 ST_WRITE; + core_cmd <= #1 `I2C_CMD_WRITE; + end + else // stop + begin + c_state <= #1 ST_STOP; + core_cmd <= #1 `I2C_CMD_STOP; + end + + ld <= #1 1'b1; + end + + ST_START: + if (core_ack) + begin + if (read) + begin + c_state <= #1 ST_READ; + core_cmd <= #1 `I2C_CMD_READ; + end + else + begin + c_state <= #1 ST_WRITE; + core_cmd <= #1 `I2C_CMD_WRITE; + end + + ld <= #1 1'b1; + end + + ST_WRITE: + if (core_ack) + if (cnt_done) + begin + c_state <= #1 ST_ACK; + core_cmd <= #1 `I2C_CMD_READ; + end + else + begin + c_state <= #1 ST_WRITE; // stay in same state + core_cmd <= #1 `I2C_CMD_WRITE; // write next bit + shift <= #1 1'b1; + end + + ST_READ: + if (core_ack) + begin + if (cnt_done) + begin + c_state <= #1 ST_ACK; + core_cmd <= #1 `I2C_CMD_WRITE; + end + else + begin + c_state <= #1 ST_READ; // stay in same state + core_cmd <= #1 `I2C_CMD_READ; // read next bit + end + + shift <= #1 1'b1; + core_txd <= #1 ack_in; + end + + ST_ACK: + if (core_ack) + begin + if (stop) + begin + c_state <= #1 ST_STOP; + core_cmd <= #1 `I2C_CMD_STOP; + end + else + begin + c_state <= #1 ST_IDLE; + core_cmd <= #1 `I2C_CMD_NOP; + + // generate command acknowledge signal + cmd_ack <= #1 1'b1; + end + + // assign ack_out output to bit_controller_rxd (contains last received bit) + ack_out <= #1 core_rxd; + + core_txd <= #1 1'b1; + end + else + core_txd <= #1 ack_in; + + ST_STOP: + if (core_ack) + begin + c_state <= #1 ST_IDLE; + core_cmd <= #1 `I2C_CMD_NOP; + + // generate command acknowledge signal + cmd_ack <= #1 1'b1; + end + + endcase + end +endmodule diff --git a/tests/iwls2005/i2c/i2c_master_defines.v b/tests/iwls2005/i2c/i2c_master_defines.v new file mode 100644 index 00000000..ee3b694f --- /dev/null +++ b/tests/iwls2005/i2c/i2c_master_defines.v @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE rev.B2 compliant I2C Master controller defines //// +//// //// +//// //// +//// Author: Richard Herveille //// +//// richard@asics.ws //// +//// www.asics.ws //// +//// //// +//// Downloaded from: http://www.opencores.org/projects/i2c/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: i2c_master_defines.v,v 1.3 2001/11/05 11:59:25 rherveille Exp $ +// +// $Date: 2001/11/05 11:59:25 $ +// $Revision: 1.3 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: i2c_master_defines.v,v $ +// Revision 1.3 2001/11/05 11:59:25 rherveille +// Fixed wb_ack_o generation bug. +// Fixed bug in the byte_controller statemachine. +// Added headers. +// + + +// I2C registers wishbone addresses + +// bitcontroller states +`define I2C_CMD_NOP 4'b0000 +`define I2C_CMD_START 4'b0001 +`define I2C_CMD_STOP 4'b0010 +`define I2C_CMD_WRITE 4'b0100 +`define I2C_CMD_READ 4'b1000 diff --git a/tests/iwls2005/i2c/i2c_master_top.v b/tests/iwls2005/i2c/i2c_master_top.v new file mode 100644 index 00000000..30689bd7 --- /dev/null +++ b/tests/iwls2005/i2c/i2c_master_top.v @@ -0,0 +1,301 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE revB.2 compliant I2C Master controller Top-level //// +//// //// +//// //// +//// Author: Richard Herveille //// +//// richard@asics.ws //// +//// www.asics.ws //// +//// //// +//// Downloaded from: http://www.opencores.org/projects/i2c/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: i2c_master_top.v,v 1.11 2005/02/27 09:26:24 rherveille Exp $ +// +// $Date: 2005/02/27 09:26:24 $ +// $Revision: 1.11 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: i2c_master_top.v,v $ +// Revision 1.11 2005/02/27 09:26:24 rherveille +// Fixed register overwrite issue. +// Removed full_case pragma, replaced it by a default statement. +// +// Revision 1.10 2003/09/01 10:34:38 rherveille +// Fix a blocking vs. non-blocking error in the wb_dat output mux. +// +// Revision 1.9 2003/01/09 16:44:45 rherveille +// Fixed a bug in the Command Register declaration. +// +// Revision 1.8 2002/12/26 16:05:12 rherveille +// Small code simplifications +// +// Revision 1.7 2002/12/26 15:02:32 rherveille +// Core is now a Multimaster I2C controller +// +// Revision 1.6 2002/11/30 22:24:40 rherveille +// Cleaned up code +// +// Revision 1.5 2001/11/10 10:52:55 rherveille +// Changed PRER reset value from 0x0000 to 0xffff, conform specs. +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +`include "i2c_master_defines.v" + +module i2c_master_top( + wb_clk_i, wb_rst_i, arst_i, wb_adr_i, wb_dat_i, wb_dat_o, + wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_inta_o, + scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o ); + + // parameters + parameter ARST_LVL = 1'b0; // asynchronous reset level + + // + // inputs & outputs + // + + // wishbone signals + input wb_clk_i; // master clock input + input wb_rst_i; // synchronous active high reset + input arst_i; // asynchronous reset + input [2:0] wb_adr_i; // lower address bits + input [7:0] wb_dat_i; // databus input + output [7:0] wb_dat_o; // databus output + input wb_we_i; // write enable input + input wb_stb_i; // stobe/core select signal + input wb_cyc_i; // valid bus cycle input + output wb_ack_o; // bus cycle acknowledge output + output wb_inta_o; // interrupt request signal output + + reg [7:0] wb_dat_o; + reg wb_ack_o; + reg wb_inta_o; + + // I2C signals + // i2c clock line + input scl_pad_i; // SCL-line input + output scl_pad_o; // SCL-line output (always 1'b0) + output scl_padoen_o; // SCL-line output enable (active low) + + // i2c data line + input sda_pad_i; // SDA-line input + output sda_pad_o; // SDA-line output (always 1'b0) + output sda_padoen_o; // SDA-line output enable (active low) + + + // + // variable declarations + // + + // registers + reg [15:0] prer; // clock prescale register + reg [ 7:0] ctr; // control register + reg [ 7:0] txr; // transmit register + wire [ 7:0] rxr; // receive register + reg [ 7:0] cr; // command register + wire [ 7:0] sr; // status register + + // done signal: command completed, clear command register + wire done; + + // core enable signal + wire core_en; + wire ien; + + // status register signals + wire irxack; + reg rxack; // received aknowledge from slave + reg tip; // transfer in progress + reg irq_flag; // interrupt pending flag + wire i2c_busy; // bus busy (start signal detected) + wire i2c_al; // i2c bus arbitration lost + reg al; // status register arbitration lost bit + + // + // module body + // + + // generate internal reset + wire rst_i = arst_i ^ ARST_LVL; + + // generate wishbone signals + wire wb_wacc = wb_cyc_i & wb_stb_i & wb_we_i; + + // generate acknowledge output signal + always @(posedge wb_clk_i) + wb_ack_o <= #1 wb_cyc_i & wb_stb_i & ~wb_ack_o; // because timing is always honored + + // assign DAT_O + always @(posedge wb_clk_i) + begin + case (wb_adr_i) // synopsis parallel_case + 3'b000: wb_dat_o <= #1 prer[ 7:0]; + 3'b001: wb_dat_o <= #1 prer[15:8]; + 3'b010: wb_dat_o <= #1 ctr; + 3'b011: wb_dat_o <= #1 rxr; // write is transmit register (txr) + 3'b100: wb_dat_o <= #1 sr; // write is command register (cr) + 3'b101: wb_dat_o <= #1 txr; + 3'b110: wb_dat_o <= #1 cr; + 3'b111: wb_dat_o <= #1 0; // reserved + endcase + end + + // generate registers + always @(posedge wb_clk_i or negedge rst_i) + if (!rst_i) + begin + prer <= #1 16'hffff; + ctr <= #1 8'h0; + txr <= #1 8'h0; + end + else if (wb_rst_i) + begin + prer <= #1 16'hffff; + ctr <= #1 8'h0; + txr <= #1 8'h0; + end + else + if (wb_wacc) + case (wb_adr_i) // synopsis parallel_case + 3'b000 : prer [ 7:0] <= #1 wb_dat_i; + 3'b001 : prer [15:8] <= #1 wb_dat_i; + 3'b010 : ctr <= #1 wb_dat_i; + 3'b011 : txr <= #1 wb_dat_i; + default: ; + endcase + + // generate command register (special case) + always @(posedge wb_clk_i or negedge rst_i) + if (~rst_i) + cr <= #1 8'h0; + else if (wb_rst_i) + cr <= #1 8'h0; + else if (wb_wacc) + begin + if (core_en & (wb_adr_i == 3'b100) ) + cr <= #1 wb_dat_i; + end + else + begin + if (done | i2c_al) + cr[7:4] <= #1 4'h0; // clear command bits when done + // or when aribitration lost + cr[2:1] <= #1 2'b0; // reserved bits + cr[0] <= #1 2'b0; // clear IRQ_ACK bit + end + + + // decode command register + wire sta = cr[7]; + wire sto = cr[6]; + wire rd = cr[5]; + wire wr = cr[4]; + wire ack = cr[3]; + wire iack = cr[0]; + + // decode control register + assign core_en = ctr[7]; + assign ien = ctr[6]; + + // hookup byte controller block + i2c_master_byte_ctrl byte_controller ( + .clk ( wb_clk_i ), + .rst ( wb_rst_i ), + .nReset ( rst_i ), + .ena ( core_en ), + .clk_cnt ( prer ), + .start ( sta ), + .stop ( sto ), + .read ( rd ), + .write ( wr ), + .ack_in ( ack ), + .din ( txr ), + .cmd_ack ( done ), + .ack_out ( irxack ), + .dout ( rxr ), + .i2c_busy ( i2c_busy ), + .i2c_al ( i2c_al ), + .scl_i ( scl_pad_i ), + .scl_o ( scl_pad_o ), + .scl_oen ( scl_padoen_o ), + .sda_i ( sda_pad_i ), + .sda_o ( sda_pad_o ), + .sda_oen ( sda_padoen_o ) + ); + + // status register block + interrupt request signal + always @(posedge wb_clk_i or negedge rst_i) + if (!rst_i) + begin + al <= #1 1'b0; + rxack <= #1 1'b0; + tip <= #1 1'b0; + irq_flag <= #1 1'b0; + end + else if (wb_rst_i) + begin + al <= #1 1'b0; + rxack <= #1 1'b0; + tip <= #1 1'b0; + irq_flag <= #1 1'b0; + end + else + begin + al <= #1 i2c_al | (al & ~sta); + rxack <= #1 irxack; + tip <= #1 (rd | wr); + irq_flag <= #1 (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated + end + + // generate interrupt request signals + always @(posedge wb_clk_i or negedge rst_i) + if (!rst_i) + wb_inta_o <= #1 1'b0; + else if (wb_rst_i) + wb_inta_o <= #1 1'b0; + else + wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set) + + // assign status register bits + assign sr[7] = rxack; + assign sr[6] = i2c_busy; + assign sr[5] = al; + assign sr[4:2] = 3'h0; // reserved + assign sr[1] = tip; + assign sr[0] = irq_flag; + +endmodule diff --git a/tests/iwls2005/i2c/timescale.v b/tests/iwls2005/i2c/timescale.v new file mode 100644 index 00000000..60d4ecbd --- /dev/null +++ b/tests/iwls2005/i2c/timescale.v @@ -0,0 +1,2 @@ +`timescale 1ns / 10ps + diff --git a/tests/iwls2005/run-fm.sh b/tests/iwls2005/run-fm.sh new file mode 100755 index 00000000..14bb4e82 --- /dev/null +++ b/tests/iwls2005/run-fm.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +if [ -n "$REMOTE_YOSYS_ROOT" ]; then + rsync --exclude=".svn" --exclude="synth.log" --exclude="run-fm.sh" -rv -e "${REMOTE_YOSYS_SSH:-ssh}" "$REMOTE_YOSYS_ROOT"/tests/iwls2005/. . +fi + +exec_fm() +{ + dir=$1; top=$2; shift; shift + cat > $dir/fm.do <<- EOT + set hdlin_ignore_full_case false + set hdlin_warn_on_mismatch_message "FMR_ELAB-115 FMR_ELAB-146 FMR_ELAB-147" + read_verilog -container r -libname WORK -01 { $* } + set_top r:/WORK/$top + read_verilog -container i -libname WORK -01 synth.v + # read_verilog -container i -technology_library -libname TECH_WORK -01 ../../../techlibs/stdcells_sim.v + set_top i:/WORK/$top + if ![verify] start_gui exit + EOT + ( cd $dir; fm_shell -64 -file fm.do 2>&1 | tee fm.log; ) +} + +# cores that validated +exec_fm aes_core aes_cipher_top aes_cipher_top.v aes_inv_cipher_top.v aes_inv_sbox.v aes_key_expand_128.v aes_rcon.v aes_sbox.v +exec_fm i2c i2c_master_top i2c_master_top.v i2c_master_bit_ctrl.v i2c_master_byte_ctrl.v +exec_fm sasc sasc_top sasc_top.v sasc_brg.v sasc_fifo4.v +exec_fm simple_spi simple_spi_top simple_spi_top.v fifo4.v +exec_fm spi spi_top spi_top.v spi_clgen.v spi_shift.v +exec_fm ss_pcm pcm_slv_top pcm_slv_top.v +exec_fm systemcaes aes aes.v byte_mixcolum.v keysched.v mixcolum.v sbox.v subbytes.v word_mixcolum.v +exec_fm usb_phy usb_phy usb_phy.v usb_rx_phy.v usb_tx_phy.v + +# cores with known problems (the fpu core unfortunately was designed with logic loops) +#exec_fm fpu fpu fpu.v except.v post_norm.v pre_norm_fmul.v pre_norm.v primitives.v + +# summary +echo; echo +for x in */fm.log; do + echo -e "${x%/*}\\t$( egrep '^Verification (SUCCEEDED|FAILED)' $x; )" +done | expand -t15 +echo; echo + diff --git a/tests/iwls2005/run-synth.sh b/tests/iwls2005/run-synth.sh new file mode 100755 index 00000000..2f1e3066 --- /dev/null +++ b/tests/iwls2005/run-synth.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +make -C ../.. +set -x + +vg="" +# vg="valgrind --leak-check=full --show-reachable=yes --log-file=valgrind.log" + +cd aes_core +time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \ + aes_cipher_top.v aes_inv_cipher_top.v aes_inv_sbox.v \ + aes_key_expand_128.v aes_rcon.v aes_sbox.v + +cd ../fpu +time $vg ../../../yosys -qt -l synth.log -o synth.v -f "verilog -nolatches" -s ../run-synth.ys \ + fpu.v except.v post_norm.v pre_norm_fmul.v pre_norm.v primitives.v + +cd ../i2c +time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \ + i2c_master_top.v i2c_master_bit_ctrl.v i2c_master_byte_ctrl.v + +cd ../sasc +time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \ + sasc_top.v sasc_brg.v sasc_fifo4.v + +cd ../simple_spi +time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \ + simple_spi_top.v fifo4.v + +cd ../spi +time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \ + spi_top.v spi_clgen.v spi_shift.v + +cd ../ss_pcm +time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \ + pcm_slv_top.v + +cd ../systemcaes +time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \ + aes.v byte_mixcolum.v keysched.v mixcolum.v sbox.v subbytes.v word_mixcolum.v + +cd ../usb_phy +time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \ + usb_phy.v usb_rx_phy.v usb_tx_phy.v + diff --git a/tests/iwls2005/run-synth.ys b/tests/iwls2005/run-synth.ys new file mode 100644 index 00000000..f3253d5f --- /dev/null +++ b/tests/iwls2005/run-synth.ys @@ -0,0 +1,11 @@ +hierarchy +proc +opt +memory +opt +# fsm -norecode +# opt +techmap +opt +abc +opt diff --git a/tests/iwls2005/sasc/sasc_brg.v b/tests/iwls2005/sasc/sasc_brg.v new file mode 100644 index 00000000..74a7cc5b --- /dev/null +++ b/tests/iwls2005/sasc/sasc_brg.v @@ -0,0 +1,160 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// Simple Baud Rate Generator //// +//// //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// //// +//// Downloaded from: http://www.opencores.org/cores/sasc/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000-2002 Rudolf Usselmann //// +//// www.asics.ws //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: sasc_brg.v,v 1.2 2002/11/08 15:22:49 rudi Exp $ +// +// $Date: 2002/11/08 15:22:49 $ +// $Revision: 1.2 $ +// $Author: rudi $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: sasc_brg.v,v $ +// Revision 1.2 2002/11/08 15:22:49 rudi +// +// Fixed a typo in brg +// +// Revision 1.1.1.1 2002/09/16 16:16:40 rudi +// Initial Checkin +// +// +// +// +// +// +// +// + +`include "timescale.v" + +/* + Baud rate Generator + ================== + + div0 - is the first stage divider + Set this to the desired number of cycles less two + div1 - is the second stage divider + Set this to the actual number of cycles + + Remember you have to generate a baud rate that is 4 higher than what + you really want. This is because of the DPLL in the RX section ... + + Example: + If your system clock is 50MHz and you want to generate a 9.6 Kbps baud rate: + 9600*4 = 38400KHz + 50MHz/38400KHz=1302 or 6*217 + set div0=4 (6-2) and set div1=217 + +*/ + +module sasc_brg(clk, rst, div0, div1, sio_ce, sio_ce_x4); +input clk; +input rst; +input [7:0] div0, div1; +output sio_ce, sio_ce_x4; + +/////////////////////////////////////////////////////////////////// +// +// Local Wires and Registers +// + +reg [7:0] ps; +reg ps_clr; +reg [7:0] br_cnt; +reg br_clr; +reg sio_ce_x4_r; +reg [1:0] cnt; +reg sio_ce, sio_ce_x4; +reg sio_ce_r ; +reg sio_ce_x4_t; + +/////////////////////////////////////////////////////////////////// +// +// Boud Rate Generator +// + +// ----------------------------------------------------- +// Prescaler +always @(posedge clk) + if(!rst) ps <= #1 8'h0; + else + if(ps_clr) ps <= #1 8'h0; + else ps <= #1 ps + 8'h1; + +always @(posedge clk) + ps_clr <= #1 (ps == div0); // Desired number of cycles less 2 + +// ----------------------------------------------------- +// Oversampled Boud Rate (x4) +always @(posedge clk) + if(!rst) br_cnt <= #1 8'h0; + else + if(br_clr) br_cnt <= #1 8'h0; + else + if(ps_clr) br_cnt <= #1 br_cnt + 8'h1; + +always @(posedge clk) + br_clr <= #1 (br_cnt == div1); // Prciese number of PS cycles + +always @(posedge clk) + sio_ce_x4_r <= #1 br_clr; + +always @(posedge clk) + sio_ce_x4_t <= #1 !sio_ce_x4_r & br_clr; + +always @(posedge clk) + sio_ce_x4 <= #1 sio_ce_x4_t; + +// ----------------------------------------------------- +// Actual Boud rate +always @(posedge clk) + if(!rst) cnt <= #1 2'h0; + else + if(!sio_ce_x4_r & br_clr) cnt <= #1 cnt + 2'h1; + +always @(posedge clk) + sio_ce_r <= #1 (cnt == 2'h0); + +always @(posedge clk) + sio_ce <= #1 !sio_ce_r & (cnt == 2'h0); + +endmodule + diff --git a/tests/iwls2005/sasc/sasc_fifo4.v b/tests/iwls2005/sasc/sasc_fifo4.v new file mode 100644 index 00000000..ab9b9fef --- /dev/null +++ b/tests/iwls2005/sasc/sasc_fifo4.v @@ -0,0 +1,135 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// FIFO 4 entries deep //// +//// //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// //// +//// Downloaded from: http://www.opencores.org/cores/sasc/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000-2002 Rudolf Usselmann //// +//// www.asics.ws //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: sasc_fifo4.v,v 1.1.1.1 2002/09/16 16:16:41 rudi Exp $ +// +// $Date: 2002/09/16 16:16:41 $ +// $Revision: 1.1.1.1 $ +// $Author: rudi $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: sasc_fifo4.v,v $ +// Revision 1.1.1.1 2002/09/16 16:16:41 rudi +// Initial Checkin +// +// +// +// +// +// + +`include "timescale.v" + +// 4 entry deep fast fifo +module sasc_fifo4(clk, rst, clr, din, we, dout, re, full, empty); + +input clk, rst; +input clr; +input [7:0] din; +input we; +output [7:0] dout; +input re; +output full, empty; + + +//////////////////////////////////////////////////////////////////// +// +// Local Wires +// + +reg [7:0] mem[0:3]; +reg [1:0] wp; +reg [1:0] rp; +wire [1:0] wp_p1; +wire [1:0] wp_p2; +wire [1:0] rp_p1; +wire full, empty; +reg gb; + +//////////////////////////////////////////////////////////////////// +// +// Misc Logic +// + +always @(posedge clk or negedge rst) + if(!rst) wp <= #1 2'h0; + else + if(clr) wp <= #1 2'h0; + else + if(we) wp <= #1 wp_p1; + +assign wp_p1 = wp + 2'h1; +assign wp_p2 = wp + 2'h2; + +always @(posedge clk or negedge rst) + if(!rst) rp <= #1 2'h0; + else + if(clr) rp <= #1 2'h0; + else + if(re) rp <= #1 rp_p1; + +assign rp_p1 = rp + 2'h1; + +// Fifo Output +assign dout = mem[ rp ]; + +// Fifo Input +always @(posedge clk) + if(we) mem[ wp ] <= #1 din; + +// Status +assign empty = (wp == rp) & !gb; +assign full = (wp == rp) & gb; + +// Guard Bit ... +always @(posedge clk) + if(!rst) gb <= #1 1'b0; + else + if(clr) gb <= #1 1'b0; + else + if((wp_p1 == rp) & we) gb <= #1 1'b1; + else + if(re) gb <= #1 1'b0; + +endmodule + + diff --git a/tests/iwls2005/sasc/sasc_top.v b/tests/iwls2005/sasc/sasc_top.v new file mode 100644 index 00000000..a59329ad --- /dev/null +++ b/tests/iwls2005/sasc/sasc_top.v @@ -0,0 +1,301 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// Simple Asynchronous Serial Comm. Device //// +//// //// +//// //// +//// Author: Rudolf Usselmann //// +//// rudi@asics.ws //// +//// //// +//// //// +//// Downloaded from: http://www.opencores.org/cores/sasc/ //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000-2002 Rudolf Usselmann //// +//// www.asics.ws //// +//// rudi@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: sasc_top.v,v 1.1.1.1 2002/09/16 16:16:42 rudi Exp $ +// +// $Date: 2002/09/16 16:16:42 $ +// $Revision: 1.1.1.1 $ +// $Author: rudi $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: sasc_top.v,v $ +// Revision 1.1.1.1 2002/09/16 16:16:42 rudi +// Initial Checkin +// +// +// +// +// +// +// +// + +`include "timescale.v" + +/* +Serial IO Interface +=============================== +RTS I Request To Send +CTS O Clear to send +TD I Transmit Data +RD O Receive Data +*/ + +module sasc_top( clk, rst, + + // SIO + rxd_i, txd_o, cts_i, rts_o, + + // External Baud Rate Generator + sio_ce, sio_ce_x4, + + // Internal Interface + din_i, dout_o, re_i, we_i, full_o, empty_o); + +input clk; +input rst; +input rxd_i; +output txd_o; +input cts_i; +output rts_o; +input sio_ce; +input sio_ce_x4; +input [7:0] din_i; +output [7:0] dout_o; +input re_i, we_i; +output full_o, empty_o; + +/////////////////////////////////////////////////////////////////// +// +// Local Wires and Registers +// + +parameter START_BIT = 1'b0, + STOP_BIT = 1'b1, + IDLE_BIT = 1'b1; + +wire [7:0] txd_p; +reg load; +reg load_r; +wire load_e; +reg [9:0] hold_reg; +wire txf_empty; +reg txd_o; +reg shift_en; +reg [3:0] tx_bit_cnt; +reg rxd_s, rxd_r; +wire start; +reg [3:0] rx_bit_cnt; +reg rx_go; +reg [9:0] rxr; +reg rx_valid, rx_valid_r; +wire rx_we; +wire rxf_full; +reg rts_o; +reg txf_empty_r; +reg shift_en_r; +reg rxd_r1, rxd_r2; +wire lock_en; +reg change; +reg rx_sio_ce_d, rx_sio_ce_r1, rx_sio_ce_r2, rx_sio_ce; +reg [1:0] dpll_state, dpll_next_state; + +/////////////////////////////////////////////////////////////////// +// +// IO Fifo's +// + +sasc_fifo4 tx_fifo( .clk( clk ), + .rst( rst ), + .clr( 1'b0 ), + .din( din_i ), + .we( we_i ), + .dout( txd_p ), + .re( load_e ), + .full( full_o ), + .empty( txf_empty ) + ); + +sasc_fifo4 rx_fifo( .clk( clk ), + .rst( rst ), + .clr( 1'b0 ), + .din( rxr[9:2] ), + .we( rx_we ), + .dout( dout_o ), + .re( re_i ), + .full( rxf_full ), + .empty( empty_o ) + ); + +/////////////////////////////////////////////////////////////////// +// +// Transmit Logic +// +always @(posedge clk) + if(!rst) txf_empty_r <= #1 1'b1; + else + if(sio_ce) txf_empty_r <= #1 txf_empty; + +always @(posedge clk) + load <= #1 !txf_empty_r & !shift_en & !cts_i; + +always @(posedge clk) + load_r <= #1 load; + +assign load_e = load & sio_ce; + +always @(posedge clk) + if(load_e) hold_reg <= #1 {STOP_BIT, txd_p, START_BIT}; + else + if(shift_en & sio_ce) hold_reg <= #1 {IDLE_BIT, hold_reg[9:1]}; + +always @(posedge clk) + if(!rst) txd_o <= #1 IDLE_BIT; + else + if(sio_ce) + if(shift_en | shift_en_r) txd_o <= #1 hold_reg[0]; + else txd_o <= #1 IDLE_BIT; + +always @(posedge clk) + if(!rst) tx_bit_cnt <= #1 4'h9; + else + if(load_e) tx_bit_cnt <= #1 4'h0; + else + if(shift_en & sio_ce) tx_bit_cnt <= #1 tx_bit_cnt + 4'h1; + +always @(posedge clk) + shift_en <= #1 (tx_bit_cnt != 4'h9); + +always @(posedge clk) + if(!rst) shift_en_r <= #1 1'b0; + else + if(sio_ce) shift_en_r <= #1 shift_en; + +/////////////////////////////////////////////////////////////////// +// +// Recieve Logic +// + +always @(posedge clk) + rxd_s <= #1 rxd_i; + +always @(posedge clk) + rxd_r <= #1 rxd_s; + +assign start = (rxd_r == IDLE_BIT) & (rxd_s == START_BIT); + +always @(posedge clk) + if(!rst) rx_bit_cnt <= #1 4'ha; + else + if(!rx_go & start) rx_bit_cnt <= #1 4'h0; + else + if(rx_go & rx_sio_ce) rx_bit_cnt <= #1 rx_bit_cnt + 4'h1; + +always @(posedge clk) + rx_go <= #1 (rx_bit_cnt != 4'ha); + +always @(posedge clk) + rx_valid <= #1 (rx_bit_cnt == 4'h9); + +always @(posedge clk) + rx_valid_r <= #1 rx_valid; + +assign rx_we = !rx_valid_r & rx_valid & !rxf_full; + +always @(posedge clk) + if(rx_go & rx_sio_ce) rxr <= {rxd_s, rxr[9:1]}; + +always @(posedge clk) + rts_o <= #1 rxf_full; + +/////////////////////////////////////////////////////////////////// +// +// Reciever DPLL +// + +// Uses 4x baud clock to lock to incoming stream + +// Edge detector +always @(posedge clk) + if(sio_ce_x4) rxd_r1 <= #1 rxd_s; + +always @(posedge clk) + if(sio_ce_x4) rxd_r2 <= #1 rxd_r1; + +always @(posedge clk) + if(!rst) change <= #1 1'b0; + else + if(rxd_r != rxd_s) change <= #1 1'b1; + else + if(sio_ce_x4) change <= #1 1'b0; + +// DPLL FSM +always @(posedge clk or negedge rst) + if(!rst) dpll_state <= #1 2'h1; + else + if(sio_ce_x4) dpll_state <= #1 dpll_next_state; + +always @(dpll_state or change) + begin + rx_sio_ce_d = 1'b0; + case(dpll_state) + 2'h0: + if(change) dpll_next_state = 3'h0; + else dpll_next_state = 3'h1; + 2'h1:begin + rx_sio_ce_d = 1'b1; + if(change) dpll_next_state = 3'h3; + else dpll_next_state = 3'h2; + end + 2'h2: + if(change) dpll_next_state = 3'h0; + else dpll_next_state = 3'h3; + 2'h3: + if(change) dpll_next_state = 3'h0; + else dpll_next_state = 3'h0; + endcase + end + +// Compensate for sync registers at the input - allign sio +// clock enable to be in the middle between two bit changes ... +always @(posedge clk) + rx_sio_ce_r1 <= #1 rx_sio_ce_d; + +always @(posedge clk) + rx_sio_ce_r2 <= #1 rx_sio_ce_r1; + +always @(posedge clk) + rx_sio_ce <= #1 rx_sio_ce_r1 & !rx_sio_ce_r2; + +endmodule + + diff --git a/tests/iwls2005/sasc/timescale.v b/tests/iwls2005/sasc/timescale.v new file mode 100644 index 00000000..ff9e265a --- /dev/null +++ b/tests/iwls2005/sasc/timescale.v @@ -0,0 +1 @@ +`timescale 1ns / 10ps diff --git a/tests/iwls2005/simple_spi/fifo4.v b/tests/iwls2005/simple_spi/fifo4.v new file mode 100644 index 00000000..f041c7d2 --- /dev/null +++ b/tests/iwls2005/simple_spi/fifo4.v @@ -0,0 +1,134 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// FIFO 4 entries deep //// +//// //// +//// Authors: Rudolf Usselmann, Richard Herveille //// +//// rudi@asics.ws richard@asics.ws //// +//// //// +//// //// +//// Download from: http://www.opencores.org/projects/sasc //// +//// http://www.opencores.org/projects/simple_spi //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000-2002 Rudolf Usselmann, Richard Herveille //// +//// www.asics.ws //// +//// rudi@asics.ws, richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: fifo4.v,v 1.1.1.1 2002/12/22 16:07:14 rherveille Exp $ +// +// $Date: 2002/12/22 16:07:14 $ +// $Revision: 1.1.1.1 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: fifo4.v,v $ +// Revision 1.1.1.1 2002/12/22 16:07:14 rherveille +// Initial release +// +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + + +// 4 entry deep fast fifo +module fifo4(clk, rst, clr, din, we, dout, re, full, empty); + +parameter dw = 8; + +input clk, rst; +input clr; +input [dw:1] din; +input we; +output [dw:1] dout; +input re; +output full, empty; + + +//////////////////////////////////////////////////////////////////// +// +// Local Wires +// + +reg [dw:1] mem[0:3]; +reg [1:0] wp; +reg [1:0] rp; +wire [1:0] wp_p1; +wire [1:0] wp_p2; +wire [1:0] rp_p1; +wire full, empty; +reg gb; + +//////////////////////////////////////////////////////////////////// +// +// Misc Logic +// + +always @(posedge clk or negedge rst) + if(!rst) wp <= #1 2'h0; + else + if(clr) wp <= #1 2'h0; + else + if(we) wp <= #1 wp_p1; + +assign wp_p1 = wp + 2'h1; +assign wp_p2 = wp + 2'h2; + +always @(posedge clk or negedge rst) + if(!rst) rp <= #1 2'h0; + else + if(clr) rp <= #1 2'h0; + else + if(re) rp <= #1 rp_p1; + +assign rp_p1 = rp + 2'h1; + +// Fifo Output +assign dout = mem[ rp ]; + +// Fifo Input +always @(posedge clk) + if(we) mem[ wp ] <= #1 din; + +// Status +assign empty = (wp == rp) & !gb; +assign full = (wp == rp) & gb; + +// Guard Bit ... +always @(posedge clk) + if(!rst) gb <= #1 1'b0; + else + if(clr) gb <= #1 1'b0; + else + if((wp_p1 == rp) & we) gb <= #1 1'b1; + else + if(re) gb <= #1 1'b0; + +endmodule diff --git a/tests/iwls2005/simple_spi/simple_spi_top.v b/tests/iwls2005/simple_spi/simple_spi_top.v new file mode 100644 index 00000000..e952f4be --- /dev/null +++ b/tests/iwls2005/simple_spi/simple_spi_top.v @@ -0,0 +1,329 @@ +///////////////////////////////////////////////////////////////////// +//// //// +//// OpenCores MC68HC11E based SPI interface //// +//// //// +//// Author: Richard Herveille //// +//// richard@asics.ws //// +//// www.asics.ws //// +//// //// +///////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2002 Richard Herveille //// +//// richard@asics.ws //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer.//// +//// //// +//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// +//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// +//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// +//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// +//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// +//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// +//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// +//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// +//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// +//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// +//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// +//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// +//// POSSIBILITY OF SUCH DAMAGE. //// +//// //// +///////////////////////////////////////////////////////////////////// + +// CVS Log +// +// $Id: simple_spi_top.v,v 1.5 2004/02/28 15:59:50 rherveille Exp $ +// +// $Date: 2004/02/28 15:59:50 $ +// $Revision: 1.5 $ +// $Author: rherveille $ +// $Locker: $ +// $State: Exp $ +// +// Change History: +// $Log: simple_spi_top.v,v $ +// Revision 1.5 2004/02/28 15:59:50 rherveille +// Fixed SCK_O generation bug. +// This resulted in a major rewrite of the serial interface engine. +// +// Revision 1.4 2003/08/01 11:41:54 rherveille +// Fixed some timing bugs. +// +// Revision 1.3 2003/01/09 16:47:59 rherveille +// Updated clkcnt size and decoding due to new SPR bit assignments. +// +// Revision 1.2 2003/01/07 13:29:52 rherveille +// Changed SPR bits coding. +// +// Revision 1.1.1.1 2002/12/22 16:07:15 rherveille +// Initial release +// +// + + + +// +// Motorola MC68HC11E based SPI interface +// +// Currently only MASTER mode is supported +// + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +module simple_spi_top( + // 8bit WISHBONE bus slave interface + input wire clk_i, // clock + input wire rst_i, // reset (asynchronous active low) + input wire cyc_i, // cycle + input wire stb_i, // strobe + input wire [1:0] adr_i, // address + input wire we_i, // write enable + input wire [7:0] dat_i, // data input + output reg [7:0] dat_o, // data output + output reg ack_o, // normal bus termination + output reg inta_o, // interrupt output + + // SPI port + output reg sck_o, // serial clock output + output wire mosi_o, // MasterOut SlaveIN + input wire miso_i // MasterIn SlaveOut +); + + // + // Module body + // + reg [7:0] spcr; // Serial Peripheral Control Register ('HC11 naming) + wire [7:0] spsr; // Serial Peripheral Status register ('HC11 naming) + reg [7:0] sper; // Serial Peripheral Extension register + reg [7:0] treg, rreg; // Transmit/Receive register + + // fifo signals + wire [7:0] rfdout; + reg wfre, rfwe; + wire rfre, rffull, rfempty; + wire [7:0] wfdout; + wire wfwe, wffull, wfempty; + + // misc signals + wire tirq; // transfer interrupt (selected number of transfers done) + wire wfov; // write fifo overrun (writing while fifo full) + reg [1:0] state; // statemachine state + reg [2:0] bcnt; + + // + // Wishbone interface + wire wb_acc = cyc_i & stb_i; // WISHBONE access + wire wb_wr = wb_acc & we_i; // WISHBONE write access + + // dat_i + always @(posedge clk_i or negedge rst_i) + if (~rst_i) + begin + spcr <= #1 8'h10; // set master bit + sper <= #1 8'h00; + end + else if (wb_wr) + begin + if (adr_i == 2'b00) + spcr <= #1 dat_i | 8'h10; // always set master bit + + if (adr_i == 2'b11) + sper <= #1 dat_i; + end + + // write fifo + assign wfwe = wb_acc & (adr_i == 2'b10) & ack_o & we_i; + assign wfov = wfwe & wffull; + + // dat_o + always @(posedge clk_i) + case(adr_i) // synopsys full_case parallel_case + 2'b00: dat_o <= #1 spcr; + 2'b01: dat_o <= #1 spsr; + 2'b10: dat_o <= #1 rfdout; + 2'b11: dat_o <= #1 sper; + endcase + + // read fifo + assign rfre = wb_acc & (adr_i == 2'b10) & ack_o & ~we_i; + + // ack_o + always @(posedge clk_i or negedge rst_i) + if (~rst_i) + ack_o <= #1 1'b0; + else + ack_o <= #1 wb_acc & !ack_o; + + // decode Serial Peripheral Control Register + wire spie = spcr[7]; // Interrupt enable bit + wire spe = spcr[6]; // System Enable bit + wire dwom = spcr[5]; // Port D Wired-OR Mode Bit + wire mstr = spcr[4]; // Master Mode Select Bit + wire cpol = spcr[3]; // Clock Polarity Bit + wire cpha = spcr[2]; // Clock Phase Bit + wire [1:0] spr = spcr[1:0]; // Clock Rate Select Bits + + // decode Serial Peripheral Extension Register + wire [1:0] icnt = sper[7:6]; // interrupt on transfer count + wire [1:0] spre = sper[1:0]; // extended clock rate select + + wire [3:0] espr = {spre, spr}; + + // generate status register + wire wr_spsr = wb_wr & (adr_i == 2'b01); + + reg spif; + always @(posedge clk_i) + if (~spe) + spif <= #1 1'b0; + else + spif <= #1 (tirq | spif) & ~(wr_spsr & dat_i[7]); + + reg wcol; + always @(posedge clk_i) + if (~spe) + wcol <= #1 1'b0; + else + wcol <= #1 (wfov | wcol) & ~(wr_spsr & dat_i[6]); + + assign spsr[7] = spif; + assign spsr[6] = wcol; + assign spsr[5:4] = 2'b00; + assign spsr[3] = wffull; + assign spsr[2] = wfempty; + assign spsr[1] = rffull; + assign spsr[0] = rfempty; + + + // generate IRQ output (inta_o) + always @(posedge clk_i) + inta_o <= #1 spif & spie; + + // + // hookup read/write buffer fifo + fifo4 #(8) + rfifo( + .clk ( clk_i ), + .rst ( rst_i ), + .clr ( ~spe ), + .din ( treg ), + .we ( rfwe ), + .dout ( rfdout ), + .re ( rfre ), + .full ( rffull ), + .empty ( rfempty ) + ), + wfifo( + .clk ( clk_i ), + .rst ( rst_i ), + .clr ( ~spe ), + .din ( dat_i ), + .we ( wfwe ), + .dout ( wfdout ), + .re ( wfre ), + .full ( wffull ), + .empty ( wfempty ) + ); + + // + // generate clk divider + reg [11:0] clkcnt; + always @(posedge clk_i) + if(spe & (|clkcnt & |state)) + clkcnt <= #1 clkcnt - 11'h1; + else + case (espr) // synopsys full_case parallel_case + 4'b0000: clkcnt <= #1 12'h0; // 2 -- original M68HC11 coding + 4'b0001: clkcnt <= #1 12'h1; // 4 -- original M68HC11 coding + 4'b0010: clkcnt <= #1 12'h3; // 16 -- original M68HC11 coding + 4'b0011: clkcnt <= #1 12'hf; // 32 -- original M68HC11 coding + 4'b0100: clkcnt <= #1 12'h1f; // 8 + 4'b0101: clkcnt <= #1 12'h7; // 64 + 4'b0110: clkcnt <= #1 12'h3f; // 128 + 4'b0111: clkcnt <= #1 12'h7f; // 256 + 4'b1000: clkcnt <= #1 12'hff; // 512 + 4'b1001: clkcnt <= #1 12'h1ff; // 1024 + 4'b1010: clkcnt <= #1 12'h3ff; // 2048 + 4'b1011: clkcnt <= #1 12'h7ff; // 4096 + endcase + + // generate clock enable signal + wire ena = ~|clkcnt; + + // transfer statemachine + always @(posedge clk_i) + if (~spe) + begin + state <= #1 2'b00; // idle + bcnt <= #1 3'h0; + treg <= #1 8'h00; + wfre <= #1 1'b0; + rfwe <= #1 1'b0; + sck_o <= #1 1'b0; + end + else + begin + wfre <= #1 1'b0; + rfwe <= #1 1'b0; + + case (state) //synopsys full_case parallel_case + 2'b00: // idle state + begin + bcnt <= #1 3'h7; // set transfer counter + treg <= #1 wfdout; // load transfer register + sck_o <= #1 cpol; // set sck + + if (~wfempty) begin + wfre <= #1 1'b1; + state <= #1 2'b01; + if (cpha) sck_o <= #1 ~sck_o; + end + end + + 2'b01: // clock-phase2, next data + if (ena) begin + sck_o <= #1 ~sck_o; + state <= #1 2'b11; + end + + 2'b11: // clock phase1 + if (ena) begin + treg <= #1 {treg[6:0], miso_i}; + bcnt <= #1 bcnt -3'h1; + + if (~|bcnt) begin + state <= #1 2'b00; + sck_o <= #1 cpol; + rfwe <= #1 1'b1; + end else begin + state <= #1 2'b01; + sck_o <= #1 ~sck_o; + end + end + + 2'b10: state <= #1 2'b00; + endcase + end + + assign mosi_o = treg[7]; + + + // count number of transfers (for interrupt generation) + reg [1:0] tcnt; // transfer count + always @(posedge clk_i) + if (~spe) + tcnt <= #1 icnt; + else if (rfwe) // rfwe gets asserted when all bits have been transfered + if (|tcnt) + tcnt <= #1 tcnt - 2'h1; + else + tcnt <= #1 icnt; + + assign tirq = ~|tcnt & rfwe; + +endmodule + diff --git a/tests/iwls2005/spi/spi_clgen.v b/tests/iwls2005/spi/spi_clgen.v new file mode 100644 index 00000000..7bc4f6e5 --- /dev/null +++ b/tests/iwls2005/spi/spi_clgen.v @@ -0,0 +1,108 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// spi_clgen.v //// +//// //// +//// This file is part of the SPI IP core project //// +//// http://www.opencores.org/projects/spi/ //// +//// //// +//// Author(s): //// +//// - Simon Srot (simons@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +`include "spi_defines.v" +`include "timescale.v" + +module spi_clgen (clk_in, rst, go, enable, last_clk, divider, clk_out, pos_edge, neg_edge); + + parameter Tp = 1; + + input clk_in; // input clock (system clock) + input rst; // reset + input enable; // clock enable + input go; // start transfer + input last_clk; // last clock + input [`SPI_DIVIDER_LEN-1:0] divider; // clock divider (output clock is divided by this value) + output clk_out; // output clock + output pos_edge; // pulse marking positive edge of clk_out + output neg_edge; // pulse marking negative edge of clk_out + + reg clk_out; + reg pos_edge; + reg neg_edge; + + reg [`SPI_DIVIDER_LEN-1:0] cnt; // clock counter + wire cnt_zero; // conter is equal to zero + wire cnt_one; // conter is equal to one + + + assign cnt_zero = cnt == {`SPI_DIVIDER_LEN{1'b0}}; + assign cnt_one = cnt == {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1}; + + // Counter counts half period + always @(posedge clk_in or posedge rst) + begin + if(rst) + cnt <= #Tp {`SPI_DIVIDER_LEN{1'b1}}; + else + begin + if(!enable || cnt_zero) + cnt <= #Tp divider; + else + cnt <= #Tp cnt - {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1}; + end + end + + // clk_out is asserted every other half period + always @(posedge clk_in or posedge rst) + begin + if(rst) + clk_out <= #Tp 1'b0; + else + clk_out <= #Tp (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out; + end + + // Pos and neg edge signals + always @(posedge clk_in or posedge rst) + begin + if(rst) + begin + pos_edge <= #Tp 1'b0; + neg_edge <= #Tp 1'b0; + end + else + begin + pos_edge <= #Tp (enable && !clk_out && cnt_one) || (!(|divider) && clk_out) || (!(|divider) && go && !enable); + neg_edge <= #Tp (enable && clk_out && cnt_one) || (!(|divider) && !clk_out && enable); + end + end +endmodule + diff --git a/tests/iwls2005/spi/spi_defines.v b/tests/iwls2005/spi/spi_defines.v new file mode 100644 index 00000000..a6925918 --- /dev/null +++ b/tests/iwls2005/spi/spi_defines.v @@ -0,0 +1,159 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// spi_define.v //// +//// //// +//// This file is part of the SPI IP core project //// +//// http://www.opencores.org/projects/spi/ //// +//// //// +//// Author(s): //// +//// - Simon Srot (simons@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +// +// Number of bits used for devider register. If used in system with +// low frequency of system clock this can be reduced. +// Use SPI_DIVIDER_LEN for fine tuning theexact number. +// +//`define SPI_DIVIDER_LEN_8 +`define SPI_DIVIDER_LEN_16 +//`define SPI_DIVIDER_LEN_24 +//`define SPI_DIVIDER_LEN_32 + +`ifdef SPI_DIVIDER_LEN_8 + `define SPI_DIVIDER_LEN 8 // Can be set from 1 to 8 +`endif +`ifdef SPI_DIVIDER_LEN_16 + `define SPI_DIVIDER_LEN 16 // Can be set from 9 to 16 +`endif +`ifdef SPI_DIVIDER_LEN_24 + `define SPI_DIVIDER_LEN 24 // Can be set from 17 to 24 +`endif +`ifdef SPI_DIVIDER_LEN_32 + `define SPI_DIVIDER_LEN 32 // Can be set from 25 to 32 +`endif + +// +// Maximum nuber of bits that can be send/received at once. +// Use SPI_MAX_CHAR for fine tuning the exact number, when using +// SPI_MAX_CHAR_32, SPI_MAX_CHAR_24, SPI_MAX_CHAR_16, SPI_MAX_CHAR_8. +// +`define SPI_MAX_CHAR_128 +//`define SPI_MAX_CHAR_64 +//`define SPI_MAX_CHAR_32 +//`define SPI_MAX_CHAR_24 +//`define SPI_MAX_CHAR_16 +//`define SPI_MAX_CHAR_8 + +`ifdef SPI_MAX_CHAR_128 + `define SPI_MAX_CHAR 128 // Can only be set to 128 + `define SPI_CHAR_LEN_BITS 7 +`endif +`ifdef SPI_MAX_CHAR_64 + `define SPI_MAX_CHAR 64 // Can only be set to 64 + `define SPI_CHAR_LEN_BITS 6 +`endif +`ifdef SPI_MAX_CHAR_32 + `define SPI_MAX_CHAR 32 // Can be set from 25 to 32 + `define SPI_CHAR_LEN_BITS 5 +`endif +`ifdef SPI_MAX_CHAR_24 + `define SPI_MAX_CHAR 24 // Can be set from 17 to 24 + `define SPI_CHAR_LEN_BITS 5 +`endif +`ifdef SPI_MAX_CHAR_16 + `define SPI_MAX_CHAR 16 // Can be set from 9 to 16 + `define SPI_CHAR_LEN_BITS 4 +`endif +`ifdef SPI_MAX_CHAR_8 + `define SPI_MAX_CHAR 8 // Can be set from 1 to 8 + `define SPI_CHAR_LEN_BITS 3 +`endif + +// +// Number of device select signals. Use SPI_SS_NB for fine tuning the +// exact number. +// +`define SPI_SS_NB_8 +//`define SPI_SS_NB_16 +//`define SPI_SS_NB_24 +//`define SPI_SS_NB_32 + +`ifdef SPI_SS_NB_8 + `define SPI_SS_NB 8 // Can be set from 1 to 8 +`endif +`ifdef SPI_SS_NB_16 + `define SPI_SS_NB 16 // Can be set from 9 to 16 +`endif +`ifdef SPI_SS_NB_24 + `define SPI_SS_NB 24 // Can be set from 17 to 24 +`endif +`ifdef SPI_SS_NB_32 + `define SPI_SS_NB 32 // Can be set from 25 to 32 +`endif + +// +// Bits of WISHBONE address used for partial decoding of SPI registers. +// +`define SPI_OFS_BITS 4:2 + +// +// Register offset +// +`define SPI_RX_0 0 +`define SPI_RX_1 1 +`define SPI_RX_2 2 +`define SPI_RX_3 3 +`define SPI_TX_0 0 +`define SPI_TX_1 1 +`define SPI_TX_2 2 +`define SPI_TX_3 3 +`define SPI_CTRL 4 +`define SPI_DEVIDE 5 +`define SPI_SS 6 + +// +// Number of bits in ctrl register +// +`define SPI_CTRL_BIT_NB 14 + +// +// Control register bit position +// +`define SPI_CTRL_ASS 13 +`define SPI_CTRL_IE 12 +`define SPI_CTRL_LSB 11 +`define SPI_CTRL_TX_NEGEDGE 10 +`define SPI_CTRL_RX_NEGEDGE 9 +`define SPI_CTRL_GO 8 +`define SPI_CTRL_RES_1 7 +`define SPI_CTRL_CHAR_LEN 6:0 + diff --git a/tests/iwls2005/spi/spi_shift.v b/tests/iwls2005/spi/spi_shift.v new file mode 100644 index 00000000..b17ac8b1 --- /dev/null +++ b/tests/iwls2005/spi/spi_shift.v @@ -0,0 +1,238 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// spi_shift.v //// +//// //// +//// This file is part of the SPI IP core project //// +//// http://www.opencores.org/projects/spi/ //// +//// //// +//// Author(s): //// +//// - Simon Srot (simons@opencores.org) //// +//// //// +//// All additional information is avaliable in the Readme.txt //// +//// file. //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2002 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +`include "spi_defines.v" +`include "timescale.v" + +module spi_shift (clk, rst, latch, byte_sel, len, lsb, go, + pos_edge, neg_edge, rx_negedge, tx_negedge, + tip, last, + p_in, p_out, s_clk, s_in, s_out); + + parameter Tp = 1; + + input clk; // system clock + input rst; // reset + input [3:0] latch; // latch signal for storing the data in shift register + input [3:0] byte_sel; // byte select signals for storing the data in shift register + input [`SPI_CHAR_LEN_BITS-1:0] len; // data len in bits (minus one) + input lsb; // lbs first on the line + input go; // start stansfer + input pos_edge; // recognize posedge of sclk + input neg_edge; // recognize negedge of sclk + input rx_negedge; // s_in is sampled on negative edge + input tx_negedge; // s_out is driven on negative edge + output tip; // transfer in progress + output last; // last bit + input [31:0] p_in; // parallel in + output [`SPI_MAX_CHAR-1:0] p_out; // parallel out + input s_clk; // serial clock + input s_in; // serial in + output s_out; // serial out + + reg s_out; + reg tip; + + reg [`SPI_CHAR_LEN_BITS:0] cnt; // data bit count + reg [`SPI_MAX_CHAR-1:0] data; // shift register + wire [`SPI_CHAR_LEN_BITS:0] tx_bit_pos; // next bit position + wire [`SPI_CHAR_LEN_BITS:0] rx_bit_pos; // next bit position + wire rx_clk; // rx clock enable + wire tx_clk; // tx clock enable + + assign p_out = data; + + assign tx_bit_pos = lsb ? {!(|len), len} - cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1}; + assign rx_bit_pos = lsb ? {!(|len), len} - (rx_negedge ? cnt + {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1} |