def discard(chip, a): """Discard a stream of data. arguments --------- chip - the chip a - the stream of data to discard returns ------- N/A """ discard_component = VerilogComponent(C_file="""/* Discard Component */ int in = input("in"); void main(){ while(1){ fgetc(in); } }""", V_file=""" //Discard stream contents module {name} (input_in_ack,clk,rst,input_in,input_in_stb,exception); input clk; input rst; input [31:0] input_in; input input_in_stb; output input_in_ack; output exception; assign input_in_ack = 1; assign exception = 0; endmodule """, inline=True) discard_component(chip, inputs={"in": a}, outputs={}, parameters={})
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 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 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 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