Intellectual Highway realizes IP core development in a short period of time by utilizing RTL design technology by C/C++ (C2RTL technology) developed at Tokyo Institute of Technology.

 

About C2RTL

Developed by Tokyo Institute of Technology, C2RTL is a technology that enables RTL description in the C/C++ language.
From the source code written in C/C++, a synthesizable Verilog code, a C language simulation model equivalent to the Verilog code, and a test bench are generated at the same time.
By using C2RTL, the development efficiency of IP cores and SoC can be dramatically improved.

Features of C2RTL

  • C/C++ description

    Highly abstract description by software, high reusability, and flexible parameterization are possible. Unlike general high-level synthesis described in the C/C++ language, the RTL description is expressed in C/C++ as it is, so the performance of the logical circuit can be maximized.

  • Effective for Processor and SoC design

    C2RTL enable auto 'pipelining' the processor behavior as multi cycles processing, then Processor design becomes significantly easy. Moreover, C2RTL can be used not only for designing a single IP core, but also for designing an SoC that integrates multiple IP cores developed by C2RTL.

  • Fast development

    Since the C language model equivalent to RTL generated by C2RTL is written in C language, high-speed cycle accuracy simulation is possible.
    Simulation with the equivalent C language model can improve development productivity by leveraging existing software tools.

Example code by C2RTL

Here is an example of code that generates a FIFO.
This code allows you to use the FIFO depth and user-defined structs as type parameters during instantiation.
In this way, you can use powerful C ++ abstract expressions such as inheritance, templates, compile-time processing functions, and type inference rather than writing in Verilog (System Verilog) or VHDL. With a small amount of code, you can create a very reusable module.
Also, unlike high-level synthesis, the control of cycle level and register transfer level is described directly, so there is no unintended delay or parallel circuit.


#include "c2r_constexpr.hpp"
#include "c2r_typedef.hpp"

template 
struct FifoIF {
  BIT ren;
  BIT wen;
  BIT empty;
  BIT full;
  T din;
  T dout;
} _TYPE(direct_signal);

template 
class FifoL {
private:
  T dbuf[depth] _TYPE(state);
  UintxType ridx _BWT(idx_w) _TYPE(state); // current read index
  UintxType widx _BWT(idx_w) _TYPE(state); // current write index

public:
  void run(FifoIF& fifo_if) {
    BIT empty = (ridx == widx) ? 1 : 0;
    BIT full = ((ridx ^ widx) == depth) ? 1 : 0;
    fifo_if.empty = empty;
    fifo_if.full = full;

    int oidx = ridx & C2R_MAXVAL((idx_w - 1));
    fifo_if.dout = dbuf[oidx];
    if (fifo_if.ren == 1 & empty) {
      ridx = (ridx + 1) & (C2R_MAXVAL(idx_w));
    }
    if (fifo_if.wen == 1 & full) {
      int iidx = widx & C2R_MAXVAL((idx_w - 1));
      dbuf[iidx] = fifo_if.din;
      widx = (widx + 1) & (C2R_MAXVAL(idx_w));
    }
  }
};

Module instantiation.


struct DataSt {
  BIT flag;
  unsigned short data;
};

_C2R_FUNC(1)
void Sfifo(FifoIF& fifo_if) {
  static FifoL inst;
  inst.run(fifo_if);
}

The following RTL will be generated in a compile time of about 0.4 seconds.

