<filename>rif_template.py
header = """/*
 Icebreaker and IceSugar RSMB5 project - RV32I for Lattice iCE40
 With complete open-source toolchain flow using:
 -> yosys 
 -> icarus verilog
 -> icestorm project

 Tests are written in several languages
 -> Systemverilog Pure Testbench (Vivado)
 -> UVM testbench (Vivado)
 -> PyUvm (Icarus)
 -> Formal either using SVA and PSL (Vivado) or cuncurrent assertions with Yosys

 Copyright (c) 2021 <NAME> (<EMAIL>)

 Permission is hereby granted, free of charge, to any person obtaining a 
 copy of this software and associated documentation files (the "Software"), 
 to deal in the Software without restriction, including without limitation 
 the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 and/or sell copies of the Software, and to permit persons to whom the 
 Software is furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included 
 in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

/* 
  This file contains register parameters and is autogenerated
*/
"""

sv_inclusion = """
`ifndef COCOTB_SIM
// Main Inclusion
`else
// Main Inclusion
`endif
"""

module_name_param = """
// Main Module
module gen_rif #(
	// Parameter Declaration
	parameter REG_WIDTH 			      = 32,
	parameter ERROUT_IF_NOT_ACCESS	= 1
  )"""

standard_rif_input_ports = """
  (
	// Port Declaration
	// General RIF input port
	input logic 					        rif_clk,    				// Clock
	input logic 					        rif_arst,   				// Asynchronous reset active high
	input logic 					        rif_write,  				// If 0 -> Read if 1 -> Write
	input logic 					        rif_cs,     				// States if the slave has been properly selected 
  input logic [REG_WIDTH-1:0] 	rif_addr, 					// Address coming into the bus
	input logic [REG_WIDTH-1:0] 	rif_wdata,  				// Write Data coming into the bus"""

hw_write_template_port = """
  input logic [REG_WIDTH-1:0] 	$input_port_hw_rw_access_name,"""

hw_read_template_port = """
  output logic [REG_WIDTH-1:0]  $output_port_hw_rw_access_name,"""

standard_rif_output_ports = """
	// General RIF output ports
	output logic [REG_WIDTH-1:0]	rif_rdata,  				// Read Data coming out the bus
	output logic 				  	      rif_error,  				// Give error in few specific conditions only 
	output logic 					        rif_ready   				// Is controlled by the slave and claims if the specifc slave is busy or not
);"""

set_of_decoder_flags = """
    logic $dec_val;""" 

set_register = """
    logic [REG_WIDTH-1:0] $reg_rw;"""

internal_additional_signals = """
    // Register Access Process
    logic error_handler, error_access;
    logic wr_rq, rd_rq;

    // Register decoder we are addressing 1Word at time so remove the first 2 bits
    logic [REG_WIDTH-1:0] reg_dec, reg_dec_dly;"""

internal_decoder_signals_generation =  """
    assign reg_dec = rif_addr >> 2;
    always_ff@(posedge rif_clk or posedge rif_arst) begin
      if(rif_arst)  reg_dec_dly <= 'h0;
      else      	  reg_dec_dly <= reg_dec;
    end"""

internal_wr_rd_request = """

  	// Assign the WR_REQUEST and RD_REQUEST
  	assign wr_rq = rif_write & rif_cs;
  	assign rd_rq = ~rif_write & rif_cs;

  	// Register the request to be used for the READY signal
  	logic [1:0] regsistered_request;
  	always_ff @(posedge rif_clk or posedge rif_arst) begin : request_reg
  		if(rif_arst) begin
  			regsistered_request <= 2'b11;
  		end else begin
  			// Regardless of the read of write request we have to register the CS
  			regsistered_request[0] <= (~rif_cs);
  			regsistered_request[1] <= regsistered_request[0];
  		end
  	end
"""

initialize_decoder_state = """
  	// Address decoding with full combo logic
  	always_comb begin: addres_decoding
  		// Initialize
    	error_access      = 1'b0;"""

init_dec_access = """
		  $dec_val     	  = 1'b0;"""

case_switch_over_address = """
    	// Select using the address
    	case (rif_addr)"""

selection = """
    		$define_name: 			begin $dec_val = 1'b1; end"""

defualt_end_case = """
    		default: begin 
    			if(ERROUT_IF_NOT_ACCESS)	error_access = 1'b1;
    			else 										 	error_access = 1'b0;
    		end
    	endcase // Endcase
  	end // addres_decoding
"""

initialize_write_decoder_std = """
    // Register write access
    always_ff @(posedge rif_clk or posedge rif_arst) begin : proc_reg_write_access
      if(rif_arst) begin
        rif_rdata			<= 'h0;"""

initialize_write_decoder_init_start = """
        $reg_name 			<= $reset_val; """

