NEUMANN
NEUMANN
NEUMANN
module alu(
input [3:0] opcode,
input [7:0] operand1,
input [7:0] operand2,
output reg [7:0] result,
output [1:0] flags
);
endmodule
REGS
module regs(
input clk,
// portul de scriere
input wen,
input [3:0] waddr,
input [7:0] wdata,
// porturile de citire
input [3:0] raddr1,
input [3:0] raddr2,
output [7:0] rdata1,
output [7:0] rdata2
);
// portul de scriere
always @(posedge clk) begin
if(wen) registru[waddr] <= wdata; // scriere sincron? - pe ceas - a rezultatului în registrul destina?ie
end
// portul 1 de citire
assign rdata1 = registru[raddr1]; // ie?irea rdata1 este valoarea din registrul cu num?rul raddr1
// portul 2 de citire
assign rdata2 = registru[raddr2]; // ie?irea rdata2 este valoarea din registrul cu num?rul raddr2
endmodule
RALU
module ralu(
input clk,
input rst,
input [3:0] opcode,
input wen,
input [3:0] dest,
input [7:0] wdata,
input [3:0] sursa1,
input [3:0] sursa2,
output [7:0] result,
output reg [1:0] flags
);
//-----------------------------------------------------------------------------
regs regs(
.clk (clk ),
.wen (wen ),
.waddr (dest ),
.wdata (wdata ),
.raddr1 (sursa1 ),
.raddr2 (sursa2 ),
.rdata1 (operand1 ),
.rdata2 (operand2 )
);
//-----------------------------------------------------------------------------
alu alu(
.opcode (opcode ),
.operand1 (operand1 ),
.operand2 (operand2 ),
.result (result ),
.flags (flags_alu)
);
//-----------------------------------------------------------------------------
always @(posedge clk) begin
if(rst)
flags <= 2'b00;
else
flags <= flags_alu;
end
endmodule
UCP
module ucp(
input clk,
input rst,
input [3:0] opcode,
input [1:0] flags,
// control signals
output pc_incr,
output pc_load,
output addr_load,
output sel_addr,
output sel_mem_data,
output sel_instr_data,
output ir_load_high,
output ir_load_low,
output regs_wen,
output write
);
FETCH2: begin
case(opcode)
4'b0000: state <= FETCH1; // NOP
4'b0001: state <= EXECUTE; // ADD
4'b1000: state <= LDCONST; // LOADC
4'b1001: state <= LDADDR; // LOAD
4'b1010: state <= LDADDR; // STORE
4'b1111: state <= HALT; // HALT
endcase
end
LDADDR : begin
if(opcode == 4'b1001)
state <= LD_DATA;
if(opcode == 4'b1010)
state <= ST_DATA;
end
LD_DATA: state <= FETCH1;
endmodule
PROCESOR
module processor(
input clk,
input rst,
input [7:0] data_in, // data from memory
output [7:0] data_out, // data to memory
output [7:0] addr, // memory address
output write // memory write enable
);
//-----------------------------------------------------------------------------
// address mux
assign addr = sel_addr ? data_addr : pc;
//-----------------------------------------------------------------------------
// PC
always @(posedge clk) begin
if(rst)
pc <= 0;
else begin
if(pc_load)
pc <= common_data;
else if(pc_incr)
pc <= pc + 1;
else
pc <= pc;
end
end
//-----------------------------------------------------------------------------
// ADDR
always @(posedge clk) begin
if(rst)
data_addr <= 0;
else begin
if(addr_load)
data_addr <= common_data;
else
data_addr <= data_addr;
end
end
//-----------------------------------------------------------------------------
// IR
always @(posedge clk) begin
if(rst)
instruction <= 0;
else begin
if(ir_load_high)
instruction[15:8] <= common_data;
else if(ir_load_low)
instruction[ 7:0] <= common_data;
else
instruction <= instruction;
end
end
//-----------------------------------------------------------------------------
// decode
assign opcode = instruction[15:12];
assign dest = instruction[11: 8];
assign sursa1 = instruction[ 7: 4];
assign sursa2 = addr_load ? instruction[ 7: 4] : instruction[ 3: 0];
assign instr_data = instruction[ 7: 0];
//-----------------------------------------------------------------------------
// common data mux
always @(*) begin
if(sel_mem_data)
common_data = data_in; // se selecteaz? data dinspre memorie
else if(sel_instr_data)
common_data = instr_data; // se selecteaz? constanta
else
common_data = result; // se selecteaz? rezultatul de la ALU
end
//-----------------------------------------------------------------------------
ralu ralu(
.clk (clk ),
.rst (rst ),
.opcode (opcode ),
.wen (regs_wen ),
.dest (dest ),
.wdata (common_data),
.sursa1 (sursa1 ),
.sursa2 (sursa2 ),
.result (result ),
.flags (flags )
);
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
ucp ucp(
.clk (clk ),
.rst (rst ),
.opcode (opcode ),
.flags (flags ),
.pc_incr (pc_incr ),
.pc_load (pc_load ),
.addr_load (addr_load ),
.sel_addr (sel_addr ),
.sel_mem_data (sel_mem_data ),
.sel_instr_data (sel_instr_data),
.ir_load_high (ir_load_high ),
.ir_load_low (ir_load_low ),
.regs_wen (regs_wen ),
.write (write )
);
Endmodule
MEMORIE
module memory(
input clk,
input write,
input [7:0] addr,
input [7:0] din,
output [7:0] dout
);
// program
initial begin
{memory[00], memory[01]} = 16'b1000_0000_1111_1111; // LOADC R0 #255
{memory[02], memory[03]} = 16'b1000_0001_1111_1110; // LOADC R1 #254
{memory[04], memory[05]} = 16'b1000_0010_1111_1101; // LOADC R2 #253
{memory[06], memory[07]} = 16'b1001_0100_0000_0000; // LOAD R4 R0
{memory[08], memory[09]} = 16'b1001_0101_0001_0000; // LOAD R5 R1
{memory[10], memory[11]} = 16'b0001_0110_0101_0100; // ADD R6 R5 R4
{memory[12], memory[13]} = 16'b1010_0000_0010_0110; // STORE R2 R6
{memory[14], memory[15]} = 16'b1111_1111_1111_1111; // HALT
end
// date initiale
initial begin
memory[254] = 17;
memory[255] = 23;
end
endmodule
NEUMANN
module neumann(
input clk,
input rst
);
wire write;
wire [7:0] addr;
wire [7:0] data_from_mem;
wire [7:0] data_to_mem;
processor procesor(
.clk (clk ),
.rst (rst ),
.data_in (data_from_mem),
.data_out(data_to_mem ),
.addr (addr ),
.write (write )
);
memory memorie(
.clk (clk ),
.write (write ),
.addr (addr ),
.din (data_to_mem ),
.dout (data_from_mem)
);
Endmodule
NEUMANN_TB
module neumann_tb;
// declara?ii de variable
reg clk;
reg rst;
// instan?ierea calculatorului
neumann dut(
.clk (clk),
.rst (rst)
);
endmodule