module Sfifo_no_mem   (
    /* global inputs*/
    clk, rst_n,

    /*inputs*/
    G_fifo_if_ren, G_fifo_if_wen, G_fifo_if_din_flag, G_fifo_if_din_data, 

    /*outputs*/
    G_fifo_if_empty, G_fifo_if_full, G_fifo_if_dout_flag, G_fifo_if_dout_data, 

    /*probes*/
    _prb_Sfifo_pSetup

  );
  parameter M_ID = 0; // module ID

  
  /*input ports*/
  input        clk;
  input        rst_n;
  input        G_fifo_if_ren     ; /// <0,1> [U1]     ;
  input        G_fifo_if_wen     ; /// <0,1> [U1]     ;
  input        G_fifo_if_din_flag; /// <0,1> [U1]     ;
  input [15:0] G_fifo_if_din_data; /// <0,65535> [U16];

  /*output ports*/
  output       G_fifo_if_empty    ; /// <0,1> [U1]     ;
  output       G_fifo_if_full     ; /// <0,1> [U1]     ;
  output       G_fifo_if_dout_flag; /// <0,1> [U1]     ;
  output[15:0] G_fifo_if_dout_data; /// <0,65535> [U16];

  /*probe ports*/
  output       _prb_Sfifo_pSetup;

  wire      ROOT_CP = 1'b1; /// root control path (always active)

  wire      Sfifo_pSetup = 1'b1; /// pipeStageCount = 1

  reg       G_Sfifo_inst_dbuf_0_flag;
  reg[15:0] G_Sfifo_inst_dbuf_0_data;
  reg       G_Sfifo_inst_dbuf_1_flag;
  reg[15:0] G_Sfifo_inst_dbuf_1_data;
  reg       G_Sfifo_inst_dbuf_2_flag;
  reg[15:0] G_Sfifo_inst_dbuf_2_data;
  reg       G_Sfifo_inst_dbuf_3_flag;
  reg[15:0] G_Sfifo_inst_dbuf_3_data;
  reg[ 1:0] G_Sfifo_inst_ridx, G_Sfifo_inst_widx;



  //// pipe-stage(1) : combinational-logic...

