`timescale 1ns / 1ps module ehw(clk, sram_data, addr, nwe, ncs, noe, reset, led, irq_pin); parameter B = (7); input clk, addr, nwe, ncs, noe, reset; inout [B:0] sram_data; output led; output irq_pin; // synchronize signals reg sncs, snwe; reg [12:0] buffer_addr; reg [B:0] buffer_data; wire led; // bram-cpu interfaz reg we; reg w_st=0; reg [B:0] wdBus; reg [B:0] rdBus; wire [12:0] addr; reg [7:0] bae; // bram-evalfit interfaz wire we_eval, en_ev; wire [63:0] ev_do; wire [63:0] ev_di; // Interconnection wire [31:0] mt_rnd; wire [31:0] reg0; wire [31:0] reg1; wire [31:0] reg2; wire [31:0] reg3; wire [31:0] reg4; wire [7:0] status; wire [15:0] error; wire [8:0] evalfit_addr; wire en_fit; wire [15:0] max_com; wire [3:0] max_lev; wire [7:0] control; reg [7:0] reg_bank [31:0]; wire enReg; wire [4:0] address; // Test : LED blinking reg [25:0] counter; always @(posedge clk) begin if (~reset) counter <= {25{1'b0}}; else counter <= counter + 1; end assign led = counter[24]; // Data Bus direction control wire T = ~noe | ncs; assign sram_data = T?8'bZ:rdBus; // synchronize assignment always @(negedge clk) begin sncs <= ncs; snwe <= nwe; buffer_data <= sram_data; buffer_addr <= addr; end // write access cpu to bram always @(posedge clk) if(~reset) {w_st, we, wdBus} <= 0; else begin wdBus <= buffer_data; case (w_st) 0: begin we <= 0; if(sncs | snwe) w_st <= 1; end 1: begin if(~(sncs | snwe)) begin we <= 1; w_st <= 0; end else we <= 0; end endcase end // Address Decoder // We have 2 memory blocks 1: 512 x 64 bits memory 32kb = 4kB 0000 - 0FFF buffer_addr[12] = 0 // 2: Register Bank 1000 - 101F buffer_addr[12] = 1 // SIE has an eight bits data bus, this module generate the required signals to create a 64 bits word. always @(buffer_addr) begin if(~buffer_addr[12]) begin case (buffer_addr[2:0]) 0: bae <= 8'h01; 1: bae <= 8'h02; 2: bae <= 8'h04; 3: bae <= 8'h08; 4: bae <= 8'h10; 5: bae <= 8'h20; 6: bae <= 8'h40; 7: bae <= 8'h80; endcase end else bae <= 8'h00; end wire en1, en2; // enable memory signals assign en0 = bae[0] | bae[1] | bae[2] | bae[3]; assign en1 = bae[4] | bae[5] | bae[6] | bae[7]; reg[31:0] DIA_Aux; always @ (posedge clk) begin if (bae[0]) DIA_Aux[7:0] = wdBus[7:0]; if (bae[1]) DIA_Aux[15:8] = wdBus[7:0]; if (bae[2]) DIA_Aux[23:16] = wdBus[7:0]; if (bae[3]) DIA_Aux[31:24] = wdBus[7:0]; if (bae[4]) DIA_Aux[7:0] = wdBus[7:0]; if (bae[5]) DIA_Aux[15:8] = wdBus[7:0]; if (bae[6]) DIA_Aux[23:16] = wdBus[7:0]; if (bae[7]) DIA_Aux[31:24] = wdBus[7:0]; end reg [2:0] state, nextstate; //FSM for write in 32bit mode to memory wire we0, we1; wire nreset; assign nreset = ~reset; parameter S0 = 3'b000; parameter S1 = 3'b001; parameter S2 = 3'b010; always @ (posedge clk, posedge nreset) if (nreset) state <= S0; else state <= nextstate; // next state logic always@(*) case (state) S0:if (bae[3]&we) nextstate = S1; else if (bae[7]&we) nextstate = S2; else nextstate = S0; S1: nextstate = S0; S2: nextstate = S0; default: nextstate = S0; endcase // output logic assign we0 = (state == S1); assign we1 = (state == S2); // Read control reg [7:0] MemDOA; wire [63:0] DOA_Aux; always @(posedge clk) if(~reset)begin rdBus = 8'h00; end else begin if(enReg) rdBus = reg_bank[address]; else rdBus = MemDOA[7:0]; end // memory output mux always @(buffer_addr[2:0]) case (buffer_addr[2:0]) 0 : MemDOA = DOA_Aux[7:0]; 1 : MemDOA = DOA_Aux[15:8]; 2 : MemDOA = DOA_Aux[23:16]; 3 : MemDOA = DOA_Aux[31:24]; 4 : MemDOA = DOA_Aux[39:32]; 5 : MemDOA = DOA_Aux[47:40]; 6 : MemDOA = DOA_Aux[55:48]; 7 : MemDOA = DOA_Aux[63:56]; default: MemDOA = 8'h00; endcase // Store Inputs always @(posedge clk) begin if(enReg) begin reg_bank[20] = error[7:0]; reg_bank[21] = error[15:8]; reg_bank[22] = status[7:0]; reg_bank[24] = mt_rnd[7:0]; reg_bank[25] = mt_rnd[15:8]; reg_bank[26] = mt_rnd[23:16]; reg_bank[27] = mt_rnd[31:24]; end end assign address[4:0] = buffer_addr[4:0]; assign enReg = buffer_addr[12]; assign reg0[7:0] = reg_bank[0]; assign reg0[15:8] = reg_bank[1]; assign reg0[23:16] = reg_bank[2]; assign reg0[31:24] = reg_bank[3]; assign reg1[7:0] = reg_bank[4]; assign reg1[15:8] = reg_bank[5]; assign reg1[23:16] = reg_bank[6]; assign reg1[31:24] = reg_bank[7]; assign reg2[7:0] = reg_bank[8]; assign reg2[15:8] = reg_bank[9]; assign reg2[23:16] = reg_bank[10]; assign reg2[31:24] = reg_bank[11]; assign reg3[7:0] = reg_bank[12]; assign reg3[15:8] = reg_bank[13]; assign reg3[23:16] = reg_bank[14]; assign reg3[31:24] = reg_bank[15]; assign reg4[7:0] = reg_bank[16]; assign reg4[15:8] = reg_bank[17]; assign reg4[23:16] = reg_bank[18]; assign reg4[31:24] = reg_bank[19]; assign max_lev = reg_bank[28]; assign control = reg_bank[29]; assign max_com[7:0] = reg_bank[30]; assign max_com[15:8] = reg_bank[31]; // Write control always @(negedge clk) if(we & enReg) begin case (address) 0: reg_bank[0] = wdBus; 1: reg_bank[1] = wdBus; 2: reg_bank[2] = wdBus; 3: reg_bank[3] = wdBus; 4: reg_bank[4] = wdBus; 5: reg_bank[5] = wdBus; 6: reg_bank[6] = wdBus; 7: reg_bank[7] = wdBus; 8: reg_bank[8] = wdBus; 9: reg_bank[9] = wdBus; 10: reg_bank[10] = wdBus; 11: reg_bank[11] = wdBus; 12: reg_bank[12] = wdBus; 13: reg_bank[13] = wdBus; 14: reg_bank[14] = wdBus; 15: reg_bank[15] = wdBus; 16: reg_bank[16] = wdBus; 17: reg_bank[17] = wdBus; 18: reg_bank[18] = wdBus; 19: reg_bank[19] = wdBus; 28: reg_bank[28] = wdBus; 29: reg_bank[29] = wdBus; 30: reg_bank[30] = wdBus; 31: reg_bank[31] = wdBus; endcase end RAMB16_S36_S36 #(.INIT_00(256'hABCDEF00_00000000_00000000_00000000_00000000_00000000_00000000_76543210) ) mem0 ( .CLKA(~clk), .ENA(en0), .SSRA(1'b0), .ADDRA(buffer_addr[11:3]), .WEA(we0), .DIA(DIA_Aux[31:0]), .DIPA(0'b0), .DOA(DOA_Aux[31:0]), .CLKB(~clk), .ENB(en_ev), .SSRB(1'b0), .ADDRB(evalfit_addr), .WEB(we_eval), .DIB(ev_do[31:0]), .DIPB(0'b0), .DOB(ev_di[31:0])); RAMB16_S36_S36 mem1( .CLKA(~clk), .ENA(en1), .SSRA(1'b0), .ADDRA(buffer_addr[11:3]), .WEA(we1), .DIA(DIA_Aux[31:0]), .DIPA(0'b0), .DOA(DOA_Aux[63:32]), .CLKB(~clk), .ENB(en_ev),.SSRB(1'b0), .ADDRB(evalfit_addr), .WEB(we_eval), .DIB(ev_do[63:32]), .DIPB(0'b0), .DOB(ev_di[63:32])); // evalfit_peripheral evalfit_peripheral evalfit( .clk(clk), .reset(~reset), .habilita(control[0]), .maxcombs(max_com), .nivel_max(max_lev), .peripheral_mem_in(ev_di), .peripheral_mem_en(en_eval), .peripheral_mem_out(ev_do), .peripheral_mem_we(we_eval), .peripheral_mem_addr(evalfit_addr), .evalfit3_estado(status), .errores(error), .fin_ack(irq_pin), .reg0_s(reg0), .reg1_s(reg1), .reg2_s(reg2), .reg3_s(reg3), .reg4_s(reg4)); // MersenneTwister mt_mem random( .clk(clk), .ena(1'b1), .resetn(reset), .random(mt_rnd)); endmodule