def tee(chip, a, out1=None, out2=None): tee_component = Component(""" int out1 = output("out1"); int out2 = output("out2"); int in = input("in"); void main(){ int data; while(1){ data = fgetc(in); fputc(data, out1); fputc(data, out2); } }""", inline=True) if out1 is None: out1 = Wire(chip) if out2 is None: out2 = Wire(chip) tee_component(chip, inputs={"in": a}, outputs={ "out1": out1, "out2": out2 }, parameters={}) return out1, out2
def cycle(chip, args, type_="int", out=None): if out is None: out = Wire(chip) c_component = """ #include <stdio.h> int out = output("out"); void main(){ %s list[%i] = {%s}; int i; %s data; while(1){ for(i=0; i<%i; i++){ data = list[i]; fput_%s(data, out); } } } """ % (type_, len(args), ", ".join(["%s" % i for i in args ]), type_, len(args), type_) cycle_component = Component(c_component, inline=True) cycle_component( chip, inputs={}, outputs={"out": out}, parameters={}, ) return out
def application(chip): application = Component("application.c") server = Component("server.c") arbiter = Component("arbiter.c") socket_tx = Wire(chip) socket_rx = Wire(chip) application_out = Wire(chip) server_out = Wire(chip) arbiter( chip=chip, inputs={ "in1": application_out, "in2": server_out, }, outputs={ "out": chip.outputs["output_rs232_tx"], }, ) application( chip=chip, inputs={ "socket": socket_rx, "rs232_rx": chip.inputs["input_rs232_rx"], "switches": chip.inputs["input_switches"], "buttons": chip.inputs["input_buttons"], }, outputs={ "socket": socket_tx, "rs232_tx": application_out, "leds": chip.outputs["output_leds"], }, ) server(chip=chip, inputs={ "eth_rx": chip.inputs["input_eth_rx"], "socket": socket_tx, }, outputs={ "eth_tx": chip.outputs["output_eth_tx"], "rs232_tx": server_out, "socket": socket_rx, })
def async (chip, a, out=None): if out is None: out = Wire(chip) async = Component("""void main(){ int in = input("in"); int out = output("out"); int data; while(1){ if(ready(in)){ data = fgetc(in); } if(ready(out)){ fputc(data, out); } } }""", inline=True) async (chip, inputs={"in": a}, outputs={"out": out}, parameters={}) return out
def delay(chip, a, initial=0, type_="int", out=None): delay_component = Component(""" #include <stdio.h> int out = output("out"); int in = input("in"); void main(){ fput_%s(INITIAL, out); while(1){ fput_%s(fget_%s(in), out); } }""" % (type_, type_, type_), inline=True) if out is None: out = Wire(chip) delay_component(chip, inputs={"in": a}, outputs={"out": out}, parameters={"INITIAL": initial}) return out
def _comparison(chip, a, b, operation, type_="int", out=None): if out is None: out = Wire(chip) code = """ #include <stdio.h> int out = output("out"); int in1 = input("in1"); int in2 = input("in2"); void main(){ while(1){ fput_int(fget_%s(in1) %s fget_%s(in2), out); } }""" % (type_, operation, type_) comparison = Component(code, inline=True) comparison(chip, inputs={ "in1": a, "in2": b }, outputs={"out": out}, parameters={}) return out
def tree_combine(chip, component, args, out): children = list(args) while len(children) > 2: parents = [] while len(children) > 2: wire = Wire(chip) component(chip, inputs={ "in1": children.pop(), "in2": children.pop(0) }, outputs={"out": wire}, parameters={}) parents.append(wire) parents.append(children.pop(0)) children = parents component(chip, inputs={ "in1": children.pop(), "in2": children.pop(0) }, outputs={"out": out}, parameters={})
def _arithmetic(chip, a, b, operation, type_="int", out=None): if out is None: out = Wire(chip) arithmetic_component = Component(""" #include <stdio.h> /* Adder component model */ int out = output("out"); int in1 = input("in1"); int in2 = input("in2"); void main(){ while(1){ fput_%s(fget_%s(in1) %s fget_%s(in2), out); } }""" % (type_, type_, operation, type_), inline=True) arithmetic_component(chip, inputs={ "in1": a, "in2": b }, outputs={"out": out}, parameters={}) return out
def arbiter(chip, streams, out=None): """ Merge many streams of data into a single stream giving each stream equal priority arguments --------- chip - the chip args - a list (oriterable) of streams of data to combine out=None - a Wire in which to output the arbitrated data if out is None, then a wire will be created. returns ------- stream - a stream of data """ if out is None: out = Wire(chip) arbiter_component = VerilogComponent( C_file=""" int out = output("out"); int in1 = input("in1"); int in2 = input("in2"); void main(){ while(1){ if(ready(in1)) fputc(fgetc(in1), out); if(ready(in2)) fputc(fgetc(in2), out); } }""", V_file="""module {name}(input_in1,input_in2,input_in1_stb,input_in2_stb, output_out_ack,clk,rst,output_out,output_out_stb,input_in1_ack,input_in2_ack,exception); parameter arbitrate_0 = 3'd0, arbitrate_1 = 3'd1, read_0 = 3'd2, read_1 = 3'd3, write_0 = 3'd4, write_1 = 3'd5; input [31:0] input_in1; input [31:0] input_in2; input input_in1_stb; input input_in2_stb; input output_out_ack; input clk; input rst; output [31:0] output_out; output output_out_stb; output input_in1_ack; output input_in2_ack; output exception; reg [31:0] s_output_out_stb; reg [31:0] s_output_out; reg [31:0] s_input_in1_ack; reg [31:0] s_input_in2_ack; reg [31:0] write_value; reg [2:0] state; always @(posedge clk) begin case(state) arbitrate_0: begin state <= arbitrate_1; if (input_in1_stb) begin state <= read_0; end end arbitrate_1: begin state <= arbitrate_0; if (input_in2_stb) begin state <= read_1; end end read_0: begin s_input_in1_ack <= 1; if (s_input_in1_ack && input_in1_stb) begin write_value <= input_in1; s_input_in1_ack <= 0; state <= write_0; end end read_1: begin s_input_in2_ack <= 1; if (s_input_in2_ack && input_in2_stb) begin write_value <= input_in2; s_input_in2_ack <= 0; state <= write_1; end end write_0: begin s_output_out_stb <= 1; s_output_out <= write_value; if (output_out_ack && s_output_out_stb) begin s_output_out_stb <= 0; state <= arbitrate_1; end end write_1: begin s_output_out_stb <= 1; s_output_out <= write_value; if (output_out_ack && s_output_out_stb) begin s_output_out_stb <= 0; state <= arbitrate_0; end end endcase if (rst == 1'b1) begin state <= arbitrate_0; s_input_in1_ack <= 0; s_input_in2_ack <= 0; s_output_out_stb <= 0; end end assign input_in1_ack = s_input_in1_ack; assign input_in2_ack = s_input_in2_ack; assign output_out_stb = s_output_out_stb; assign output_out = s_output_out; assign exception = 0; endmodule""", inline=True) tree_combine(chip, arbiter_component, streams, out) return out
def line_arbiter(chip, streams, out=None): """ Merge many streams of data into a single stream giving each stream equal priority Once a stream is selected by the arbiter, it will remain selected until an entire line has been output. Used to combine text based streams from multiple sources into a single stream, without merging lines. arguments --------- chip - the chip streams - a list (or iterable) of streams of data to combine out=None - Optionaly, an output Wire() object may be passed in. If out is None, then an output wire will be created. returns ------- stream - a stream of data """ if out is None: out = Wire(chip) arbiter_component = VerilogComponent( C_file="""int in1 = input("in1"); int in2 = input("in2"); int out = output("out"); void main(){ int temp; while(1){ if(ready(in1)){ while(1){ temp = fgetc(in1); fputc(temp, out); if(temp == '\\n') break; } } if(ready(in2)){ while(1){ temp = fgetc(in2); fputc(temp, out); if(temp == '\\n') break; } } } } """, V_file="""module {name}(input_in1,input_in2,input_in1_stb,input_in2_stb, output_out_ack,clk,rst,output_out,output_out_stb,input_in1_ack,input_in2_ack,exception); parameter arbitrate_0 = 3'd0, arbitrate_1 = 3'd1, read_0 = 3'd2, read_1 = 3'd3, write_0 = 3'd4, write_1 = 3'd5; input [31:0] input_in1; input [31:0] input_in2; input input_in1_stb; input input_in2_stb; input output_out_ack; input clk; input rst; output [31:0] output_out; output output_out_stb; output input_in1_ack; output input_in2_ack; output exception; reg [31:0] s_output_out_stb; reg [31:0] s_output_out; reg [31:0] s_input_in1_ack; reg [31:0] s_input_in2_ack; reg [31:0] write_value; reg [2:0] state; always @(posedge clk) begin case(state) arbitrate_0: begin state <= arbitrate_1; if (input_in1_stb) begin state <= read_0; end end arbitrate_1: begin state <= arbitrate_0; if (input_in2_stb) begin state <= read_1; end end read_0: begin s_input_in1_ack <= 1; if (s_input_in1_ack && input_in1_stb) begin write_value <= input_in1; s_input_in1_ack <= 0; state <= write_0; end end read_1: begin s_input_in2_ack <= 1; if (s_input_in2_ack && input_in2_stb) begin write_value <= input_in2; s_input_in2_ack <= 0; state <= write_1; end end write_0: begin s_output_out_stb <= 1; s_output_out <= write_value; if (output_out_ack && s_output_out_stb) begin s_output_out_stb <= 0; if (write_value == 10) begin state <= arbitrate_1; end else begin state <= read_0; end end end write_1: begin s_output_out_stb <= 1; s_output_out <= write_value; if (output_out_ack && s_output_out_stb) begin s_output_out_stb <= 0; if (write_value == 10) begin state <= arbitrate_0; end else begin state <= read_1; end end end endcase if (rst == 1'b1) begin state <= arbitrate_0; s_input_in1_ack <= 0; s_input_in2_ack <= 0; s_output_out_stb <= 0; end end assign input_in1_ack = s_input_in1_ack; assign input_in2_ack = s_input_in2_ack; assign output_out_stb = s_output_out_stb; assign output_out = s_output_out; assign exception = 0; endmodule""", inline=True) tree_combine(chip, arbiter_component, streams, out) return out
def constant(chip, value, type_="int", out=None): if out is None: out = Wire(chip) verilog_value = value if type_ in ["int", "float"]: if type_ == "float": verilog_value = float_to_bits(value) verilog_file = """ module {name} (output_out_ack,clk,rst,output_out,output_out_stb,exception); input output_out_ack; input clk; input rst; output [31:0] output_out; output output_out_stb; output exception; assign output_out = %s; assign output_out_stb = 1; assign exception = 0; endmodule """ % verilog_value elif type_ in ["long", "double"]: high, low = split_word(value) if type_ == "double": high, low = split_word(double_to_bits(value)) verilog_file = """ module {name} (output_out_ack,clk,rst,output_out,output_out_stb,exception); input output_out_ack; input clk; input rst; output [31:0] output_out; output output_out_stb; output exception; reg [31:0] s_output_out_stb; reg [31:0] s_output_out; reg high; always @(posedge clk) begin if (high) begin s_output_out_stb <= 1; s_output_out <= %s; if (output_out_ack && s_output_out_stb) begin s_output_out_stb <= 0; high <= 0; end end else begin s_output_out_stb <= 1; s_output_out <= %s; if (output_out_ack && s_output_out_stb) begin s_output_out_stb <= 0; high <= 1; end end if (rst == 1'b1) begin high <= 0; s_output_out_stb <= 0; end end assign output_out = s_output_out; assign output_out_stb = s_output_out_stb; assign exception = 0; endmodule """ % (high, low) constant_component = VerilogComponent(C_file=""" #include <stdio.h> int out = output("out"); void main(){ while(1){ fput_%s(%s, out); } } """ % (type_, value), V_file=verilog_file, inline=True) constant_component( chip, inputs={}, outputs={"out": out}, parameters={}, ) return out
def server(chip, ethernet_rx, ethernet_tx, application_in, application_out, console_out): ip_rx = Component("ip_rx.c", options={"memory_size": 64}) ip_tx = Component("ip_tx.c", options={"memory_size": 256}) icmp = Component("icmp.c", options={"memory_size": 1024}) decoupler = Component("decoupler.c", options={"memory_size": 64}) tcp_rx = Component("tcp_rx.c", options={"memory_size": 256}) tcp_tx = Component("tcp_tx.c", options={"memory_size": 1024}) icmp_in = Wire(chip) icmp_out = Wire(chip) arp = Wire(chip) tcp_in = Wire(chip) tcp_out = Wire(chip) tcp_decoupler_in = Wire(chip) tcp_decoupler_out = Wire(chip) stdout = [Wire(chip) for i in range(5)] ip_rx(chip=chip, inputs={ "ethernet_in": ethernet_rx, }, outputs={ "icmp_out": icmp_in, "tcp_out": tcp_in, "arp": arp, "cout": stdout[0], }, parameters={}) ip_tx(chip=chip, inputs={ "icmp_in": icmp_out, "tcp_in": tcp_out, "arp": arp, }, outputs={ "ethernet_out": ethernet_tx, "cout": stdout[1], }, parameters={}) icmp(chip=chip, inputs={ "icmp_in": icmp_in, }, outputs={ "icmp_out": icmp_out, "cout": stdout[2] }, parameters={}) decoupler(chip=chip, inputs={ "tcp_in": tcp_decoupler_in, }, outputs={ "tcp_out": tcp_decoupler_out, }, parameters={}) tcp_rx(chip=chip, inputs={ "tcp_in": tcp_in, }, outputs={ "tcp_out": tcp_decoupler_in, "application_out": application_out, "cout": stdout[3] }, parameters={}) tcp_tx(chip=chip, inputs={ "application_in": application_in, "tcp_in": tcp_decoupler_out, }, outputs={ "tcp_out": tcp_out, "cout": stdout[4] }, parameters={}) line_arbiter(chip, stdout, console_out)
outputs={ "tcp_out": tcp_out, "cout": stdout[4] }, parameters={}) line_arbiter(chip, stdout, console_out) if __name__ == "__main__": import sys from demo.io_models.network import VirtualNetworkCard, NetworkIn, NetworkOut from demo.io_models.console import ConsoleOut from chips.components.components import constant from chips.utils.debugger import Debugger from chips.compiler.exceptions import C2CHIPError from chips.api.gui import GuiChip try: vnc = VirtualNetworkCard() chip = Chip("server") wire = Wire(chip) server(chip, NetworkIn(chip, "eth_in", vnc), NetworkOut(chip, "eth_out", vnc), wire, wire, ConsoleOut(chip, "stdout")) Debugger(chip) except C2CHIPError as e: print e.message
def tee(chip, a, out1=None, out2=None): verilog_file = """ module {name} (clk,rst,exception, input_in, input_in_stb, input_in_ack, output_out1, output_out1_stb, output_out1_ack, output_out2, output_out2_stb, output_out2_ack); input clk; input rst; output exception; input [31:0] input_in; input input_in_stb; output input_in_ack; output reg [31:0] output_out1; output output_out1_stb; input output_out1_ack; output reg [31:0] output_out2; output output_out2_stb; input output_out2_ack; reg s_output_out1_stb; reg s_output_out2_stb; wire s_input_in_ack; always @(posedge clk) begin if (s_input_in_ack & input_in_stb) begin s_output_out1_stb <= 1; s_output_out2_stb <= 1; output_out1 <= input_in; output_out2 <= input_in; end else begin if (output_out1_ack) begin s_output_out1_stb <= 0; end if (output_out2_ack) begin s_output_out2_stb <= 0; end end if (rst == 1'b1) begin s_output_out1_stb <= 0; s_output_out2_stb <= 0; end end assign s_input_in_ack = (output_out1_ack | (~s_output_out1_stb)) & (output_out2_ack | (~s_output_out2_stb)); assign input_in_ack = s_input_in_ack; assign output_out1_stb = s_output_out1_stb; assign output_out2_stb = s_output_out2_stb; assign exception = 0; endmodule """ tee_component = VerilogComponent(""" int out1 = output("out1"); int out2 = output("out2"); int in = input("in"); void main(){ int data; while(1){ data = fgetc(in); fputc(data, out1); fputc(data, out2); } }""", V_file=verilog_file, inline=True) if out1 is None: out1 = Wire(chip) if out2 is None: out2 = Wire(chip) tee_component(chip, inputs={"in": a}, outputs={ "out1": out1, "out2": out2 }, parameters={}) return out1, out2