wire       I_run_B1_9          = G_Sfifo_inst_ridx/*prv*/[0]/*&1'h1*/    ; //  (comb-Out)  [F0<0>,B4<0>] <0,1> [U1] P1(./SfifoReg.hpp:L28)
wire       N_07                = I_run_B1_9 & 1'h1                       ; //  (comb-Out)  [F0<0>,B4<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
wire       N_40                = ! N_07                                  ; //  (comb-Out)  [F0<0>,B3<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
wire       N_41         = (N_40) ? G_Sfifo_inst_dbuf_0_flag/*prv*/ : 1'h0; //  (comb-Out) (L1,A1) [F1<0>,B3<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
wire       N_42                = N_07 == 1'h1                            ; //  (comb-Out) (S) [F0<0>,B3<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
wire       N_43         = (N_42) ? G_Sfifo_inst_dbuf_1_flag/*prv*/ : 1'h0; //  (comb-Out) (L1,A1) [F1<0>,B3<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
wire       N_48                = N_41 | N_43                             ; //  (comb-Out) (L1,A1) [F2<0>,B2<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
wire       N_44                = {1'b0,N_07} == 2'h2                     ; //  (comb-Out) (L1,A1,S) [F1<0>,B4<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
wire       N_45         = (N_44) ? G_Sfifo_inst_dbuf_2_flag/*prv*/ : 1'h0; //  (comb-Out) (L1,A1) [F2<0>,B3<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
wire       N_46                = {1'b0,N_07} == 2'h3                     ; //  (comb-Out) (L1,A1,S) [F1<0>,B4<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
wire       N_47         = (N_46) ? G_Sfifo_inst_dbuf_3_flag/*prv*/ : 1'h0; //  (comb-Out) (L1,A1) [F2<0>,B3<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
wire       N_49                = N_45 | N_47                             ; //  (comb-Out) (L1,A1) [F3<0>,B2<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
wire       N_50                = N_48 | N_49                             ; //  (comb-Out) (L1,A1) [F4<0>,B1<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
assign     G_fifo_if_dout_flag = N_50                                    ; //  (comb-Out)  [F4<0>,B0<0>] <0,1> [U1] P1(./SfifoReg.hpp:L29)
wire       I_run_B1_2 = G_Sfifo_inst_ridx/*prv*/ == G_Sfifo_inst_widx/*prv*/; //  (comb-Out/FFSink) (L3,A5,S) [F3<0>,B4<0>] <0,1> [U1] P1(./SfifoReg.hpp:L23)
assign     G_fifo_if_empty     = I_run_B1_2                              ; //  (comb-Out)  [F3<0>,B0<0>] <0,1> [U1] P1(./SfifoReg.hpp:L25)
wire[ 1:0] I_run_B1_4 = G_Sfifo_inst_widx/*prv*/ ^ G_Sfifo_inst_ridx/*prv*/; //  (comb-Out/FFSink) (L2,A4) [F2<0>,B5<0>] <0,3> [U2] P1(./SfifoReg.hpp:L24)
wire       I_run_B1_5          = {1'b0,I_run_B1_4} == 3'h4               ; //  (comb-Out/FFSink) (L2,A2,S) [F4<0>,B3<0>] <0,1> [U1] P1(./SfifoReg.hpp:L24)
assign     G_fifo_if_full      = I_run_B1_5                              ; //  (comb-Out)  [F4<0>,B0<0>] <0,1> [U1] P1(./SfifoReg.hpp:L26)
wire[15:0] N_52        = (N_40) ? G_Sfifo_inst_dbuf_0_data/*prv*/ : 16'h0; //  (comb-Out) (L1,A1) [F1<0>,B3<0>] <0,65535> [U16] P1(./SfifoReg.hpp:L29)
wire[15:0] N_54        = (N_42) ? G_Sfifo_inst_dbuf_1_data/*prv*/ : 16'h0; //  (comb-Out) (L1,A1) [F1<0>,B3<0>] <0,65535> [U16] P1(./SfifoReg.hpp:L29)
wire[15:0] N_59                = N_52 | N_54                             ; //  (comb-Out) (L1,A16) [F2<0>,B2<0>] <0,65535> [U16] P1(./SfifoReg.hpp:L29)
wire[15:0] N_56        = (N_44) ? G_Sfifo_inst_dbuf_2_data/*prv*/ : 16'h0; //  (comb-Out) (L1,A1) [F2<0>,B3<0>] <0,65535> [U16] P1(./SfifoReg.hpp:L29)
wire[15:0] N_58        = (N_46) ? G_Sfifo_inst_dbuf_3_data/*prv*/ : 16'h0; //  (comb-Out) (L1,A1) [F2<0>,B3<0>] <0,65535> [U16] P1(./SfifoReg.hpp:L29)
wire[15:0] N_60                = N_56 | N_58                             ; //  (comb-Out) (L1,A16) [F3<0>,B2<0>] <0,65535> [U16] P1(./SfifoReg.hpp:L29)
wire[15:0] N_61                = N_59 | N_60                             ; //  (comb-Out) (L1,A16) [F4<0>,B1<0>] <0,65535> [U16] P1(./SfifoReg.hpp:L29)
assign     G_fifo_if_dout_data = N_61                                    ; //  (comb-Out)  [F4<0>,B0<0>] <0,65535> [U16] P1(./SfifoReg.hpp:L29)
wire       I_run_B5_1          = G_Sfifo_inst_widx/*prv*/[0]/*&1'h1*/    ; //   [F0<0>,B3<0>] <0,1> [U1] P1(./SfifoReg.hpp:L34)
wire       N_06                = I_run_B5_1 & 1'h1                       ; //   [F0<0>,B3<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       N_10                = ! N_06                                  ; //   [F0<0>,B2<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       I_run_B4_1          = G_fifo_if_wen == 1'h1                   ; //  (S) [F0<0>,B2<0>] <0,1> [U1] P1(./SfifoReg.hpp:L33)
wire       A_62                = N_10 & I_run_B4_1                       ; //  (L1,A1) [F1<0>,B2<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       N_11                = A_62 & I_run_B1_5                       ; //  (L1,A1) [F5<0>,B1<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       N_18                = N_06 == 1'h1                            ; //  (S) [F0<0>,B2<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       A_63                = N_18 & I_run_B4_1                       ; //  (L1,A1) [F1<0>,B2<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       N_19                = A_63 & I_run_B1_5                       ; //  (L1,A1) [F5<0>,B1<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       N_26                = {1'b0,N_06} == 2'h2                     ; //  (L1,A1,S) [F1<0>,B3<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       A_64                = N_26 & I_run_B4_1                       ; //  (L1,A1) [F2<0>,B2<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       N_27                = A_64 & I_run_B1_5                       ; //  (L1,A1) [F5<0>,B1<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       N_34                = {1'b0,N_06} == 2'h3                     ; //  (L1,A1,S) [F1<0>,B3<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       A_65                = N_34 & I_run_B4_1                       ; //  (L1,A1) [F2<0>,B2<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       N_35                = A_65 & I_run_B1_5                       ; //  (L1,A1) [F5<0>,B1<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
wire       I_run_B2_1          = G_fifo_if_ren == 1'h1                   ; //  (S) [F0<0>,B1<0>] <0,1> [U1] P1(./SfifoReg.hpp:L30)
wire       CP_run_B2_F1        = I_run_B1_2 & I_run_B2_1                 ; //  (L1,A1) [F4<0>,B1<0>] <0,1> [U1] P1(./SfifoReg.hpp:L30)
wire[ 2:0] I_run_B3_1          = {1'b0,G_Sfifo_inst_ridx/*prv*/} + 3'h1  ; //  (L2,C3,A9) [F(3,2)<0>,B0<0>] <1,4> [U3] P1(./SfifoReg.hpp:L31)
wire[ 1:0] I_run_B3_2          = I_run_B3_1[1:0]/*&2'h3*/                ; //   [F(3,2)<0>,B0<0>] <0,3> [U2] P1(./SfifoReg.hpp:L31)
wire       CP_run_B4_F1        = I_run_B1_5 & I_run_B4_1                 ; //  (L1,A1) [F5<0>,B1<0>] <0,1> [U1] P1(./SfifoReg.hpp:L33)
wire[ 2:0] I_run_B6_1          = {1'b0,G_Sfifo_inst_widx/*prv*/} + 3'h1  ; //  (L2,C3,A9) [F(3,2)<0>,B0<0>] <1,4> [U3] P1(./SfifoReg.hpp:L36)
wire[ 1:0] I_run_B6_2          = I_run_B6_1[1:0]/*&2'h3*/                ; //   [F(3,2)<0>,B0<0>] <0,3> [U2] P1(./SfifoReg.hpp:L36)


  //// pipe-stage(1) : state-registers...

  always @ (posedge clk or negedge rst_n) begin
  if (rst_n == 1'b0) begin
    G_Sfifo_inst_dbuf_0_flag <= 1'h0 ;
    G_Sfifo_inst_dbuf_0_data <= 16'h0;
    G_Sfifo_inst_dbuf_1_flag <= 1'h0 ;
    G_Sfifo_inst_dbuf_1_data <= 16'h0;
    G_Sfifo_inst_dbuf_2_flag <= 1'h0 ;
    G_Sfifo_inst_dbuf_2_data <= 16'h0;
    G_Sfifo_inst_dbuf_3_flag <= 1'h0 ;
    G_Sfifo_inst_dbuf_3_data <= 16'h0;
    G_Sfifo_inst_ridx        <= 2'h0 ;
    G_Sfifo_inst_widx        <= 2'h0 ;
  end /// (rst_n == 1'b0)
  else begin /*reg-assignments*/
    if (N_11) begin
      G_Sfifo_inst_dbuf_0_flag <= G_fifo_if_din_flag; //  (S,@) [F5<0>,B0<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
      G_Sfifo_inst_dbuf_0_data <= G_fifo_if_din_data; //  (S,@) [F5<0>,B0<0>] <0,65535> [U16] P1(./SfifoReg.hpp:L35)
    end /// (N_11)
    if (N_19) begin
      G_Sfifo_inst_dbuf_1_flag <= G_fifo_if_din_flag; //  (S,@) [F5<0>,B0<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
      G_Sfifo_inst_dbuf_1_data <= G_fifo_if_din_data; //  (S,@) [F5<0>,B0<0>] <0,65535> [U16] P1(./SfifoReg.hpp:L35)
    end /// (N_19)
    if (N_27) begin
      G_Sfifo_inst_dbuf_2_flag <= G_fifo_if_din_flag; //  (S,@) [F5<0>,B0<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
      G_Sfifo_inst_dbuf_2_data <= G_fifo_if_din_data; //  (S,@) [F5<0>,B0<0>] <0,65535> [U16] P1(./SfifoReg.hpp:L35)
    end /// (N_27)
    if (N_35) begin
      G_Sfifo_inst_dbuf_3_flag <= G_fifo_if_din_flag; //  (S,@) [F5<0>,B0<0>] <0,1> [U1] P1(./SfifoReg.hpp:L35)
      G_Sfifo_inst_dbuf_3_data <= G_fifo_if_din_data; //  (S,@) [F5<0>,B0<0>] <0,65535> [U16] P1(./SfifoReg.hpp:L35)
    end /// (N_35)
    if (CP_run_B2_F1)  G_Sfifo_inst_ridx <= I_run_B3_2; //  (S,@) [F4<0>,B0<0>] <0,3> [U2] P1(./SfifoReg.hpp:L31)
    if (CP_run_B4_F1)  G_Sfifo_inst_widx <= I_run_B6_2; //  (S,@) [F5<0>,B0<0>] <0,3> [U2] P1(./SfifoReg.hpp:L36)
  end /// reg-assignments
  end /// always @ ...

  /*probe assignments*/
  assign _prb_Sfifo_pSetup = Sfifo_pSetup;

endmodule // Sfifo_no_mem

C2R Gate

C2R Gate, a tool based on C2RTL technology, is sold by Eureka Inc.
Eureka Inc