implement control comb logic (untested)
This commit is contained in:
parent
2f967bef04
commit
ed6fd943a6
@ -21,7 +21,7 @@ module ALU #(parameter W=8)(
|
|||||||
SUB: Out = A - B; // subtract B from A
|
SUB: Out = A - B; // subtract B from A
|
||||||
ORR: Out = A | B; // bitwise OR between A and B
|
ORR: Out = A | B; // bitwise OR between A and B
|
||||||
AND: Out = A & B; // bitwise AND between A and B
|
AND: Out = A & B; // bitwise AND between A and B
|
||||||
LSH: Out = A << B; // shift A by B bits
|
LSH: Out = B << A; // shift B by A bits (limitation of control)
|
||||||
RXOR_7: Out = ^(A[6:0]); // perform reduction XOR of lower 7 bits of A
|
RXOR_7: Out = ^(A[6:0]); // perform reduction XOR of lower 7 bits of A
|
||||||
RXOR_8: Out = ^(A[7:0]); // perform reduction XOR of lower 8 bits of A
|
RXOR_8: Out = ^(A[7:0]); // perform reduction XOR of lower 8 bits of A
|
||||||
XOR: Out = A ^ B; // bitwise XOR between A and B
|
XOR: Out = A ^ B; // bitwise XOR between A and B
|
||||||
|
211
RTL/Ctrl.sv
211
RTL/Ctrl.sv
@ -1,84 +1,143 @@
|
|||||||
// CSE141L
|
// Module Name: ALU
|
||||||
import Definitions::*;
|
// Project Name: CSE141L
|
||||||
// control decoder (combinational, not clocked)
|
// control decoder (combinational, not clocked)
|
||||||
// inputs from instrROM, ALU flags
|
|
||||||
// outputs to program_counter (fetch unit)
|
|
||||||
module Ctrl (
|
|
||||||
input[ 8:0] Instruction, // machine code
|
|
||||||
input[ 7:0] DatMemAddr,
|
|
||||||
output logic Branch ,
|
|
||||||
BranchEn ,
|
|
||||||
RegWrEn , // write to reg_file (common)
|
|
||||||
MemWrEn , // write to mem (store only)
|
|
||||||
LoadInst , // mem or ALU to reg_file ?
|
|
||||||
TapSel ,
|
|
||||||
Ack , // "done w/ program"
|
|
||||||
output logic[1:0] PCTarg,
|
|
||||||
// output logic[2:0] ALU_inst
|
|
||||||
);
|
|
||||||
|
|
||||||
/* ***** All numerical values are completely arbitrary and for illustration only *****
|
import Definitions::*;
|
||||||
*/
|
|
||||||
|
|
||||||
// alternative -- case format
|
module Ctrl #(
|
||||||
always_comb begin
|
parameter W = 8,
|
||||||
// list the defaults here
|
parameter T = 10
|
||||||
Branch = 'b0;
|
) (
|
||||||
BranchEn = 'b0;
|
input logic [8:0] Instruction,
|
||||||
RegWrEn = 'b1;
|
input logic [W-1:0] ALU_Out, // control ALU operation
|
||||||
MemWrEn = 'b0;
|
input logic [W-1:0] RegOutA, RegOutB, // select from register inputs or immediate inputs
|
||||||
LoadInst = 'b0;
|
input logic [T-1:0] ProgCtr_p4,
|
||||||
TapSel ' 'b0; //
|
input logic [W-1:0] mem_out,
|
||||||
PCTarg = 'b0; // branch "where to?"
|
output op_mne ALU_OP,
|
||||||
case(Instruction[8:6]) // list just the exceptions
|
output logic [W-1:0] ALU_A, ALU_B,
|
||||||
3'b000: begin
|
output logic RegWrite, Done_in,
|
||||||
MemWrEn = 'b1; // store, maybe
|
output logic [3:0] RaddrA, RaddrB, Waddr, RegInput,
|
||||||
RegWrEn = 'b0;
|
output logic BranchEZ, BranchNZ, BranchAlways,
|
||||||
|
output logic write_mem
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [7:0] I_Immediate;
|
||||||
|
logic [7:0] T_Immediate;
|
||||||
|
logic [3:0] A_operand;
|
||||||
|
logic [3:0] S_operand;
|
||||||
|
logic [3:0] G_operand;
|
||||||
|
|
||||||
|
assign I_Immediate = Instruction[7:0];
|
||||||
|
assign T_Immediate = Instruction[2:0];
|
||||||
|
assign A_operand = Instruction[3:0];
|
||||||
|
assign S_operand = {'b1, Instruction[2:0]};
|
||||||
|
assign G_operand = {'b0, Instruction[2:0]};
|
||||||
|
|
||||||
|
assign ALU_B = RegOutB;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
// default values for an invalid NOP instruction, proper NOP instruction encoded as a LSH by 0
|
||||||
|
ALU_OP = NOP;
|
||||||
|
ALU_A = RegOutA;
|
||||||
|
RegWrite = 'b1;
|
||||||
|
Done_in = 'b0;
|
||||||
|
RaddrA = 'b0;
|
||||||
|
RaddrB = 'b0;
|
||||||
|
Waddr = 'b0;
|
||||||
|
RegInput = ALU_Out;
|
||||||
|
BranchEZ = 'b0;
|
||||||
|
BranchNZ = 'b0;
|
||||||
|
BranchAlways = 'b0;
|
||||||
|
write_mem = 'b0;
|
||||||
|
casez(Instruction)
|
||||||
|
'b1_xxxx_xxxx: begin // LDI
|
||||||
|
ALU_A = I_Immediate;
|
||||||
|
end
|
||||||
|
'b0_0000_xxxx: begin // PUT
|
||||||
|
Waddr = A_operand;
|
||||||
|
end
|
||||||
|
'b0_0001_xxxx: begin // GET
|
||||||
|
RaddrA = A_operand;
|
||||||
|
end
|
||||||
|
'b0_0010_0xxx: begin // LDW
|
||||||
|
RaddrA = S_operand;
|
||||||
|
RegInput = mem_out;
|
||||||
|
end
|
||||||
|
'b0_0010_1xxx: begin // STW
|
||||||
|
RaddrA = S_operand;
|
||||||
|
RegWrite = 'b0;
|
||||||
|
write_mem = 'b1;
|
||||||
|
end
|
||||||
|
'b0_0011_0xxx: begin // NXT
|
||||||
|
if(S_operand == 'd8 || S_operand == 'd9 || S_operand == d'10) ALU_OP = INC;
|
||||||
|
else if (S_operand == 'd11 || S_operand == 'd12 || S_operand == d'13) ALU_OP = DEC;
|
||||||
|
else ALU_OP = NOP;
|
||||||
|
RaddrA = S_operand;
|
||||||
|
Waddr = S_operand;
|
||||||
|
end
|
||||||
|
'b0_0011_1xxx: begin //CLB
|
||||||
|
ALU_OP = CLB;
|
||||||
|
RaddrA = G_operand;
|
||||||
|
Waddr = G_operand;
|
||||||
|
end
|
||||||
|
'b0_0100_xxxx: begin // ADD
|
||||||
|
ALU_OP = ADD;
|
||||||
|
RaddrB = A_operand;
|
||||||
|
end
|
||||||
|
'b0_0101_xxxx: begin // SUB
|
||||||
|
ALU_OP = SUB;
|
||||||
|
RaddrB = A_operand;
|
||||||
|
end
|
||||||
|
'b0_0110_xxxx: begin // ORR
|
||||||
|
ALU_OP = ORR;
|
||||||
|
RaddrB = A_operand;
|
||||||
|
end
|
||||||
|
'b0_0111_xxxx: begin // AND
|
||||||
|
ALU_OP = AND;
|
||||||
|
RaddrB = A_operand;
|
||||||
|
end
|
||||||
|
'b0_1000_0xxx: begin // LSH
|
||||||
|
ALU_OP = LSH;
|
||||||
|
ALU_A = T_Immediate;
|
||||||
|
end
|
||||||
|
'b0_1000_1xxx: begin // PTY
|
||||||
|
ALU_OP = RXOR_7;
|
||||||
|
RaddrA = G_operand;
|
||||||
|
end
|
||||||
|
'b0_1001_xxxx: begin // CHK
|
||||||
|
ALU_OP = RXOR_8;
|
||||||
|
RaddrA = A_operand;
|
||||||
|
end
|
||||||
|
'b0_1010_xxxx: begin // XOR
|
||||||
|
ALU_OP = XOR;
|
||||||
|
RaddrB = A_operand;
|
||||||
|
end
|
||||||
|
'b0_1011_xxxx: begin // DNE
|
||||||
|
Done_in = 'b1;
|
||||||
|
end
|
||||||
|
'b0_1110_0xxx: begin // JNZ
|
||||||
|
RegWrite = 'b0;
|
||||||
|
RaddrA = G_operand;
|
||||||
|
BranchNZ = 'b1;
|
||||||
|
end
|
||||||
|
'b0_1110_1xxx: begin // JEZ
|
||||||
|
RegWrite = 'b0;
|
||||||
|
RaddrA = G_operand;
|
||||||
|
BranchEZ = 'b1;
|
||||||
|
end
|
||||||
|
'b0_1111_0xxx: begin // JMP
|
||||||
|
RegWrite = 'b0;
|
||||||
|
RaddrA = G_operand;
|
||||||
|
BranchAlways = 'b1;
|
||||||
|
end
|
||||||
|
'b0_1111_1xxx: begin // JAL
|
||||||
|
RaddrA = G_operand;
|
||||||
|
Waddr = 'd14; // write to link register specifically
|
||||||
|
RegInput = ProgCtr_p4; // write the value pc+4
|
||||||
|
BranchAlways = 'b1;
|
||||||
end
|
end
|
||||||
3'b001: LoadInst = 'b1; // load
|
|
||||||
3'b010: begin end
|
|
||||||
3'b011: begin end
|
|
||||||
3'b100: begin end
|
|
||||||
3'b101: begin end
|
|
||||||
3'b110: begin end
|
|
||||||
// no default case needed -- covered before "case"
|
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
assign Ack = ProgCtr == 971;
|
|
||||||
// alternative Ack = Instruction == 'b111_000_111
|
|
||||||
|
|
||||||
// ALU commands
|
|
||||||
//assign ALU_inst = Instruction[2:0];
|
|
||||||
|
|
||||||
// STR commands only -- write to data_memory
|
|
||||||
assign MemWrEn = Instruction[8:6]==3'b110;
|
|
||||||
|
|
||||||
// all but STR and NOOP (or maybe CMP or TST) -- write to reg_file
|
|
||||||
assign RegWrEn = Instruction[8:7]!=2'b11;
|
|
||||||
|
|
||||||
// route data memory --> reg_file for loads
|
|
||||||
// whenever instruction = 9'b110??????;
|
|
||||||
assign LoadInst = Instruction[8:6]==3'b110; // calls out load specially
|
|
||||||
|
|
||||||
assign tapSel = LoadInst && DatMemAddr=='d62;
|
|
||||||
// jump enable command to program counter / instruction fetch module on right shift command
|
|
||||||
// equiv to simply: assign Jump = Instruction[2:0] == RSH;
|
|
||||||
always_comb
|
|
||||||
if(Instruction[2:0] == RSH)
|
|
||||||
Branch = 1;
|
|
||||||
else
|
|
||||||
Branch = 0;
|
|
||||||
|
|
||||||
// branch every time instruction = 9'b?????1111;
|
|
||||||
assign BranchEn = &Instruction[3:0];
|
|
||||||
|
|
||||||
// whenever branch or jump is taken, PC gets updated or incremented from "Target"
|
|
||||||
// PCTarg = 2-bit address pointer into Target LUT (PCTarg in --> Target out
|
|
||||||
assign PCTarg = Instruction[3:2];
|
|
||||||
|
|
||||||
// reserve instruction = 9'b111111111; for Ack
|
|
||||||
assign Ack = &Instruction; // = ProgCtr == 385;
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -1,17 +1,7 @@
|
|||||||
// Create Date: 2017.01.25
|
// Module Name: ALU
|
||||||
// Design Name: CSE141L
|
// Project Name: CSE141L
|
||||||
// Module Name: DataMem
|
// control decoder (combinational, not clocked)
|
||||||
// Last Update: 2022.01.13
|
|
||||||
|
|
||||||
// Memory can only read (LDR) or write (STR) on each Clk cycle, so there is a single
|
|
||||||
// address pointer for both read and write operations.
|
|
||||||
//
|
|
||||||
// Parameters:
|
|
||||||
// - A: Address Width. This controls the number of entries in memory
|
|
||||||
// - W: Data Width. This controls the size of each entry in memory
|
|
||||||
// This memory can hold `(2**A) * W` bits of data.
|
|
||||||
//
|
|
||||||
// WI22 is a 256-entry single-byte (8 bit) data memory.
|
|
||||||
module DataMem #(parameter W=8, A=8) ( // do not change W=8
|
module DataMem #(parameter W=8, A=8) ( // do not change W=8
|
||||||
input Clk,
|
input Clk,
|
||||||
Reset, // initialization
|
Reset, // initialization
|
||||||
@ -40,9 +30,9 @@ always_ff @ (posedge Clk)
|
|||||||
|
|
||||||
if(Reset) begin
|
if(Reset) begin
|
||||||
// Preload desired constants into data_mem[128:255]
|
// Preload desired constants into data_mem[128:255]
|
||||||
core[128] <= 'b1;
|
//core[128] <= 'b1;
|
||||||
core[129] <= 'hff;
|
//core[129] <= 'hff;
|
||||||
core[130] <= 'd64;
|
//core[130] <= 'd64;
|
||||||
end
|
end
|
||||||
else if(WriteEn) // store
|
else if(WriteEn) // store
|
||||||
// Do the actual writes
|
// Do the actual writes
|
||||||
|
@ -26,6 +26,8 @@ module RegFile #(parameter W=8, D=4)( // W = data path width (leave at 8); D =
|
|||||||
for(int i=0; i<2**D; i++) begin
|
for(int i=0; i<2**D; i++) begin
|
||||||
Registers[i] <= 'h0;
|
Registers[i] <= 'h0;
|
||||||
end
|
end
|
||||||
|
Zero <= 0;
|
||||||
|
Done <= 1; // default Done to halt machine
|
||||||
end
|
end
|
||||||
else if (WriteEn) begin
|
else if (WriteEn) begin
|
||||||
Registers[Waddr] <= DataIn;
|
Registers[Waddr] <= DataIn;
|
||||||
|
Reference in New Issue
Block a user