initialize_write_decoder_init_end = """
      end 
      else begin: reg_write_decoder"""

register_write_decoder_start = """
      	// Logic for HW = R and SW = RW
      	if($dec_val) begin
          if(wr_rq) begin
          	$reg_name 			<= rif_wdata & $sw_write_mask;
          end
        end"""

register_write_decoder_end = """
    end // proc_reg_write_access
"""

errorr_handler_logic_start = """
    // check the error using COMBO logic to fire an error if RD happens on a RO register
    always_comb begin: read_process_error_handle"""

errorr_handler_logic = """
        // Logic for HW = W and SW = RO
        if($dec_val) begin
          if(wr_rq) begin
                error_handler   = 1'b1;
          end
          else if(rd_rq) begin
                rif_rdata         = $read_reg & $sw_read_mask;
                error_handler   = 1'b0;
          end           
        end"""

errorr_handler_logic_end = """
    end // read_process_error_handle
"""

errorr_handler_write_logic_start = """
    // check the error using COMBO logic to fire an error if RD happens on a WO register
    always_comb begin: write_process_error_handle"""

errorr_handler_write_logic = """
        // Logic for HW = R and SW = WO
        if($dec_val) begin
          if(rd_rq) begin
                error_handler   = 1'b1;
                rif_rdata       = 'h0'
          end
          else begin
                error_handler   = 1'b0;
          end        
        end"""

errorr_handler_write_logic_end = """
    end // write_process_error_handle
"""

internal_latest_assignement = """
    // assign the Error output
    assign rif_error = rif_cs ? (error_handler | error_access) : 'h0;

    // Assign the ready signal
    assign rif_ready = &(regsistered_request);
"""

assign_for_hw_read_policy_reg = """
    assign $out_port = rif_cs ? ($reg_name & $hw_read_mask) : 'h0;"""

assign_for_hw_write_policy_reg = """
    assign $reg_name 	= $in_port & $hw_write_mask;"""

end_module_rif = """
endmodule : gen_rif"""
<filename>rif_template.py
header = """/*
 Icebreaker and IceSugar RSMB5 project - RV32I for Lattice iCE40
 With complete open-source toolchain flow using:
 -> yosys 
 -> icarus verilog
 -> icestorm project

 Tests are written in several languages
 -> Systemverilog Pure Testbench (Vivado)
 -> UVM testbench (Vivado)
 -> PyUvm (Icarus)
 -> Formal either using SVA and PSL (Vivado) or cuncurrent assertions with Yosys

 Copyright (c) 2021 <NAME> (<EMAIL>)

 Permission is hereby granted, free of charge, to any person obtaining a 
 copy of this software and associated documentation files (the "Software"), 
 to deal in the Software without restriction, including without limitation 
 the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 and/or sell copies of the Software, and to permit persons to whom the 
 Software is furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included 
 in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 
 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 
 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

/* 
  This file contains register parameters and is autogenerated
*/
"""

sv_inclusion = """
`ifndef COCOTB_SIM
// Main Inclusion
`else
// Main Inclusion
`endif
"""

module_name_param = """
// Main Module
module gen_rif #(
	// Parameter Declaration
	parameter REG_WIDTH 			      = 32,
	parameter ERROUT_IF_NOT_ACCESS	= 1
  )"""

standard_rif_input_ports = """
  (
	// Port Declaration
	// General RIF input port
	input logic 					        rif_clk,    				// Clock
	input logic 					        rif_arst,   				// Asynchronous reset active high
	input logic 					        rif_write,  				// If 0 -> Read if 1 -> Write
	input logic 					        rif_cs,     				// States if the slave has been properly selected 
  input logic [REG_WIDTH-1:0] 	rif_addr, 					// Address coming into the bus
	input logic [REG_WIDTH-1:0] 	rif_wdata,  				// Write Data coming into the bus"""

hw_write_template_port = """
  input logic [REG_WIDTH-1:0] 	$input_port_hw_rw_access_name,"""

hw_read_template_port = """
  output logic [REG_WIDTH-1:0]  $output_port_hw_rw_access_name,"""

standard_rif_output_ports = """
	// General RIF output ports
	output logic [REG_WIDTH-1:0]	rif_rdata,  				// Read Data coming out the bus
	output logic 				  	      rif_error,  				// Give error in few specific conditions only 
	output logic 					        rif_ready   				// Is controlled by the slave and claims if the specifc slave is busy or not
);"""

set_of_decoder_flags = """
    logic $dec_val;""" 

set_register = """
    logic [REG_WIDTH-1:0] $reg_rw;"""

