Skip to content

Instantly share code, notes, and snippets.

@benpye

benpye/cpu.v Secret

Created March 25, 2016 17:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benpye/07aa8a66e25a7c702766 to your computer and use it in GitHub Desktop.
Save benpye/07aa8a66e25a7c702766 to your computer and use it in GitHub Desktop.
module hex(
input wire clk,
output wire [7:0] mem_addr,
output wire mem_wr,
input wire [7:0] din,
output wire [7:0] dout,
output reg [7:0] pc,
output reg [7:0] areg);
parameter s_fetch = 2'b00;
parameter s_decode = 2'b01;
parameter s_execute = 2'b10;
parameter s_write = 2'b11;
parameter i_ldam = 4'h0;
parameter i_ldbm = 4'h1;
parameter i_stam = 4'h2;
parameter i_ldac = 4'h3;
parameter i_ldbc = 4'h4;
parameter i_ldap = 4'h5;
parameter i_ldai = 4'h6;
parameter i_ldbi = 4'h7;
parameter i_stai = 4'h8;
parameter i_br = 4'h9;
parameter i_brz = 4'ha;
parameter i_brn = 4'hb;
parameter i_brb = 4'hc;
parameter i_add = 4'hd;
parameter i_sub = 4'he;
parameter i_pfix = 4'hf;
reg [1:0] state;
reg [7:0] breg;
reg [7:0] oreg;
reg [3:0] inst;
initial begin
mem_wr <= 0;
pc <= 0;
state <= s_fetch;
end
always @(posedge clk)
begin
case(state)
s_fetch: begin
mem_addr <= pc;
state <= s_decode;
end
s_decode: begin
oreg[3:0] <= din[3:0];
inst <= din[7:4];
pc <= pc + 1;
case(din[7:4])
i_ldam: mem_addr <= {oreg[7:4], din[3:0]};
i_ldbm: mem_addr <= {oreg[7:4], din[3:0]};
i_ldai: mem_addr <= areg + {oreg[7:4], din[3:0]};
i_ldbi: mem_addr <= breg + {oreg[7:4], din[3:0]};
default: ;
endcase
state <= s_execute;
end
s_execute: begin
case(inst)
i_ldam: areg <= din;
i_ldbm: breg <= din;
i_stam: begin
mem_wr <= 1;
mem_addr <= oreg;
dout <= areg;
end
i_ldac: areg <= oreg;
i_ldbc: breg <= oreg;
i_ldap: areg <= pc + oreg;
i_ldai: areg <= din;
i_ldbi: breg <= din;
i_stai: begin
mem_wr <= 1;
mem_addr <= breg + oreg;
dout <= areg;
end
i_br: pc <= pc + oreg;
i_brz: if(areg == 0) pc <= pc + oreg;
i_brn: if(areg > 127) pc <= pc + oreg;
i_brb: pc <= breg;
i_add: areg <= areg + breg;
i_sub: areg <= areg - breg;
i_pfix: oreg <= {oreg[3:0],4'b0000};
endcase
if(inst != i_pfix) oreg <= 0;
state <= s_write;
end
s_write: begin
mem_wr <= 0;
state <= s_fetch;
end
endcase
end
endmodule
module ram (din, addr, write_en, clk, dout);// 256x8
parameter addr_width = 8;
parameter data_width = 8;
input [addr_width-1:0] addr;
input [data_width-1:0] din;
input write_en, clk;
output [data_width-1:0] dout;
reg [data_width-1:0] dout; // Register for output.
reg [data_width-1:0] mem [(1<<addr_width)-1:0];
initial
begin
mem[0] = 8'hF0;
mem[1] = 8'h92;
mem[2] = 8'hFE;
mem[3] = 8'h00;
mem[4] = 8'h51;
mem[5] = 8'h93;
mem[6] = 8'h61;
mem[7] = 8'hFF;
mem[8] = 8'h9E;
mem[9] = 8'h12;
mem[10] = 8'h80;
mem[11] = 8'hFF;
mem[12] = 8'h3C;
mem[13] = 8'hD0;
mem[14] = 8'h22;
mem[15] = 8'h35;
mem[16] = 8'h12;
mem[17] = 8'h82;
mem[18] = 8'h52;
mem[19] = 8'hF7;
mem[20] = 8'h95;
mem[21] = 8'h61;
mem[22] = 8'h12;
mem[23] = 8'h85;
mem[24] = 8'h34;
mem[25] = 8'hD0;
mem[26] = 8'h22;
mem[27] = 8'h74;
mem[28] = 8'hC0;
mem[29] = 8'h12;
mem[30] = 8'h80;
mem[31] = 8'hFF;
mem[32] = 8'h3A;
mem[33] = 8'hD0;
mem[34] = 8'h22;
mem[35] = 8'h02;
mem[36] = 8'h68;
mem[37] = 8'h13;
mem[38] = 8'hE0;
mem[39] = 8'hB2;
mem[40] = 8'hF1;
mem[41] = 8'h95;
mem[42] = 8'h02;
mem[43] = 8'h69;
mem[44] = 8'h12;
mem[45] = 8'h79;
mem[46] = 8'hD0;
mem[47] = 8'h12;
mem[48] = 8'h83;
mem[49] = 8'h02;
mem[50] = 8'h68;
mem[51] = 8'h12;
mem[52] = 8'h78;
mem[53] = 8'hD0;
mem[54] = 8'h12;
mem[55] = 8'h82;
mem[56] = 8'h52;
mem[57] = 8'hFE;
mem[58] = 8'h92;
mem[59] = 8'h61;
mem[60] = 8'h12;
mem[61] = 8'h85;
mem[62] = 8'h93;
mem[63] = 8'h30;
mem[64] = 8'h12;
mem[65] = 8'h85;
mem[66] = 8'h03;
mem[67] = 8'h12;
mem[68] = 8'h78;
mem[69] = 8'hE0;
mem[70] = 8'hBC;
mem[71] = 8'h03;
mem[72] = 8'h12;
mem[73] = 8'h78;
mem[74] = 8'hE0;
mem[75] = 8'h23;
mem[76] = 8'h02;
mem[77] = 8'h65;
mem[78] = 8'h12;
mem[79] = 8'h79;
mem[80] = 8'hD0;
mem[81] = 8'h12;
mem[82] = 8'h85;
mem[83] = 8'h02;
mem[84] = 8'h65;
mem[85] = 8'h12;
mem[86] = 8'h87;
mem[87] = 8'h36;
mem[88] = 8'hD0;
mem[89] = 8'h22;
mem[90] = 8'h76;
mem[91] = 8'hC0;
mem[92] = 8'h12;
mem[93] = 8'h80;
mem[94] = 8'hFF;
mem[95] = 8'h3A;
mem[96] = 8'hD0;
mem[97] = 8'h22;
mem[98] = 8'h02;
mem[99] = 8'h68;
mem[100] = 8'h12;
mem[101] = 8'h79;
mem[102] = 8'hE0;
mem[103] = 8'hB1;
mem[104] = 8'h98;
mem[105] = 8'h02;
mem[106] = 8'h68;
mem[107] = 8'h23;
mem[108] = 8'h02;
mem[109] = 8'h69;
mem[110] = 8'h12;
mem[111] = 8'h85;
mem[112] = 8'h97;
mem[113] = 8'h02;
mem[114] = 8'h69;
mem[115] = 8'h23;
mem[116] = 8'h02;
mem[117] = 8'h68;
mem[118] = 8'h12;
mem[119] = 8'h85;
mem[120] = 8'h02;
mem[121] = 8'h65;
mem[122] = 8'h12;
mem[123] = 8'h83;
mem[124] = 8'h31;
mem[125] = 8'h12;
mem[126] = 8'h82;
mem[127] = 8'h52;
mem[128] = 8'hF9;
mem[129] = 8'h9B;
mem[130] = 8'h61;
mem[131] = 8'h12;
mem[132] = 8'h87;
mem[133] = 8'h36;
mem[134] = 8'hD0;
mem[135] = 8'h22;
mem[136] = 8'h76;
mem[137] = 8'hC0;
mem[138] = 8'h12;
mem[139] = 8'h80;
mem[140] = 8'hFF;
mem[141] = 8'h3A;
mem[142] = 8'hD0;
mem[143] = 8'h22;
mem[144] = 8'h02;
mem[145] = 8'h68;
mem[146] = 8'hA1;
mem[147] = 8'h93;
mem[148] = 8'h31;
mem[149] = 8'hF1;
mem[150] = 8'h98;
mem[151] = 8'h02;
mem[152] = 8'h68;
mem[153] = 8'h41;
mem[154] = 8'hE0;
mem[155] = 8'h12;
mem[156] = 8'h82;
mem[157] = 8'h52;
mem[158] = 8'hFE;
mem[159] = 8'h9A;
mem[160] = 8'h61;
mem[161] = 8'h12;
mem[162] = 8'h85;
mem[163] = 8'h02;
mem[164] = 8'h68;
mem[165] = 8'h12;
mem[166] = 8'h82;
mem[167] = 8'h02;
mem[168] = 8'h65;
mem[169] = 8'h12;
mem[170] = 8'h83;
mem[171] = 8'h52;
mem[172] = 8'hFA;
mem[173] = 8'h9E;
mem[174] = 8'h61;
mem[175] = 8'h12;
mem[176] = 8'h87;
mem[177] = 8'h36;
mem[178] = 8'hD0;
mem[179] = 8'h22;
mem[180] = 8'h76;
mem[181] = 8'hC0;
end
always @(negedge clk)
begin
if (write_en)
mem[addr] <= din;
dout = mem[addr]; // Output register controlled by clock.
end
endmodule
module top (
input clk,
output LED0,
output LED1,
output LED2,
output LED3,
output LED4,
output LED5,
output LED6,
output LED7
);
localparam LOG2DELAY = 10;
reg [LOG2DELAY-1:0] delay = 0;
reg inclk;
wire [7:0] mem_addr;
wire mem_wr;
wire [7:0] din;
wire [7:0] dout;
wire [7:0] pc;
wire [7:0] areg;
reg running = 1;
ram read_only_memory(
dout, mem_addr, mem_wr, inclk, din
);
hex cpu_core(
inclk,
mem_addr,
mem_wr,
din,
dout,
pc,
areg
);
always@(posedge clk) begin
delay <= delay + 1;
end
always@(posedge delay[LOG2DELAY-1]) begin
inclk <= inclk + 1;
end
assign {LED0, LED1, LED2, LED3, LED4, LED5, LED6, LED7} = areg;
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment