dsim1.v
module dsim1 #(parameter DATA_WIDTH=16, parameter ADDR_WIDTH=8) ( input clk, reset_n, output [(ADDR_WIDTH-1):0] addr, output we, output [2:0] ra, rb, rd, output [(DATA_WIDTH-1):0] q, qa, qb, qd, output reg [7:0] pc, output reg [(DATA_WIDTH-1):0] inst, output [4:0] opcode, output ma, rwe ); single_port_ram dev1( .data(qa), .addr(addr[6:0]), .we(we), .clk(clk), .q(q) ); regfile dev2( .clk(clk), .ra(ra), .rb(rb), .rd(rd), .qa(qa), .qb(qb), .qd(qd), .we(rwe) ); //reg [7:0] pc; assign rwe = state==WB; //wire [2:0] opcode = q[15:13]; //wire [4:0] opcode; wire [15:0] qi = (state==ID? q: inst); assign opcode = qi[15:11]; wire [7:0] immed = qi[7:0]; wire [7:0] se = immed[7]? 8'hFF: 8'h00; reg [2:0] state; localparam IF = 3'h0, ID = 3'h1, EX = 3'h2, MEM = 3'h3, WB = 3'h4, HALT = 3'h7; `include "opcodes.txt" wire op_sw = opcode==SW; wire op_lw = opcode==LW; wire op_lui = opcode==LUI; wire op_li = opcode==LI; assign we = (state==MEM) && op_sw; assign ma = (op_sw || op_lw); // memory_access assign rd = (op_sw? 3'h0: qi[10:8]); assign ra = (op_lw||op_lui? qi[10:8]: qi[7:5]); assign rb = (ma? 3'd0: qi[4:2]); wire [7:0] nextpc = pc + 1'b1; assign addr = (state==MEM? immed: nextpc); // output multiplexer wire [15:0] qt = (op_lui? {immed,qa[7:0]}: (op_li? {se,immed}: 16'h0000)); // writeback register multiplexer assign qd = (op_lw? q: qt); always @(posedge clk, negedge reset_n) begin if (!reset_n) begin pc <= 8'hFF; state <= IF; end else case (state) IF: begin state <= ID; pc <= addr; end ID: begin // save results of IF phase inst <= q; state <= EX; end EX: begin if (inst == 16'h0000) state <= HALT; else if (ma) state <= MEM; else state <= WB; end MEM: begin state <= WB; end WB: begin state <= IF; end HALT: begin state <= HALT; end default: state <= HALT; endcase end endmodule
regfile.v
// The register file is a triple-port RAM // with two read addresses and a write address. // It is implemented with two double-port RAMs module regfile #(parameter DATA_WIDTH=16, parameter ADDR_WIDTH=3) ( input clk, input [(ADDR_WIDTH-1):0] ra, rb, rd, output [(DATA_WIDTH-1):0] qa, qb, input [(DATA_WIDTH-1):0] qd, input we ); double_port port1( .clk(clk), .we(we), .ra(ra), .rd(rd), .qa(qa), .qd(qd) ); double_port port2( .clk(clk), .we(we), .ra(rb), .rd(rd), .qa(qb), .qd(qd) ); endmodule module double_port #(parameter DATA_WIDTH=16, parameter ADDR_WIDTH=3) ( input [(DATA_WIDTH-1):0] qd, input [(ADDR_WIDTH-1):0] ra, rd, input we, clk, output [(DATA_WIDTH-1):0] qa ); // Declare the RAM variable reg [DATA_WIDTH-1:0] ram[0:2**ADDR_WIDTH-1]; // Initialize the RAM with $readmemb. Put the memory contents // in the data file. Without this file, // this design will not compile. // See Verilog LRM 1364-2001 Section 17.2.8 for details on the // format of this file. initial begin $readmemh("registers.txt", ram); end // Variable to hold the registered read address reg [ADDR_WIDTH-1:0] ra_reg; always @ (posedge clk) begin // Write if (we) ram[rd] <= qd; end always @ (posedge clk) ra_reg <= ra; // Continuous assignment implies read returns NEW data. // This is the natural behavior of the TriMatrix memory // blocks in Single Port mode. assign qa = (ra_reg? ram[ra_reg]:16'h0000); endmodule
single_port_ram.v
// Quartus II Verilog Template // Single port RAM with single read/write address module single_port_ram #(parameter DATA_WIDTH=16, parameter ADDR_WIDTH=7) ( input [(DATA_WIDTH-1):0] data, input [(ADDR_WIDTH-1):0] addr, input we, clk, output [(DATA_WIDTH-1):0] q ); // Declare the RAM variable reg [DATA_WIDTH-1:0] ram[0:2**ADDR_WIDTH-1]; // Initialize the RAM with $readmemb. Put the memory contents // in the file single_port_rom_init.txt. Without this file, // this design will not compile. // See Verilog LRM 1364-2001 Section 17.2.8 for details on the // format of this file. initial begin $readmemh("ram_init.txt", ram); end // Variable to hold the registered read address reg [ADDR_WIDTH-1:0] addr_reg; always @ (posedge clk) begin // Write if (we) ram[addr] <= data; addr_reg <= addr; end // Continuous assignment implies read returns NEW data. // This is the natural behavior of the TriMatrix memory // blocks in Single Port mode. assign q = ram[addr_reg]; endmodule
fit.summary
Fitter Status : Successful - Mon Feb 28 22:50:46 2011 Quartus II Version : 9.0 Build 235 06/17/2009 SP 2 SJ Web Edition Revision Name : dsim1 Top-level Entity Name : dsim1 Family : Cyclone II Device : EP2C35F672C6 Timing Models : Final Total logic elements : 149 / 33,216 ( < 1 % ) Total combinational functions : 148 / 33,216 ( < 1 % ) Dedicated logic registers : 55 / 33,216 ( < 1 % ) Total registers : 55 Total pins : 115 / 475 ( 24 % ) Total virtual pins : 0 Total memory bits : 2,304 / 483,840 ( < 1 % ) Embedded Multiplier 9-bit elements : 0 / 70 ( 0 % ) Total PLLs : 0 / 4 ( 0 % )
tan.summary
-------------------------------------------------------------------------------------- Timing Analyzer Summary -------------------------------------------------------------------------------------- Type : Worst-case tsu Slack : N/A Required Time : None Actual Time : 0.254 ns From : reset_n To : inst[2]~reg0 From Clock : -- To Clock : clk Failed Paths : 0 Type : Worst-case tco Slack : N/A Required Time : None Actual Time : 14.222 ns From : single_port_ram:dev1|altsyncram:ram_rtl_0|altsyncram_qjb1:auto_generated|ram_block1a0~porta_address_reg6 To : ma From Clock : clk To Clock : -- Failed Paths : 0 Type : Worst-case th Slack : N/A Required Time : None Actual Time : 0.247 ns From : reset_n To : inst[0]~reg0 From Clock : -- To Clock : clk Failed Paths : 0 Type : Clock Setup: 'clk' Slack : N/A Required Time : None Actual Time : 129.07 MHz ( period = 7.748 ns ) From : single_port_ram:dev1|altsyncram:ram_rtl_0|altsyncram_qjb1:auto_generated|ram_block1a0~porta_address_reg6 To : regfile:dev2|double_port:port1|altsyncram:ram_rtl_1|altsyncram_6ui1:auto_generated|ram_block1a0~porta_datain_reg10 From Clock : clk To Clock : clk Failed Paths : 0 Type : Total number of failed paths Slack : Required Time : Actual Time : From : To : From Clock : To Clock : Failed Paths : 0 --------------------------------------------------------------------------------------
Maintained by John Loomis, last updated Mon Feb 28 22:54:46 2011