internal_additional_signals = """
    // Register Access Process
    logic error_handler, error_access;
    logic wr_rq, rd_rq;

    // Register decoder we are addressing 1Word at time so remove the first 2 bits
    logic [REG_WIDTH-1:0] reg_dec, reg_dec_dly;"""

internal_decoder_signals_generation =  """
    assign reg_dec = rif_addr >> 2;
    always_ff@(posedge rif_clk or posedge rif_arst) begin
      if(rif_arst)  reg_dec_dly <= 'h0;
      else      	  reg_dec_dly <= reg_dec;
    end"""

internal_wr_rd_request = """

  	// Assign the WR_REQUEST and RD_REQUEST
  	assign wr_rq = rif_write & rif_cs;
  	assign rd_rq = ~rif_write & rif_cs;

  	// Register the request to be used for the READY signal
  	logic [1:0] regsistered_request;
  	always_ff @(posedge rif_clk or posedge rif_arst) begin : request_reg
  		if(rif_arst) begin
  			regsistered_request <= 2'b11;
  		end else begin
  			// Regardless of the read of write request we have to register the CS
  			regsistered_request[0] <= (~rif_cs);
  			regsistered_request[1] <= regsistered_request[0];
  		end
  	end
"""

initialize_decoder_state = """
  	// Address decoding with full combo logic
  	always_comb begin: addres_decoding
  		// Initialize
    	error_access      = 1'b0;"""

init_dec_access = """
		  $dec_val     	  = 1'b0;"""

case_switch_over_address = """
    	// Select using the address
    	case (rif_addr)"""

selection = """
    		$define_name: 			begin $dec_val = 1'b1; end"""

defualt_end_case = """
    		default: begin 
    			if(ERROUT_IF_NOT_ACCESS)	error_access = 1'b1;
    			else 										 	error_access = 1'b0;
    		end
    	endcase // Endcase
  	end // addres_decoding
"""

initialize_write_decoder_std = """
    // Register write access
    always_ff @(posedge rif_clk or posedge rif_arst) begin : proc_reg_write_access
      if(rif_arst) begin
        rif_rdata			<= 'h0;"""

initialize_write_decoder_init_start = """
        $reg_name 			<= $reset_val; """

initialize_write_decoder_init_end = """
      end 
      else begin: reg_write_decoder"""

register_write_decoder_start = """
      	// Logic for HW = R and SW = RW
      	if($dec_val) begin
          if(wr_rq) begin
          	$reg_name 			<= rif_wdata & $sw_write_mask;
          end
        end"""

register_write_decoder_end = """
    end // proc_reg_write_access
"""

errorr_handler_logic_start = """
    // check the error using COMBO logic to fire an error if RD happens on a RO register
    always_comb begin: read_process_error_handle"""

errorr_handler_logic = """
        // Logic for HW = W and SW = RO
        if($dec_val) begin
          if(wr_rq) begin
                error_handler   = 1'b1;
          end
          else if(rd_rq) begin
                rif_rdata         = $read_reg & $sw_read_mask;
                error_handler   = 1'b0;
          end           
        end"""

errorr_handler_logic_end = """
    end // read_process_error_handle
"""

errorr_handler_write_logic_start = """
    // check the error using COMBO logic to fire an error if RD happens on a WO register
    always_comb begin: write_process_error_handle"""

errorr_handler_write_logic = """
        // Logic for HW = R and SW = WO
        if($dec_val) begin
          if(rd_rq) begin
                error_handler   = 1'b1;
                rif_rdata       = 'h0'
          end
          else begin
                error_handler   = 1'b0;
          end        
        end"""

errorr_handler_write_logic_end = """
    end // write_process_error_handle
"""

internal_latest_assignement = """
    // assign the Error output
    assign rif_error = rif_cs ? (error_handler | error_access) : 'h0;

    // Assign the ready signal
    assign rif_ready = &(regsistered_request);
"""

assign_for_hw_read_policy_reg = """
    assign $out_port = rif_cs ? ($reg_name & $hw_read_mask) : 'h0;"""

assign_for_hw_write_policy_reg = """
    assign $reg_name 	= $in_port & $hw_write_mask;"""

