`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 09:58:21 02/12/2008 // Design Name: // Module Name: sramcontrol // Project Name: // Target Devices: // Tool versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module sram_block( amem, dmem_in, dmem_out, en, wen, addr_sr, data_io_0, data_io_1, ce_0, ce_1, oe, we, ub_0, lb_0, ub_1, lb_1, clk_cpu, clk_sram, rst); input[19:0] amem; input[31:0] dmem_in; output[31:0] dmem_out; reg[31:0] dmem_out; input[3:0] en; input[3:0] wen; output[17:0] addr_sr; reg[17:0] addr_sr; inout[15:0] data_io_0; inout[15:0] data_io_1; //wire[15:0] datawrite_0; //wire[15:0] datawrite_1; output ce_0; output ce_1; reg ce_0, ce_1; output oe; reg oe; output we; reg we; output ub_0; output lb_0; reg ub_0, lb_0; output ub_1; output lb_1; reg ub_1, lb_1; output clk_cpu; //reg clk_cpu; input clk_sram; input rst; /* always @(posedge clk_sram) begin we <= 1; oe <= 1; ce_0 <= 1; ce_1 <= 1; ub_0 <= 1; lb_0 <= 1; ub_1 <= 1; lb_1 <= 1; locked <= 1; end */ // prelude reg ub_0_A; reg lb_0_A; reg ub_1_A; reg lb_1_A; reg ce_0_A; reg ce_1_A; reg oe_A; reg we_A; reg[17:0] addr_sr_A; reg[31:0] dmem_out1_A; // a special reset logic for the clk_sram domain reg r1; reg rst_sram; always @(posedge clk_sram or posedge rst) begin if (rst) r1 <= 1'b1; else r1 <= 1'b0; end always @(posedge clk_sram or posedge rst) begin if (rst) rst_sram <= 1'b1; else rst_sram <= r1; end // the state machine for reading and writing to the SRAM reg[3:0] state, next_st; // infer tri-states parameter wait_sync_state = 0, normal_first = 1, first_after_read = 2, first_after_write = 3, second_state = 4, third_state = 5, fourth_state = 6, read_state_1 = 7, read_state_2 = 8, write_state_1 = 9, write_state_2 = 10, fifth_state = 11, sixth_state = 12; reg[15:0] datawrite_0_Mem; reg[15:0] datawrite_1_Mem; assign data_io_0 = ((state == write_state_2) || (state == first_after_write)) ? datawrite_0_Mem : 16'bz; assign data_io_1 = ((state == write_state_2) || (state == first_after_write)) ? datawrite_1_Mem : 16'bz; wire[17:0] addr_sr_in; assign addr_sr_in = amem[19:2]; //assign datawrite_0 = dmem_in[15:0]; //assign datawrite_1 = dmem_in[31:16]; always @(posedge clk_cpu) begin if (state == read_state_2) dmem_out <= dmem_out1_A; end always @(posedge clk_sram or posedge rst_sram) begin if (rst_sram) begin state <= normal_first; datawrite_0_Mem <= 16'b0; datawrite_0_Mem <= 16'b0; end else begin if (state == fourth_state) begin addr_sr_A <= addr_sr_in; state <= next_st; end else if (state == write_state_1) begin datawrite_0_Mem <= dmem_in[15:0]; datawrite_1_Mem <= dmem_in[31:16]; state <= next_st; end else if (state == read_state_2) begin //dmem_out <= dmem_out1_A; state <= next_st; end else begin state <= next_st; end end end // next state combinatorial block: always @(state or en or wen) begin case (state) normal_first: begin next_st = second_state; end first_after_read: begin next_st = second_state; end first_after_write:begin next_st = second_state; end second_state: begin next_st = third_state; end third_state: begin next_st = fourth_state; end fourth_state: begin if ((|en) & (|wen)) next_st = write_state_1; else if ((|en) & (~(|wen))) next_st = read_state_1; else next_st = fifth_state; end read_state_1: begin next_st = read_state_2; end write_state_1: begin next_st = write_state_2; end read_state_2: begin next_st = first_after_read; end write_state_2: begin next_st = first_after_write; end fifth_state: begin next_st = sixth_state; end sixth_state: begin next_st = normal_first; end default: begin next_st = normal_first; end endcase end // output combinatorial block reg clk_cpu_A; reg clk_cpu_i; always @(posedge clk_sram or posedge rst_sram) begin if (rst_sram) clk_cpu_i <= 0; else clk_cpu_i <= clk_cpu_A; end always @(state) begin case (state) normal_first, first_after_read, first_after_write, second_state, sixth_state, read_state_2, write_state_2: begin clk_cpu_A = 1'b1; end third_state, fourth_state, fifth_state, read_state_1, write_state_1: begin clk_cpu_A = 1'b0; end default: begin clk_cpu_A = 1'b0; end endcase end BUFG bufg_clk (.I(clk_cpu_i), .O(clk_cpu)); //addr control reg addrout_allow; reg addrout_allow_A; always @(addrout_allow) addr_sr = addrout_allow ? addr_sr_A : 18'bz; always @(posedge clk_sram or posedge rst_sram) begin if (rst_sram) begin ub_0 <= 1; lb_0 <= 1; ub_1 <= 1; lb_1 <= 1; ce_0 <= 1; ce_1 <= 1; oe <= 1; we <= 1; addrout_allow <= 1'b0; // addr_sr <= 18'bz; end else begin ub_0 <= ub_0_A; lb_0 <= lb_0_A; ub_1 <= ub_1_A; lb_1 <= lb_1_A; ce_0 <= ce_0_A; ce_1 <= ce_1_A; oe <= oe_A; we <= we_A; addrout_allow <= addrout_allow_A; // addr_sr <= addr_sr_A; end end always @(state, data_io_1, data_io_0) begin case (state) normal_first, first_after_write, second_state, third_state, fourth_state, fifth_state, sixth_state, write_state_1, write_state_2: begin dmem_out1_A = 32'b0; end read_state_1, read_state_2, first_after_read: begin dmem_out1_A = {data_io_1,data_io_0}; end default: begin dmem_out1_A = 32'b0; end endcase end always @(state or en or wen or addr_sr_in) begin case (state) normal_first, first_after_read, first_after_write, second_state, third_state, fifth_state, sixth_state : begin ub_0_A = 1; lb_0_A = 1; ub_1_A = 1; lb_1_A = 1; ce_0_A = 1; ce_1_A = 1; oe_A = 1; we_A = 1; addrout_allow_A = 0; //addr_sr_A = 18'bz; end fourth_state: begin if ((|en) & (~(|wen))) begin oe_A = 0; we_A = 1; addrout_allow_A = 1; //addr_sr_A = addr_sr_in; lb_0_A = ~en[0]; ub_0_A = ~en[1]; lb_1_A = ~en[2]; ub_1_A = ~en[3]; ce_0_A = ~|{en[1:0]}; ce_1_A = ~|{en[3:2]}; end else if ((|en) & (|wen)) begin oe_A = 1; we_A = 1; addrout_allow_A = 1; //addr_sr_A = addr_sr_in; lb_0_A = ~wen[0]; ub_0_A = ~wen[1]; lb_1_A = ~wen[2]; ub_1_A = ~wen[3]; ce_0_A = ~|{en[1:0]}; ce_1_A = ~|{en[3:2]}; end else begin ub_0_A = 1; lb_0_A = 1; ub_1_A = 1; lb_1_A = 1; ce_0_A = 1; ce_1_A = 1; oe_A = 1; we_A = 1; addrout_allow_A = 0; //addr_sr_A = 18'bz; end end read_state_1: begin oe_A = 0; we_A = 1; addrout_allow_A = 1; //addr_sr_A = addr_sr_in; lb_0_A = ~en[0]; ub_0_A = ~en[1]; lb_1_A = ~en[2]; ub_1_A = ~en[3]; ce_0_A = ~|{en[1:0]}; ce_1_A = ~|{en[3:2]}; end read_state_2: begin oe_A = 0; we_A = 1; addrout_allow_A = 1; //addr_sr_A = addr_sr_in; lb_0_A = ~en[0]; ub_0_A = ~en[1]; lb_1_A = ~en[2]; ub_1_A = ~en[3]; ce_0_A = ~|{en[1:0]}; ce_1_A = ~|{en[3:2]}; end write_state_1: begin oe_A = 1; we_A = 0; addrout_allow_A = 1; //addr_sr_A = addr_sr_in; lb_0_A = ~wen[0]; ub_0_A = ~wen[1]; lb_1_A = ~wen[2]; ub_1_A = ~wen[3]; ce_0_A = ~|{en[1:0]}; ce_1_A = ~|{en[3:2]}; end write_state_2: begin oe_A = 1; we_A = 1; addrout_allow_A = 1; //addr_sr_A = addr_sr_in; lb_0_A = ~wen[0]; ub_0_A = ~wen[1]; lb_1_A = ~wen[2]; ub_1_A = ~wen[3]; ce_0_A = ~|{en[1:0]}; ce_1_A = ~|{en[3:2]}; end default: begin ub_0_A = 1; lb_0_A = 1; ub_1_A = 1; lb_1_A = 1; ce_0_A = 1; ce_1_A = 1; oe_A = 1; we_A = 1; addrout_allow_A = 0; //addr_sr_A = 18'bz; end endcase end endmodule module takt (clk, clk1, clk_cpu, clk_sram, locked, rst ); input clk; input rst; output locked; output clk1; output clk_cpu; output clk_sram; // DCM : In order to incorporate this function into the design, // Verilog : the following instance declaration needs to be placed // instance : in the body of the design code. The instance name // declaration : (DCM_inst) and/or the port declarations within the // code : parenthesis maybe changed to properly reference and // : connect this function to the design. Unused inputs // : and outputs may be removed or commented out. // <-----Cut code below this line----> // DCM: Digital Clock Manager Circuit for Virtex-II/II-Pro and Spartan-3 // The current version of the Xilinx HDL Libraries Guide wire CLKIN = clk; wire clkfx; wire clkdv; wire clk0; wire CLKFB = clk0; assign clk_cpu = clkdv; assign clk_sram = clkfx; wire[7:0] STATUS; DCM DCM_inst ( .CLK0(CLK01), // 0 degree DCM CLK ouptput .CLK180(CLK180), // 180 degree DCM CLK output .CLK270(CLK270), // 270 degree DCM CLK output .CLK2X(CLK2X), // 2X DCM CLK output .CLK2X180(CLK2X180), // 2X, 180 degree DCM CLK out .CLK90(CLK90), // 90 degree DCM CLK output .CLKDV(CLKDV1), // Divided DCM CLK out (CLKDV_DIVIDE) .CLKFX(CLKFX1), // DCM CLK synthesis out (M/D) .CLKFX180(CLKFX180), // 180 degree CLK synthesis out .LOCKED(LOCKED1), // DCM LOCK status output .PSDONE(PSDONE), // Dynamic phase adjust done output .STATUS(STATUS), // 8-bit DCM status bits output .CLKFB(CLKFB), // DCM clock feedback .CLKIN(CLKIN), // Clock input (from IBUFG, BUFG or DCM) .PSCLK(PSCLK), // Dynamic phase adjust clock input .PSEN(PSEN), // Dynamic phase adjust enable input .PSINCDEC(PSINCDEC), // Dynamic phase adjust increment/decrement .RST(rst) // DCM asynchronous reset input ); BUFG bufg_1 (.I(CLKFX1), .O(clkfx)); BUFG bufg_2 (.I(CLKDV1), .O(clkdv)); BUFG bufg_3 (.I(CLK01), .O(clk0)); assign locked = LOCKED1; assign clk1 = clk0; // The following defparam declarations are only necessary if you // wish to change the default behavior // of the DCM. If the instance name is changed, these defparams need // to be updated accordingly. defparam DCM_inst.CLKDV_DIVIDE = 4.0; // Divide by: //1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5 //7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0 defparam DCM_inst.CLKFX_DIVIDE = 2; // Can be any integer from 1 to 32 defparam DCM_inst.CLKFX_MULTIPLY = 3; // Can be any integer from 2 to 32 defparam DCM_inst.CLKIN_DIVIDE_BY_2 = "FALSE"; // TRUE/FALSE to enable CLKIN divide by two feature defparam DCM_inst.CLKIN_PERIOD = 20.0; // Specify period of input clock defparam DCM_inst.CLKOUT_PHASE_SHIFT = "NONE"; // Specify phase shift of NONE, FIXED or VARIABLE defparam DCM_inst.CLK_FEEDBACK = "1X"; // Specify clock feedback of NONE, 1X or 2X defparam DCM_inst.DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS"; //SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or // an integer from 0 to 15 defparam DCM_inst.DFS_FREQUENCY_MODE = "LOW"; // HIGH or LOW frequency mode for frequency synthesis defparam DCM_inst.DLL_FREQUENCY_MODE = "LOW"; // HIGH or LOW frequency mode for DLL defparam DCM_inst.DUTY_CYCLE_CORRECTION = "TRUE"; // Duty cycle correction, TRUE or FALSE defparam DCM_inst.FACTORY_JF = 16'hC080; // FACTORY JF Values defparam DCM_inst.PHASE_SHIFT = 0; // Amount of fixed phase shift from -255 to 255 defparam DCM_inst.STARTUP_WAIT = "FALSE"; // Delay configuration DONE until DCM LOCK, TRUE/FALSE // End of DCM_inst instantiation endmodule