void resolve() { shifter(cx); // Shift the palette for this iteration. for(int y = 0; y < imageHeight; ++y) { // In the imaginary axis... double c_im = MaxIm - (y * Im_factor); // The current imaginary is the max value minus the scaled vertical iterator. for(int x=0; x<imageWidth; ++x) { // In the real axis... double c_re = MinRe + (x * Re_factor); // The current real is the min value plus the scaled horizontal iterator. c.real = c_re; c.imag = c_im; // Change the real and imaginary components of the global complex variable c. int iters = fractal(); // The returned value is the escape iterations for the current coordinate col = sf::Color(iters * 4, iters * 4, iters * 4, 255); // Create a color based on the current scape iterations. imagen.setPixel(x, y, col); // Set the image pixel at this current location to that color. } } mandtex.update(imagen); // Update the texture. mandelb.setTexture(mandtex); // Set the texture to the window. }
int main(void){ char *a = "47a1c3a508d4dd527f28ff28195a5990"; printf("%s", shifter(a)); printf("\n%d\n", a[1]); return 0; }
/* main et sc_main La fonction main() est déjà définie par la bibliothèque SystemC. Elle appelle la fonction sc_main, fournie par l'utilisateur, qui est le point d'entrée du code utilisateur. sc_main a le même prototype que main : int sc_main(int argc, char *argv[]); Cette fonction a pour rôle d'instancier tous les modules et signaux nécessaires, et de lancer la simulation. */ int sc_main(int argc, char *argv[]) { int i; /* Déclaration des signaux Le registre à décalage possède trois ports, trois signaux sont donc nécessaires à son test. On instancie donc trois signaux, de type bool (1 bit, en logique 2 valuée). L'horloge a aussi un type sc_signal<bool>. C'est nous qui nous chargerons de la faire bouger. Il existe en SystemC une façon plus propre de générer des horloges, en passant par le type sc_clock. C'est le moteur SystemC qui se charge alors de générer les transitions des objets sc_clock. */ sc_signal<bool> clk; sc_signal<bool> in; sc_signal<bool> out; /* Trace des signaux SystemC dispose de fonction de traçage de signaux au format VCD (Value Change Dump, visible par gtkwave, ... ). SystemC permet de tracer les variables scalaires, les vecteurs de bits, les signaux et certains ports. Pour les objets ne disposant pas de fonctions de traçage (structures, objets, ...) il est toujours possible de définir ses propres fonctions de traçage, qui consistent généralement à tracer les membres de l'objets. Seuls les objets existant pendant toute la simulation peuvent être tracés. En d'autres termes, les variables locales ne sont pas traçables. Avant de tracer un objet, il faut ouvrir un fichier de traces. C'est le but de la fonction sc_create_vcd_trace_file(). Puis on enregistre tous les objets à tracer à l'aide la fonction sc_trace, prenant en argument une référence ou un pointeur vers l'objet à tracer et un nom associé qui sera utilisé dans la génération des chronogrammes. Il est impératif, sous peine de crash, de fermer le fichier de trace avant de retourner de sc_main(). Plusieurs fichiers de traces peuvent être générés en même temps, et un même signal peut être tracé dans plusieurs fichiers à la fois. */ sc_trace_file *my_trace_file; my_trace_file = sc_create_vcd_trace_file ("shift_trace"); sc_trace(my_trace_file, clk, "clk"); sc_trace(my_trace_file, in, "in"); sc_trace(my_trace_file, out, "out"); // sc_trace(my_trace_file, shifter->regs, "regs"); // ??????????????????? /* Instanciation et connexion du module à tester L'instanciation d'un module se fait comme l'instanciation de n'importe quel objet C++. On peut le créer de façon statique comme ici (il prend comme argument celui attendu par son constructeur, c-à-d un nom), ou de façon dynamique à l'aide de new (new est l'équivalent de malloc en C++, il permet d'allouer dynamiquement un objet en passant des arguments à son constructeur). La connexion est faite ici de façon explicite : chaque port et relié explicitement à un signal : shifter.din(in); Il est aussi possible, comme en Verilog ou VHDL, d'utiliser une connexion par position (implicite). */ shifter shifter("reg_decalage"); shifter.clk(clk); shifter.din(in); shifter.dout(out); // connexion par position : shifter(clk, in, out); ??????????????????? /* Lancement de la simulation Une simulation se lance généralement par sc_start, et s'arrête par sc_stop. Comme aucun signal n'est géré automatiquement dans ce système-ci (pas de sc_clock), il faut gérer la simulation manuellement. La simulation peut être initialisée par l'appel de la fonction sc_start(SC_ZERO_TIME), qui se charge alors de faire toutes les initialisations du scheduler SystemC, et d'exécuter une fois tous les processus qui ne sont pas marqués dont_initialize(). Mais cet appel n'est pas obligatoire : il est fait automatiquement pas le scheduler lors du lancement de la simulation s'il n'a pas déjà été fait. Remarque : le fonction sc_initialize() est obsolète, et remplacée par sc_start(SC_ZERO_TIME). Les signaux sont alors positionnés à la main, par une simple affectation (in = 0). Puis le temps est avancé manuellement par la fonction qu'on a appelée next_cycle(), dont le code se trouve en bas du listing : cette fonction positionne manuellement la ligne d'horloge, et fait à chaque fois avancer la simulation d'une unité de temps (1ns) grâce à la fonction sc_start(). */ in = 0; next_cycle(clk); in = 1; next_cycle(clk); next_cycle(clk); in = 0; next_cycle(clk); in = 1; next_cycle(clk); next_cycle(clk); in=0; for(i=0; i<17; i++) next_cycle(clk); sc_close_vcd_trace_file (my_trace_file); return EXIT_SUCCESS; }
int sc_main(int argc , char *argv[]) { sc_signal< sc_uint<NN_DIGIT_BITS> > in_a, in_b; sc_signal< sc_uint<3> > write_select; sc_signal< bool > write_enable; sc_signal< sc_uint<3> > read_a_select, read_b_select; sc_signal< bool > read_enable, input_load; sc_signal< sc_uint<2> > input_mux_select; sc_signal< bool > reg_file_in_mux_select; sc_signal< sc_uint<NN_DIGIT_BITS> > out_a; sc_signal< sc_uint<NN_DIGIT_BITS> > out_b; sc_signal< sc_uint<NN_DIGIT_BITS> > b_high, b_low, c_high, c_low; sc_signal< sc_uint<NN_DIGIT_BITS> > input_reg_value, data_path_calculated_value, regfile_input; sc_signal< sc_uint<2> > adder_mux_select, output_mux_select; sc_signal< bool > mult_enable, adder_enable; sc_signal< bool > shifter_enable, shifter_direction; sc_signal< bool > comp_eq, comp_gt, comp_lt; sc_signal< sc_uint<NN_DIGIT_BITS> > high_1_value, low_1_value, zero_value; sc_signal< sc_uint<NN_DIGIT_BITS> > adder_mux_output, adder_output, shifter_output, mult_output; sc_clock Clk("Clock", 10, SC_NS); Driver driver("driver"); hw_const<NN_DIGIT_BITS> high_1_const("high_1_const", 0x00010000), low_1_const("low_1_const", 0x00000001), zero_const("zero_const", 0x00000000); register_wt_half_index b_reg("b_reg"), c_reg("c_reg"); mux4 input_mux("input_mux"), adder_mux("adder_mux"), output_mux("output_mux"); mux2 reg_file_in_mux("reg_file_in_mux"); register_file reg_file("reg_file"); multiplier mult("mult"); adder add("add"); shifter16 shifter("shifter"); comparator comparison("comparison"); Viewer viewer("viewer"); // Constant Connections high_1_const.output(high_1_value); low_1_const.output(low_1_value); zero_const.output(zero_value); // Driver driver.CLK(Clk); driver.in_a(in_a); driver.in_b(in_b); driver.write_enable(write_enable); driver.write_select(write_select); driver.read_a_select(read_a_select); driver.read_b_select(read_b_select); driver.read_enable(read_enable); driver.input_load(input_load); driver.input_mux_select(input_mux_select); driver.reg_file_in_mux_select(reg_file_in_mux_select); driver.adder_mux_select(adder_mux_select); driver.output_mux_select(output_mux_select); driver.mult_enable(mult_enable); driver.adder_enable(adder_enable); driver.shifter_enable(shifter_enable); driver.shifter_direction(shifter_direction); driver.comp_eq(comp_eq); driver.comp_gt(comp_gt); driver.comp_lt(comp_lt); // Init Load b_reg.in(in_a); b_reg.out_high(b_high); b_reg.out_low(b_low); b_reg.clk(Clk); b_reg.load(input_load); c_reg.in(in_b); c_reg.out_high(c_high); c_reg.out_low(c_low); c_reg.clk(Clk); c_reg.load(input_load); // FSM Input Mux input_mux.in_a(b_high); input_mux.in_b(b_low); input_mux.in_c(c_high); input_mux.in_d(c_low); input_mux.out(input_reg_value); input_mux.select(input_mux_select); // Register File Input Mux reg_file_in_mux.in_a(input_reg_value); reg_file_in_mux.in_b(data_path_calculated_value); reg_file_in_mux.out(regfile_input); reg_file_in_mux.select(reg_file_in_mux_select); reg_file.clk(Clk); reg_file.in_a(regfile_input); reg_file.write_enable(write_enable); reg_file.write_select(write_select); reg_file.read_a_select(read_a_select); reg_file.read_b_select(read_b_select); reg_file.read_enable(read_enable); reg_file.out_a(out_a); reg_file.out_b(out_b); // Multiplier mult.in_a(out_a); mult.in_b(out_b); mult.out(mult_output); mult.enable(mult_enable); // Adder Input Mux adder_mux.in_a(out_b); adder_mux.in_b(high_1_value); adder_mux.in_c(low_1_value); adder_mux.in_d(zero_value); adder_mux.out(adder_mux_output); adder_mux.select(adder_mux_select); // Adder add.in_a(out_a); add.in_b(adder_mux_output); add.out(adder_output); add.enable(adder_enable); // Shifter shifter.in(out_a); shifter.out(shifter_output); shifter.direction(shifter_direction); shifter.enable(shifter_enable); // Comparator comparison.in_a(out_a); comparison.in_b(out_b); comparison.eq(comp_eq); comparison.lt(comp_lt); comparison.gt(comp_gt); // Output Mux output_mux.in_a(mult_output); output_mux.in_b(adder_output); output_mux.in_c(shifter_output); output_mux.in_d(zero_value); output_mux.out(data_path_calculated_value); output_mux.select(output_mux_select); // Viewer viewer.out_a(out_a); viewer.out_b(out_b); sc_start(); return(0); }