end_module_rif = """
endmodule : gen_rif"""
/*  Icebreaker and IceSugar RSMB5 project - RV32I for Lattice iCE40  With complete open-source toolchain flow using:  -> yosys   -> icarus verilog  -> icestorm project   Tests are written in several languages  -> Systemverilog Pure Testbench (Vivado)  -> UVM testbench (Vivado)  -> PyUvm (Icarus)  -> Formal either using SVA and PSL (Vivado) or cuncurrent assertions with Yosys   Copyright (c) 2021 <NAME> (<EMAIL>)   Permission is hereby granted, free of charge, to any person obtaining a   copy of this software and associated documentation files (the "Software"),   to deal in the Software without restriction, including without limitation   the rights to use, copy, modify, merge, publish, distribute, sublicense,   and/or sell copies of the Software, and to permit persons to whom the   Software is furnished to do so, subject to the following conditions:   The above copyright notice and this permission notice shall be included   in all copies or substantial portions of the Software.   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */  /*    This file contains register parameters and is autogenerated */ `ifndef COCOTB_SIM // Main Inclusion `else // Main Inclusion `endif // Main Module module gen_rif #( 	// Parameter Declaration 	parameter REG_WIDTH 			      = 32, 	parameter ERROUT_IF_NOT_ACCESS	= 1   ) ( 	// Port Declaration 	// General RIF input port 	input logic 					        rif_clk,    				// Clock 	input logic 					        rif_arst,   				// Asynchronous reset active high 	input logic 					        rif_write,  				// If 0 -> Read if 1 -> Write 	input logic 					        rif_cs,     				// States if the slave has been properly selected    input logic [REG_WIDTH-1:0] 	rif_addr, 					// Address coming into the bus 	input logic [REG_WIDTH-1:0] 	rif_wdata,  				// Write Data coming into the bus input logic [REG_WIDTH-1:0] 	$input_port_hw_rw_access_name, output logic [REG_WIDTH-1:0]  $output_port_hw_rw_access_name, // General RIF output ports 	output logic [REG_WIDTH-1:0]	rif_rdata,  				// Read Data coming out the bus 	output logic 				  	      rif_error,  				// Give error in few specific conditions only  	output logic 					        rif_ready   				// Is controlled by the slave and claims if the specifc slave is busy or not ); logic $dec_val; logic [REG_WIDTH-1:0] $reg_rw; // Register Access Process     logic error_handler, error_access;     logic wr_rq, rd_rq;      // Register decoder we are addressing 1Word at time so remove the first 2 bits     logic [REG_WIDTH-1:0] reg_dec, reg_dec_dly; assign reg_dec = rif_addr >> 2;     always_ff@(posedge rif_clk or posedge rif_arst) begin       if(rif_arst)  reg_dec_dly <= 'h0;       else      	  reg_dec_dly <= reg_dec;     end // Assign the WR_REQUEST and RD_REQUEST   	assign wr_rq = rif_write & rif_cs;   	assign rd_rq = ~rif_write & rif_cs;    	// Register the request to be used for the READY signal   	logic [1:0] regsistered_request;   	always_ff @(posedge rif_clk or posedge rif_arst) begin : request_reg   		if(rif_arst) begin   			regsistered_request <= 2'b11;   		end else begin   			// Regardless of the read of write request we have to register the CS   			regsistered_request[0] <= (~rif_cs);   			regsistered_request[1] <= regsistered_request[0];   		end   	end // Address decoding with full combo logic   	always_comb begin: addres_decoding   		// Initialize     	error_access      = 1'b0; $dec_val     	  = 1'b0; // Select using the address     	case (rif_addr) $define_name: 			begin $dec_val = 1'b1; end default: begin      			if(ERROUT_IF_NOT_ACCESS)	error_access = 1'b1;     			else 										 	error_access = 1'b0;     		end     	endcase // Endcase   	end // addres_decoding // Register write access     always_ff @(posedge rif_clk or posedge rif_arst) begin : proc_reg_write_access       if(rif_arst) begin         rif_rdata			<= 'h0; $reg_name 			<= $reset_val; end        else begin: reg_write_decoder // Logic for HW = R and SW = RW       	if($dec_val) begin           if(wr_rq) begin           	$reg_name 			<= rif_wdata & $sw_write_mask;           end         end end // proc_reg_write_access // check the error using COMBO logic to fire an error if RD happens on a RO register     always_comb begin: read_process_error_handle // Logic for HW = W and SW = RO         if($dec_val) begin           if(wr_rq) begin                 error_handler   = 1'b1;           end           else if(rd_rq) begin                 rif_rdata         = $read_reg & $sw_read_mask;                 error_handler   = 1'b0;           end                    end end // read_process_error_handle // check the error using COMBO logic to fire an error if RD happens on a WO register     always_comb begin: write_process_error_handle // Logic for HW = R and SW = WO         if($dec_val) begin           if(rd_rq) begin                 error_handler   = 1'b1;                 rif_rdata       = 'h0'           end           else begin                 error_handler   = 1'b0;           end                 end end // write_process_error_handle // assign the Error output     assign rif_error = rif_cs ? (error_handler | error_access) : 'h0;      // Assign the ready signal     assign rif_ready = &(regsistered_request); assign $out_port = rif_cs ? ($reg_name & $hw_read_mask) : 'h0; assign $reg_name 	= $in_port & $hw_write_mask; endmodule : gen_rif